Auto sync2gitlab import of adcli-0.8.2-12.el8.src.rpm
This commit is contained in:
		
							parent
							
								
									74bdc0fb30
								
							
						
					
					
						commit
						32a0a2a0ec
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | /adcli-0.8.2.tar.gz | ||||||
							
								
								
									
										384
									
								
								0001-Add-setattr-option.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										384
									
								
								0001-Add-setattr-option.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,384 @@ | |||||||
|  | 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 1/2] 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,4 +150,5 @@ struct _adcli_enroll {
 | ||||||
|  |  	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, | ||||||
|  |  } 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 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,63 @@ | |||||||
|  | From 158468507bb723aa62196846749c23c121d4b298 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 8 Apr 2019 10:55:39 +0200 | ||||||
|  | Subject: [PATCH] Do not use arcfour-hmac-md5 when discovering the salt | ||||||
|  | 
 | ||||||
|  | Since the arcfour-hmac-md5 encryption types does not use salts it cannot | ||||||
|  | be used to discover the right salt. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1683745 | ||||||
|  | ---
 | ||||||
|  |  library/adkrb5.c | 21 ++++++++++++++++++++- | ||||||
|  |  1 file changed, 20 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adkrb5.c b/library/adkrb5.c
 | ||||||
|  | index da835d7..be3ede5 100644
 | ||||||
|  | --- a/library/adkrb5.c
 | ||||||
|  | +++ b/library/adkrb5.c
 | ||||||
|  | @@ -395,15 +395,33 @@ _adcli_krb5_keytab_discover_salt (krb5_context k5,
 | ||||||
|  |  	krb5_keytab scratch; | ||||||
|  |  	krb5_error_code code; | ||||||
|  |  	int i; | ||||||
|  | +	krb5_enctype *salt_enctypes = NULL;
 | ||||||
|  | +	size_t c;
 | ||||||
|  | +	size_t s;
 | ||||||
|  |   | ||||||
|  |  	/* TODO: This should be a unique name */ | ||||||
|  |   | ||||||
|  |  	code = krb5_kt_resolve (k5, "MEMORY:adcli-discover-salt", &scratch); | ||||||
|  |  	return_val_if_fail (code == 0, code); | ||||||
|  |   | ||||||
|  | +	for (c = 0; enctypes[c] != 0; c++); /* count enctypes */
 | ||||||
|  | +	salt_enctypes = calloc (c + 1, sizeof (krb5_enctype));
 | ||||||
|  | +	return_val_if_fail (salt_enctypes != NULL, ENOMEM);
 | ||||||
|  | +
 | ||||||
|  | +	/* ENCTYPE_ARCFOUR_HMAC does not use salts, so it cannot be used to
 | ||||||
|  | +	 * discover the right salt. */
 | ||||||
|  | +	s = 0;
 | ||||||
|  | +	for (c = 0; enctypes[c] != 0; c++) {
 | ||||||
|  | +		if (enctypes[c] == ENCTYPE_ARCFOUR_HMAC) {
 | ||||||
|  | +			continue;
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +		salt_enctypes[s++] = enctypes[c];
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	for (i = 0; salts[i].data != NULL; i++) { | ||||||
|  |  		code = _adcli_krb5_keytab_test_salt (k5, scratch, principal, kvno, | ||||||
|  | -		                                     password, enctypes, &salts[i]);
 | ||||||
|  | +		                                     password, salt_enctypes, &salts[i]);
 | ||||||
|  |  		if (code == 0) { | ||||||
|  |  			*discovered = i; | ||||||
|  |  			break; | ||||||
|  | @@ -412,6 +430,7 @@ _adcli_krb5_keytab_discover_salt (krb5_context k5,
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	free (salt_enctypes);
 | ||||||
|  |  	krb5_kt_close (k5, scratch); | ||||||
|  |  	return code; | ||||||
|  |  } | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										27
									
								
								0001-Fix-for-dont-expire-password-option-and-join.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								0001-Fix-for-dont-expire-password-option-and-join.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | From 924465af7a4f37390bfdfdb4971e88421f52f3d9 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 f3d606e..5b0dcd5 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -856,7 +856,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 | ||||||
|  | 
 | ||||||
							
								
								
									
										29
									
								
								0001-Fix-for-issue-found-by-Coverity.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								0001-Fix-for-issue-found-by-Coverity.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | From 5da6d34e2659f915e830932fd366c635801ecd91 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 12 Aug 2019 17:28:20 +0200 | ||||||
|  | Subject: [PATCH] Fix for issue found by Coverity | ||||||
|  | 
 | ||||||
|  | Related to https://gitlab.freedesktop.org/realmd/adcli/issues/3 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 5 ++++- | ||||||
|  |  1 file changed, 4 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 53cd812..524663a 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -2681,7 +2681,10 @@ adcli_enroll_get_permitted_keytab_enctypes (adcli_enroll *enroll)
 | ||||||
|  |  	for (c = 0; cur_enctypes[c] != 0; c++); | ||||||
|  |   | ||||||
|  |  	new_enctypes = calloc (c + 1, sizeof (krb5_enctype)); | ||||||
|  | -	return_val_if_fail (new_enctypes != NULL, NULL);
 | ||||||
|  | +	if (new_enctypes == NULL) {
 | ||||||
|  | +		krb5_free_enctypes (k5, permitted_enctypes);
 | ||||||
|  | +		return NULL;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	n = 0; | ||||||
|  |  	for (c = 0; cur_enctypes[c] != 0; c++) { | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										43
									
								
								0001-Fix-for-issues-found-by-Coverity.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								0001-Fix-for-issues-found-by-Coverity.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | From 3c93c96eb6ea2abd3869921ee4c89e1a4d9e4c44 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 14 Aug 2018 13:08:52 +0200 | ||||||
|  | Subject: [PATCH] Fix for issues found by Coverity | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 12 ++++++------ | ||||||
|  |  1 file changed, 6 insertions(+), 6 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 02bd9e3..de2242a 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -1575,7 +1575,7 @@ load_host_keytab (adcli_enroll *enroll)
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	krb5_free_context (k5); | ||||||
|  | -	return ADCLI_SUCCESS;
 | ||||||
|  | +	return res;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  typedef struct { | ||||||
|  | @@ -1756,12 +1756,12 @@ add_principal_to_keytab (adcli_enroll *enroll,
 | ||||||
|  |  		                                       enroll->kvno, &password, enctypes, &salts[*which_salt]); | ||||||
|  |   | ||||||
|  |  		free_principal_salts (k5, salts); | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  | -		if (code != 0) {
 | ||||||
|  | -			_adcli_err ("Couldn't add keytab entries: %s: %s",
 | ||||||
|  | -			            enroll->keytab_name, krb5_get_error_message (k5, code));
 | ||||||
|  | -			return ADCLI_ERR_FAIL;
 | ||||||
|  | -		}
 | ||||||
|  | +	if (code != 0) {
 | ||||||
|  | +		_adcli_err ("Couldn't add keytab entries: %s: %s",
 | ||||||
|  | +		            enroll->keytab_name, krb5_get_error_message (k5, code));
 | ||||||
|  | +		return ADCLI_ERR_FAIL;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										181
									
								
								0001-Implement-adcli-testjoin.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								0001-Implement-adcli-testjoin.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,181 @@ | |||||||
|  | From 6fd99ff6c5dd6ef0be8d942989b1c6dcee3102d9 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 22 Mar 2019 12:37:39 +0100 | ||||||
|  | Subject: [PATCH] Implement 'adcli testjoin' | ||||||
|  | 
 | ||||||
|  | By calling adcli testjoin it will be checked if the host credentials | ||||||
|  | stored in the keytab are still valid. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1622583 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml    | 34 +++++++++++++++++++++++ | ||||||
|  |  tools/computer.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  tools/tools.c    |  1 + | ||||||
|  |  tools/tools.h    |  4 +++ | ||||||
|  |  4 files changed, 111 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index af73433..9605b4a 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -43,6 +43,9 @@
 | ||||||
|  |  	<cmdsynopsis> | ||||||
|  |  		<command>adcli update</command> | ||||||
|  |  	</cmdsynopsis> | ||||||
|  | +	<cmdsynopsis>
 | ||||||
|  | +		<command>adcli testjoin</command>
 | ||||||
|  | +	</cmdsynopsis>
 | ||||||
|  |  	<cmdsynopsis> | ||||||
|  |  		<command>adcli create-user</command> | ||||||
|  |  		<arg choice="opt">--domain=domain.example.com</arg> | ||||||
|  | @@ -474,6 +477,37 @@ $ adcli update --login-ccache=/tmp/krbcc_123
 | ||||||
|  |   | ||||||
|  |  </refsect1> | ||||||
|  |   | ||||||
|  | +<refsect1 id='testjoin'>
 | ||||||
|  | +	<title>Testing if the machine account password is valid</title>
 | ||||||
|  | +
 | ||||||
|  | +	<para><command>adcli testjoin</command> uses the current credentials in
 | ||||||
|  | +	the keytab and tries to authenticate with the machine account to the AD
 | ||||||
|  | +	domain. If this works the machine account password and the join are
 | ||||||
|  | +	still valid. If it fails the machine account password or the whole
 | ||||||
|  | +	machine account have to be refreshed with
 | ||||||
|  | +	<command>adcli join</command> or <command>adcli update</command>.
 | ||||||
|  | +	</para>
 | ||||||
|  | +
 | ||||||
|  | +<programlisting>
 | ||||||
|  | +$ adcli testjoin
 | ||||||
|  | +</programlisting>
 | ||||||
|  | +
 | ||||||
|  | +	<para>Only the global options not related to authentication are
 | ||||||
|  | +	available, additionally you can specify the following options to
 | ||||||
|  | +	control how this operation is done.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<variablelist>
 | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>-K, --host-keytab=<parameter>/path/to/keytab</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Specify the path to the host keytab where
 | ||||||
|  | +			current host credentials are stored and the new ones
 | ||||||
|  | +			will be written to.  If not specified, the default
 | ||||||
|  | +			location will be used, usually
 | ||||||
|  | +			<filename>/etc/krb5.keytab</filename>.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  | +	</variablelist>
 | ||||||
|  | +</refsect1>
 | ||||||
|  | +
 | ||||||
|  |  <refsect1 id='create_user'> | ||||||
|  |  	<title>Creating a User</title> | ||||||
|  |   | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index 112340e..610ed2b 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -566,6 +566,78 @@ adcli_tool_computer_update (adcli_conn *conn,
 | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +int
 | ||||||
|  | +adcli_tool_computer_testjoin (adcli_conn *conn,
 | ||||||
|  | +                              int argc,
 | ||||||
|  | +                              char *argv[])
 | ||||||
|  | +{
 | ||||||
|  | +	adcli_enroll *enroll;
 | ||||||
|  | +	adcli_result res;
 | ||||||
|  | +	const char *ktname;
 | ||||||
|  | +	int opt;
 | ||||||
|  | +
 | ||||||
|  | +	struct option options[] = {
 | ||||||
|  | +		{ "domain", required_argument, NULL, opt_domain },
 | ||||||
|  | +		{ "domain-controller", required_argument, NULL, opt_domain_controller },
 | ||||||
|  | +		{ "host-keytab", required_argument, 0, opt_host_keytab },
 | ||||||
|  | +		{ "verbose", no_argument, NULL, opt_verbose },
 | ||||||
|  | +		{ "help", no_argument, NULL, 'h' },
 | ||||||
|  | +		{ 0 },
 | ||||||
|  | +	};
 | ||||||
|  | +
 | ||||||
|  | +	static adcli_tool_desc usages[] = {
 | ||||||
|  | +		{ 0, "usage: adcli testjoin" },
 | ||||||
|  | +		{ 0 },
 | ||||||
|  | +	};
 | ||||||
|  | +
 | ||||||
|  | +	enroll = adcli_enroll_new (conn);
 | ||||||
|  | +	if (enroll == NULL)
 | ||||||
|  | +		errx (-1, "unexpected memory problems");
 | ||||||
|  | +
 | ||||||
|  | +	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);
 | ||||||
|  | +			adcli_enroll_unref (enroll);
 | ||||||
|  | +			return opt == 'h' ? 0 : 2;
 | ||||||
|  | +		default:
 | ||||||
|  | +			parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			break;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	/* Force use of a keytab to test the join/machine account password */
 | ||||||
|  | +	adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_COMPUTER_ACCOUNT);
 | ||||||
|  | +	ktname = adcli_enroll_get_keytab_name (enroll);
 | ||||||
|  | +	adcli_conn_set_login_keytab_name (conn, ktname ? ktname : "");
 | ||||||
|  | +
 | ||||||
|  | +	res = adcli_enroll_load (enroll);
 | ||||||
|  | +	if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		adcli_conn_unref (conn);
 | ||||||
|  | +		errx (-res, "couldn't lookup domain info from keytab: %s",
 | ||||||
|  | +		      adcli_get_last_error ());
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	res = adcli_conn_connect (conn);
 | ||||||
|  | +	if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		adcli_conn_unref (conn);
 | ||||||
|  | +		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | +		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		      adcli_get_last_error ());
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	printf ("Sucessfully validated join to domain %s\n",
 | ||||||
|  | +	        adcli_conn_get_domain_name (conn));
 | ||||||
|  | +
 | ||||||
|  | +	adcli_enroll_unref (enroll);
 | ||||||
|  | +
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  |   | ||||||
|  |  int | ||||||
|  |  adcli_tool_computer_preset (adcli_conn *conn, | ||||||
|  | diff --git a/tools/tools.c b/tools/tools.c
 | ||||||
|  | index 915130e..c4e2851 100644
 | ||||||
|  | --- a/tools/tools.c
 | ||||||
|  | +++ b/tools/tools.c
 | ||||||
|  | @@ -55,6 +55,7 @@ struct {
 | ||||||
|  |  	{ "info", adcli_tool_info, "Print information about a domain", CONNECTION_LESS }, | ||||||
|  |  	{ "join", adcli_tool_computer_join, "Join this machine to a domain", }, | ||||||
|  |  	{ "update", adcli_tool_computer_update, "Update machine membership in a domain", }, | ||||||
|  | +	{ "testjoin", adcli_tool_computer_testjoin, "Test if machine account password is valid", },
 | ||||||
|  |  	{ "preset-computer", adcli_tool_computer_preset, "Pre setup computers accounts", }, | ||||||
|  |  	{ "reset-computer", adcli_tool_computer_reset, "Reset a computer account", }, | ||||||
|  |  	{ "delete-computer", adcli_tool_computer_delete, "Delete a computer account", }, | ||||||
|  | diff --git a/tools/tools.h b/tools/tools.h
 | ||||||
|  | index 6c97ccf..8cebbf9 100644
 | ||||||
|  | --- a/tools/tools.h
 | ||||||
|  | +++ b/tools/tools.h
 | ||||||
|  | @@ -70,6 +70,10 @@ int       adcli_tool_computer_update   (adcli_conn *conn,
 | ||||||
|  |                                          int argc, | ||||||
|  |                                          char *argv[]); | ||||||
|  |   | ||||||
|  | +int       adcli_tool_computer_testjoin (adcli_conn *conn,
 | ||||||
|  | +                                        int argc,
 | ||||||
|  | +                                        char *argv[]);
 | ||||||
|  | +
 | ||||||
|  |  int       adcli_tool_computer_delete   (adcli_conn *conn, | ||||||
|  |                                          int argc, | ||||||
|  |                                          char *argv[]); | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,32 @@ | |||||||
|  | From 5cf1723c308e21cdbe9b98ed2aaa42cb997456fb Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 15 Mar 2019 14:31:12 +0100 | ||||||
|  | Subject: [PATCH] Increment kvno after password change with user creds | ||||||
|  | 
 | ||||||
|  | Originally only the host credential part was fixed in the context of | ||||||
|  | https://bugs.freedesktop.org/show_bug.cgi?id=91185. This patch adds the | ||||||
|  | fix to the case when user credentials are used. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1642546 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 4 ++++ | ||||||
|  |  1 file changed, 4 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index e02f403..58362c2 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -1057,6 +1057,10 @@ set_password_with_user_creds (adcli_enroll *enroll)
 | ||||||
|  |  #endif | ||||||
|  |  	} else { | ||||||
|  |  		_adcli_info ("Set computer password"); | ||||||
|  | +		if (enroll->kvno > 0) {
 | ||||||
|  | +			enroll->kvno++;
 | ||||||
|  | +			_adcli_info ("kvno incremented to %d", enroll->kvno);
 | ||||||
|  | +		}
 | ||||||
|  |  		res = ADCLI_SUCCESS; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										216
									
								
								0001-Make-adcli-info-DC-location-mechanism-more-compliant.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								0001-Make-adcli-info-DC-location-mechanism-more-compliant.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,216 @@ | |||||||
|  | From 0a0d0f66409eb83e06b7dc50543c2f6c15a36bc4 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Alexey A Nikitin <nikitin@amazon.com> | ||||||
|  | Date: Mon, 29 Oct 2018 20:40:36 -0700 | ||||||
|  | Subject: [PATCH] Make 'adcli info' DC location mechanism more compliant with | ||||||
|  |  [MS-ADTS] and [MS-NRPC] | ||||||
|  | 
 | ||||||
|  | AD specifications say that DC locator must attempt to find a suitable DC for the client. That means going through all of the DCs in SRV RRs one by one until one of them answers. | ||||||
|  | 
 | ||||||
|  | The problem with adcli's original behavior is that it queries only five DCs from SRV, ever. This becomes a problem if for any reason there is a large number of DCs in the domain from which the client cannot get a CLDAP response. | ||||||
|  | ---
 | ||||||
|  |  library/addisco.c | 146 +++++++++++++++++++++++++++++----------------- | ||||||
|  |  1 file changed, 94 insertions(+), 52 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/addisco.c b/library/addisco.c
 | ||||||
|  | index 8cc5bf0..6e73ead 100644
 | ||||||
|  | --- a/library/addisco.c
 | ||||||
|  | +++ b/library/addisco.c
 | ||||||
|  | @@ -41,8 +41,10 @@
 | ||||||
|  |  #include <string.h> | ||||||
|  |  #include <time.h> | ||||||
|  |   | ||||||
|  | -/* Number of servers to do discovery against */
 | ||||||
|  | -#define DISCO_COUNT 5
 | ||||||
|  | +/* Number of servers to do discovery against.
 | ||||||
|  | + * For AD DS maximum number of DCs is 1200.
 | ||||||
|  | + */
 | ||||||
|  | +#define DISCO_COUNT 1200
 | ||||||
|  |   | ||||||
|  |  /* The time period in which to do rapid requests */ | ||||||
|  |  #define DISCO_FEVER  1 | ||||||
|  | @@ -453,6 +455,51 @@ parse_disco (LDAP *ldap,
 | ||||||
|  |  	return usability; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static int
 | ||||||
|  | +ldap_disco_poller (LDAP **ldap,
 | ||||||
|  | +                   LDAPMessage **message,
 | ||||||
|  | +                   adcli_disco **results,
 | ||||||
|  | +                   const char **addrs)
 | ||||||
|  | +{
 | ||||||
|  | +	int found = ADCLI_DISCO_UNUSABLE;
 | ||||||
|  | +	int close_ldap;
 | ||||||
|  | +	int parsed;
 | ||||||
|  | +	int ret = 0;
 | ||||||
|  | +	struct timeval tvpoll = { 0, 0 };
 | ||||||
|  | +
 | ||||||
|  | +	switch (ldap_result (*ldap, LDAP_RES_ANY, 1, &tvpoll, message)) {
 | ||||||
|  | +		case LDAP_RES_SEARCH_ENTRY:
 | ||||||
|  | +		case LDAP_RES_SEARCH_RESULT:
 | ||||||
|  | +			parsed = parse_disco (*ldap, *addrs, *message, results);
 | ||||||
|  | +			if (parsed > found)
 | ||||||
|  | +				found = parsed;
 | ||||||
|  | +			ldap_msgfree (*message);
 | ||||||
|  | +			close_ldap = 1;
 | ||||||
|  | +			break;
 | ||||||
|  | +		case -1:
 | ||||||
|  | +			ldap_get_option (*ldap, LDAP_OPT_RESULT_CODE, &ret);
 | ||||||
|  | +			close_ldap = 1;
 | ||||||
|  | +			break;
 | ||||||
|  | +		default:
 | ||||||
|  | +			ldap_msgfree (*message);
 | ||||||
|  | +			close_ldap = 0;
 | ||||||
|  | +			break;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (ret != LDAP_SUCCESS) {
 | ||||||
|  | +		_adcli_ldap_handle_failure (*ldap, ADCLI_ERR_CONFIG,
 | ||||||
|  | +		                            "Couldn't perform discovery search");
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	/* Done with this connection */
 | ||||||
|  | +	if (close_ldap) {
 | ||||||
|  | +		ldap_unbind_ext_s (*ldap, NULL, NULL);
 | ||||||
|  | +		*ldap = NULL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return found;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static int | ||||||
|  |  ldap_disco (const char *domain, | ||||||
|  |              srvinfo *srv, | ||||||
|  | @@ -477,6 +524,7 @@ ldap_disco (const char *domain,
 | ||||||
|  |  	int num, i; | ||||||
|  |  	int ret; | ||||||
|  |  	int have_any = 0; | ||||||
|  | +	struct timeval interval;
 | ||||||
|  |   | ||||||
|  |  	if (domain) { | ||||||
|  |  		value = _adcli_ldap_escape_filter (domain); | ||||||
|  | @@ -540,7 +588,6 @@ ldap_disco (const char *domain,
 | ||||||
|  |  				version = LDAP_VERSION3; | ||||||
|  |  				ldap_set_option (ldap[num], LDAP_OPT_PROTOCOL_VERSION, &version); | ||||||
|  |  				ldap_set_option (ldap[num], LDAP_OPT_REFERRALS , 0); | ||||||
|  | -				_adcli_info ("Sending netlogon pings to domain controller: %s", url);
 | ||||||
|  |  				addrs[num] = srv->hostname; | ||||||
|  |  				have_any = 1; | ||||||
|  |  				num++; | ||||||
|  | @@ -555,70 +602,65 @@ ldap_disco (const char *domain,
 | ||||||
|  |  		freeaddrinfo (res); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	/* Wait for the first response. Poor mans fd watch */
 | ||||||
|  | -	for (started = now = time (NULL);
 | ||||||
|  | -	     have_any && found != ADCLI_DISCO_USABLE && now < started + DISCO_TIME;
 | ||||||
|  | -	     now = time (NULL)) {
 | ||||||
|  | +	/* Initial send and short time wait */
 | ||||||
|  | +	interval.tv_sec = 0;
 | ||||||
|  | +	for (i = 0; ADCLI_DISCO_UNUSABLE == found && i < num; ++i) {
 | ||||||
|  | +		int parsed;
 | ||||||
|  | +
 | ||||||
|  | +		if (NULL == ldap[i])
 | ||||||
|  | +			continue;
 | ||||||
|  |   | ||||||
|  | -		struct timeval tvpoll = { 0, 0 };
 | ||||||
|  | -		struct timeval interval;
 | ||||||
|  | +		have_any = 1;
 | ||||||
|  | +		_adcli_info ("Sending NetLogon ping to domain controller: %s", addrs[i]);
 | ||||||
|  |   | ||||||
|  | -		/* If in the initial period, send feverishly */
 | ||||||
|  | -		if (now < started + DISCO_FEVER) {
 | ||||||
|  | -			interval.tv_sec = 0;
 | ||||||
|  | -			interval.tv_usec = 100 * 1000;
 | ||||||
|  | +		ret = ldap_search_ext (ldap[i], "", LDAP_SCOPE_BASE,
 | ||||||
|  | +		                       filter, attrs, 0, NULL, NULL, NULL,
 | ||||||
|  | +		                       -1, &msgidp);
 | ||||||
|  | +
 | ||||||
|  | +		if (ret != LDAP_SUCCESS) {
 | ||||||
|  | +			_adcli_ldap_handle_failure (ldap[i], ADCLI_ERR_CONFIG,
 | ||||||
|  | +			                            "Couldn't perform discovery search");
 | ||||||
|  | +			ldap_unbind_ext_s (ldap[i], NULL, NULL);
 | ||||||
|  | +			ldap[i] = NULL;
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +		/* From https://msdn.microsoft.com/en-us/library/ff718294.aspx first
 | ||||||
|  | +		 * five DCs are given 0.4 seconds timeout, next five are given 0.2
 | ||||||
|  | +		 * seconds, and the rest are given 0.1 seconds
 | ||||||
|  | +		 */
 | ||||||
|  | +		if (i < 5) {
 | ||||||
|  | +			interval.tv_usec = 400000;
 | ||||||
|  | +		} else if (i < 10) {
 | ||||||
|  | +			interval.tv_usec = 200000;
 | ||||||
|  |  		} else { | ||||||
|  | -			interval.tv_sec = 1;
 | ||||||
|  | -			interval.tv_usec = 0;
 | ||||||
|  | +			interval.tv_usec = 100000;
 | ||||||
|  |  		} | ||||||
|  | +		select (0, NULL, NULL, NULL, &interval);
 | ||||||
|  | +
 | ||||||
|  | +		parsed = ldap_disco_poller (&(ldap[i]), &message, results, &(addrs[i]));
 | ||||||
|  | +		if (parsed > found)
 | ||||||
|  | +			found = parsed;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	/* Wait some more until LDAP timeout (DISCO_TIME) */
 | ||||||
|  | +	for (started = now = time (NULL);
 | ||||||
|  | +	     have_any && ADCLI_DISCO_UNUSABLE == found && now < started + DISCO_TIME;
 | ||||||
|  | +	     now = time (NULL)) {
 | ||||||
|  |   | ||||||
|  |  		select (0, NULL, NULL, NULL, &interval); | ||||||
|  |   | ||||||
|  |  		have_any = 0; | ||||||
|  | -		for (i = 0; found != ADCLI_DISCO_USABLE && i < num; i++) {
 | ||||||
|  | -			int close_ldap;
 | ||||||
|  | +		for (i = 0; ADCLI_DISCO_UNUSABLE == found && i < num; ++i) {
 | ||||||
|  |  			int parsed; | ||||||
|  |   | ||||||
|  |  			if (ldap[i] == NULL) | ||||||
|  |  				continue; | ||||||
|  |   | ||||||
|  | -			ret = 0;
 | ||||||
|  |  			have_any = 1; | ||||||
|  | -			switch (ldap_result (ldap[i], LDAP_RES_ANY, 1, &tvpoll, &message)) {
 | ||||||
|  | -			case LDAP_RES_SEARCH_ENTRY:
 | ||||||
|  | -			case LDAP_RES_SEARCH_RESULT:
 | ||||||
|  | -				parsed = parse_disco (ldap[i], addrs[i], message, results);
 | ||||||
|  | -				if (parsed > found)
 | ||||||
|  | -					found = parsed;
 | ||||||
|  | -				ldap_msgfree (message);
 | ||||||
|  | -				close_ldap = 1;
 | ||||||
|  | -				break;
 | ||||||
|  | -			case 0:
 | ||||||
|  | -				ret = ldap_search_ext (ldap[i], "", LDAP_SCOPE_BASE,
 | ||||||
|  | -				                       filter, attrs, 0, NULL, NULL, NULL,
 | ||||||
|  | -				                       -1, &msgidp);
 | ||||||
|  | -				close_ldap = (ret != 0);
 | ||||||
|  | -				break;
 | ||||||
|  | -			case -1:
 | ||||||
|  | -				ldap_get_option (ldap[i], LDAP_OPT_RESULT_CODE, &ret);
 | ||||||
|  | -				close_ldap = 1;
 | ||||||
|  | -				break;
 | ||||||
|  | -			default:
 | ||||||
|  | -				ldap_msgfree (message);
 | ||||||
|  | -				close_ldap = 0;
 | ||||||
|  | -				break;
 | ||||||
|  | -			}
 | ||||||
|  | -
 | ||||||
|  | -			if (ret != LDAP_SUCCESS) {
 | ||||||
|  | -				_adcli_ldap_handle_failure (ldap[i], ADCLI_ERR_CONFIG,
 | ||||||
|  | -				                            "Couldn't perform discovery search");
 | ||||||
|  | -			}
 | ||||||
|  |   | ||||||
|  | -			/* Done with this connection */
 | ||||||
|  | -			if (close_ldap) {
 | ||||||
|  | -				ldap_unbind_ext_s (ldap[i], NULL, NULL);
 | ||||||
|  | -				ldap[i] = NULL;
 | ||||||
|  | -			}
 | ||||||
|  | +			parsed = ldap_disco_poller (&(ldap[i]), &message, results, &(addrs[i]));
 | ||||||
|  | +			if (parsed > found)
 | ||||||
|  | +				found = parsed;
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.26.2 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,31 @@ | |||||||
|  | From d8eb0f5704f34cb7d411cd275d32c63ead297b8d Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 24 Aug 2016 15:37:41 +0200 | ||||||
|  | Subject: [PATCH 01/23] Remove upper-case only check when looking for the | ||||||
|  |  NetBIOS name | ||||||
|  | 
 | ||||||
|  | It is a convention to use only upper-case letters for NetBIOS names but | ||||||
|  | it is not enforced on the AD-side. With the new option to specify a | ||||||
|  | random NetBIOS name it is possible to create host entries in AD with | ||||||
|  | lower-case letters in the name. To properly determine the name from the | ||||||
|  | keytab the upper-case check should be dropped,dc= | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index a15e4be..d1020e9 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -1309,7 +1309,7 @@ load_keytab_entry (krb5_context k5,
 | ||||||
|  |  	if (!enroll->host_fqdn_explicit && !enroll->computer_name_explicit) { | ||||||
|  |   | ||||||
|  |  		/* Automatically use the netbios name */ | ||||||
|  | -		if (!enroll->computer_name && len > 1 && _adcli_str_is_up (name) &&
 | ||||||
|  | +		if (!enroll->computer_name && len > 1 &&
 | ||||||
|  |  		    _adcli_str_has_suffix (name, "$") && !strchr (name, '/')) { | ||||||
|  |  			enroll->computer_name = name; | ||||||
|  |  			name[len - 1] = '\0'; | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										124
									
								
								0001-Use-GSS-SPNEGO-if-available.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								0001-Use-GSS-SPNEGO-if-available.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,124 @@ | |||||||
|  | From a6f795ba3d6048b32d7863468688bf7f42b2cafd Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 11 Oct 2019 16:39:25 +0200 | ||||||
|  | Subject: [PATCH 1/2] Use GSS-SPNEGO if available | ||||||
|  | 
 | ||||||
|  | Currently adcli uses the GSSAPI SASL mechanism for LDAP authentication | ||||||
|  | and to establish encryption. While this works in general it does not | ||||||
|  | handle some of the more advanced features which can be required by AD | ||||||
|  | DCs. | ||||||
|  | 
 | ||||||
|  | The GSS-SPNEGO mechanism can handle them and is used with this patch by | ||||||
|  | adcli if the AD DC indicates that it supports it. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1762420 | ||||||
|  | ---
 | ||||||
|  |  library/adconn.c | 35 ++++++++++++++++++++++++++++++++++- | ||||||
|  |  library/adconn.h |  3 +++ | ||||||
|  |  2 files changed, 37 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adconn.c b/library/adconn.c
 | ||||||
|  | index bcaced8..ffb54f9 100644
 | ||||||
|  | --- a/library/adconn.c
 | ||||||
|  | +++ b/library/adconn.c
 | ||||||
|  | @@ -77,6 +77,7 @@ struct _adcli_conn_ctx {
 | ||||||
|  |  	char *default_naming_context; | ||||||
|  |  	char *configuration_naming_context; | ||||||
|  |  	char **supported_capabilities; | ||||||
|  | +	char **supported_sasl_mechs;
 | ||||||
|  |   | ||||||
|  |  	/* Connect state */ | ||||||
|  |  	LDAP *ldap; | ||||||
|  | @@ -845,6 +846,7 @@ connect_and_lookup_naming (adcli_conn *conn,
 | ||||||
|  |  		"defaultNamingContext", | ||||||
|  |  		"configurationNamingContext", | ||||||
|  |  		"supportedCapabilities", | ||||||
|  | +		"supportedSASLMechanisms",
 | ||||||
|  |  		NULL | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  | @@ -897,6 +899,11 @@ connect_and_lookup_naming (adcli_conn *conn,
 | ||||||
|  |  		                                                         "supportedCapabilities"); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	if (conn->supported_sasl_mechs == NULL) {
 | ||||||
|  | +		conn->supported_sasl_mechs = _adcli_ldap_parse_values (ldap, results,
 | ||||||
|  | +		                                                       "supportedSASLMechanisms");
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	ldap_msgfree (results); | ||||||
|  |   | ||||||
|  |  	if (conn->default_naming_context == NULL) { | ||||||
|  | @@ -1022,6 +1029,7 @@ authenticate_to_directory (adcli_conn *conn)
 | ||||||
|  |  	OM_uint32 minor; | ||||||
|  |  	ber_len_t ssf; | ||||||
|  |  	int ret; | ||||||
|  | +	const char *mech = "GSSAPI";
 | ||||||
|  |   | ||||||
|  |  	if (conn->ldap_authenticated) | ||||||
|  |  		return ADCLI_SUCCESS; | ||||||
|  | @@ -1038,7 +1046,11 @@ authenticate_to_directory (adcli_conn *conn)
 | ||||||
|  |  	ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MIN, &ssf); | ||||||
|  |  	return_unexpected_if_fail (ret == 0); | ||||||
|  |   | ||||||
|  | -	ret = ldap_sasl_interactive_bind_s (conn->ldap, NULL, "GSSAPI", NULL, NULL,
 | ||||||
|  | +	if (adcli_conn_server_has_sasl_mech (conn, "GSS-SPNEGO")) {
 | ||||||
|  | +		mech =  "GSS-SPNEGO";
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	ret = ldap_sasl_interactive_bind_s (conn->ldap, NULL, mech, NULL, NULL,
 | ||||||
|  |  	                                    LDAP_SASL_QUIET, sasl_interact, NULL); | ||||||
|  |   | ||||||
|  |  	/* Clear the credential cache GSSAPI to use (for this thread) */ | ||||||
|  | @@ -1231,6 +1243,7 @@ conn_free (adcli_conn *conn)
 | ||||||
|  |  	free (conn->default_naming_context); | ||||||
|  |  	free (conn->configuration_naming_context); | ||||||
|  |  	_adcli_strv_free (conn->supported_capabilities); | ||||||
|  | +	_adcli_strv_free (conn->supported_sasl_mechs);
 | ||||||
|  |   | ||||||
|  |  	free (conn->computer_name); | ||||||
|  |  	free (conn->host_fqdn); | ||||||
|  | @@ -1606,6 +1619,26 @@ adcli_conn_server_has_capability (adcli_conn *conn,
 | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +bool
 | ||||||
|  | +adcli_conn_server_has_sasl_mech (adcli_conn *conn,
 | ||||||
|  | +                                 const char *mech)
 | ||||||
|  | +{
 | ||||||
|  | +	int i;
 | ||||||
|  | +
 | ||||||
|  | +	return_val_if_fail (conn != NULL, false);
 | ||||||
|  | +	return_val_if_fail (mech != NULL, false);
 | ||||||
|  | +
 | ||||||
|  | +	if (!conn->supported_sasl_mechs)
 | ||||||
|  | +		return false;
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0; conn->supported_sasl_mechs[i] != NULL; i++) {
 | ||||||
|  | +		if (strcasecmp (mech, conn->supported_sasl_mechs[i]) == 0)
 | ||||||
|  | +			return true;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return false;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  bool adcli_conn_is_writeable (adcli_conn *conn) | ||||||
|  |  { | ||||||
|  |  	disco_dance_if_necessary (conn); | ||||||
|  | diff --git a/library/adconn.h b/library/adconn.h
 | ||||||
|  | index 1ad5715..37ebdd9 100644
 | ||||||
|  | --- a/library/adconn.h
 | ||||||
|  | +++ b/library/adconn.h
 | ||||||
|  | @@ -149,6 +149,9 @@ void                adcli_conn_set_krb5_conf_dir     (adcli_conn *conn,
 | ||||||
|  |  int                 adcli_conn_server_has_capability (adcli_conn *conn, | ||||||
|  |                                                        const char *capability); | ||||||
|  |   | ||||||
|  | +bool                adcli_conn_server_has_sasl_mech  (adcli_conn *conn,
 | ||||||
|  | +                                                      const char *mech);
 | ||||||
|  | +
 | ||||||
|  |  bool                adcli_conn_is_writeable          (adcli_conn *conn); | ||||||
|  |   | ||||||
|  |  #endif /* ADCONN_H_ */ | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,80 @@ | |||||||
|  | From 341974aae7d0755fc32a0b7e2b34d8e1ef60d195 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 20 Dec 2018 21:05:35 +0100 | ||||||
|  | Subject: [PATCH 1/4] adenroll: make sure only allowed enctypes are used in | ||||||
|  |  FIPS mode | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1717355 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 36 +++++++++++++++++++++++++++++++++++- | ||||||
|  |  1 file changed, 35 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 52aa8a8..f617f28 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -41,11 +41,19 @@
 | ||||||
|  |  #include <netdb.h> | ||||||
|  |  #include <stdio.h> | ||||||
|  |  #include <unistd.h> | ||||||
|  | +#include <sys/stat.h>
 | ||||||
|  | +#include <fcntl.h>
 | ||||||
|  |   | ||||||
|  |  #ifndef SAMBA_DATA_TOOL | ||||||
|  |  #define SAMBA_DATA_TOOL "/usr/bin/net" | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +static krb5_enctype v60_later_enctypes_fips[] = {
 | ||||||
|  | +	ENCTYPE_AES256_CTS_HMAC_SHA1_96,
 | ||||||
|  | +	ENCTYPE_AES128_CTS_HMAC_SHA1_96,
 | ||||||
|  | +	0
 | ||||||
|  | +};
 | ||||||
|  | +
 | ||||||
|  |  static krb5_enctype v60_later_enctypes[] = { | ||||||
|  |  	ENCTYPE_AES256_CTS_HMAC_SHA1_96, | ||||||
|  |  	ENCTYPE_AES128_CTS_HMAC_SHA1_96, | ||||||
|  | @@ -2594,6 +2602,28 @@ adcli_enroll_set_keytab_name (adcli_enroll *enroll,
 | ||||||
|  |  	enroll->keytab_name_is_krb5 = 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +#define PROC_SYS_FIPS "/proc/sys/crypto/fips_enabled"
 | ||||||
|  | +
 | ||||||
|  | +static bool adcli_fips_enabled (void)
 | ||||||
|  | +{
 | ||||||
|  | +	int fd;
 | ||||||
|  | +	ssize_t len;
 | ||||||
|  | +	char buf[8];
 | ||||||
|  | +
 | ||||||
|  | +	fd = open (PROC_SYS_FIPS, O_RDONLY);
 | ||||||
|  | +	if (fd != -1) {
 | ||||||
|  | +		len = read (fd, buf, sizeof (buf));
 | ||||||
|  | +		close (fd);
 | ||||||
|  | +		/* Assume FIPS in enabled if PROC_SYS_FIPS contains a
 | ||||||
|  | +		 * non-0 value. */
 | ||||||
|  | +		if ( ! (len == 2 && buf[0] == '0' && buf[1] == '\n')) {
 | ||||||
|  | +			return true;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return false;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  krb5_enctype * | ||||||
|  |  adcli_enroll_get_keytab_enctypes (adcli_enroll *enroll) | ||||||
|  |  { | ||||||
|  | @@ -2602,7 +2632,11 @@ adcli_enroll_get_keytab_enctypes (adcli_enroll *enroll)
 | ||||||
|  |  		return enroll->keytab_enctypes; | ||||||
|  |   | ||||||
|  |  	if (adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID)) | ||||||
|  | -		return v60_later_enctypes;
 | ||||||
|  | +		if (adcli_fips_enabled ()) {
 | ||||||
|  | +			return v60_later_enctypes_fips;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			return v60_later_enctypes;
 | ||||||
|  | +		}
 | ||||||
|  |  	else | ||||||
|  |  		return v51_earlier_enctypes; | ||||||
|  |  } | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										134
									
								
								0001-adutil-add-_adcli_strv_add_unique.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								0001-adutil-add-_adcli_strv_add_unique.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,134 @@ | |||||||
|  | From 85d127fd52a8469f9f3ce0d1130fe17e756fdd75 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 16 Nov 2018 13:32:33 +0100 | ||||||
|  | Subject: [PATCH 1/2] adutil: add _adcli_strv_add_unique | ||||||
|  | 
 | ||||||
|  | _adcli_strv_add_unique checks is the new value already exists in the | ||||||
|  | strv before adding it. Check can be done case-sensitive or not. | ||||||
|  | 
 | ||||||
|  | Related to https://gitlab.freedesktop.org/realmd/adcli/issues/16 | ||||||
|  | ---
 | ||||||
|  |  library/adprivate.h |  5 ++++ | ||||||
|  |  library/adutil.c    | 65 ++++++++++++++++++++++++++++++++++++++------- | ||||||
|  |  2 files changed, 61 insertions(+), 9 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adprivate.h b/library/adprivate.h
 | ||||||
|  | index bc9df6d..0806430 100644
 | ||||||
|  | --- a/library/adprivate.h
 | ||||||
|  | +++ b/library/adprivate.h
 | ||||||
|  | @@ -111,6 +111,11 @@ char **        _adcli_strv_add               (char **strv,
 | ||||||
|  |                                                char *string, | ||||||
|  |                                                int *length) GNUC_WARN_UNUSED; | ||||||
|  |   | ||||||
|  | +char **        _adcli_strv_add_unique        (char **strv,
 | ||||||
|  | +                                              char *string,
 | ||||||
|  | +                                              int *length,
 | ||||||
|  | +                                              bool case_sensitive) GNUC_WARN_UNUSED;
 | ||||||
|  | +
 | ||||||
|  |  void           _adcli_strv_remove_unsorted   (char **strv, | ||||||
|  |                                                const char *string, | ||||||
|  |                                                int *length); | ||||||
|  | diff --git a/library/adutil.c b/library/adutil.c
 | ||||||
|  | index 17d2caa..76ea158 100644
 | ||||||
|  | --- a/library/adutil.c
 | ||||||
|  | +++ b/library/adutil.c
 | ||||||
|  | @@ -221,6 +221,34 @@ _adcli_strv_add (char **strv,
 | ||||||
|  |  	return seq_push (strv, length, string); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static int
 | ||||||
|  | +_adcli_strv_has_ex (char **strv,
 | ||||||
|  | +                    const char *str,
 | ||||||
|  | +                    int (* compare) (const char *match, const char*value))
 | ||||||
|  | +{
 | ||||||
|  | +	int i;
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0; strv && strv[i] != NULL; i++) {
 | ||||||
|  | +		if (compare (strv[i], str) == 0)
 | ||||||
|  | +			return 1;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +char **
 | ||||||
|  | +_adcli_strv_add_unique (char **strv,
 | ||||||
|  | +                        char *string,
 | ||||||
|  | +                        int *length,
 | ||||||
|  | +                        bool case_sensitive)
 | ||||||
|  | +{
 | ||||||
|  | +	if (_adcli_strv_has_ex (strv, string, case_sensitive ? strcmp : strcasecmp) == 1) {
 | ||||||
|  | +		return strv;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return _adcli_strv_add (strv, string, length);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) | ||||||
|  |   | ||||||
|  |  void | ||||||
|  | @@ -241,19 +269,11 @@ _adcli_strv_remove_unsorted (char **strv,
 | ||||||
|  |  	                            (seq_compar)strcasecmp, free); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -
 | ||||||
|  |  int | ||||||
|  |  _adcli_strv_has (char **strv, | ||||||
|  |                   const char *str) | ||||||
|  |  { | ||||||
|  | -	int i;
 | ||||||
|  | -
 | ||||||
|  | -	for (i = 0; strv && strv[i] != NULL; i++) {
 | ||||||
|  | -		if (strcmp (strv[i], str) == 0)
 | ||||||
|  | -			return 1;
 | ||||||
|  | -	}
 | ||||||
|  | -
 | ||||||
|  | -	return 0;
 | ||||||
|  | +	return _adcli_strv_has_ex (strv, str, strcmp);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void | ||||||
|  | @@ -704,6 +724,32 @@ test_strv_add_free (void)
 | ||||||
|  |  	_adcli_strv_free (strv); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static void
 | ||||||
|  | +test_strv_add_unique_free (void)
 | ||||||
|  | +{
 | ||||||
|  | +	char **strv = NULL;
 | ||||||
|  | +
 | ||||||
|  | +	strv = _adcli_strv_add_unique (strv, strdup ("one"), NULL, false);
 | ||||||
|  | +	strv = _adcli_strv_add_unique (strv, strdup ("one"), NULL, false);
 | ||||||
|  | +	strv = _adcli_strv_add_unique (strv, strdup ("two"), NULL, false);
 | ||||||
|  | +	strv = _adcli_strv_add_unique (strv, strdup ("two"), NULL, false);
 | ||||||
|  | +	strv = _adcli_strv_add_unique (strv, strdup ("tWo"), NULL, false);
 | ||||||
|  | +	strv = _adcli_strv_add_unique (strv, strdup ("three"), NULL, false);
 | ||||||
|  | +	strv = _adcli_strv_add_unique (strv, strdup ("three"), NULL, false);
 | ||||||
|  | +	strv = _adcli_strv_add_unique (strv, strdup ("TWO"), NULL, true);
 | ||||||
|  | +
 | ||||||
|  | +	assert_num_eq (_adcli_strv_len (strv), 4);
 | ||||||
|  | +
 | ||||||
|  | +	assert_str_eq (strv[0], "one");
 | ||||||
|  | +	assert_str_eq (strv[1], "two");
 | ||||||
|  | +	assert_str_eq (strv[2], "three");
 | ||||||
|  | +	assert_str_eq (strv[3], "TWO");
 | ||||||
|  | +	assert (strv[4] == NULL);
 | ||||||
|  | +
 | ||||||
|  | +	_adcli_strv_free (strv);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +
 | ||||||
|  |  static void | ||||||
|  |  test_strv_dup (void) | ||||||
|  |  { | ||||||
|  | @@ -856,6 +902,7 @@ main (int argc,
 | ||||||
|  |        char *argv[]) | ||||||
|  |  { | ||||||
|  |  	test_func (test_strv_add_free, "/util/strv_add_free"); | ||||||
|  | +	test_func (test_strv_add_unique_free, "/util/strv_add_unique_free");
 | ||||||
|  |  	test_func (test_strv_dup, "/util/strv_dup"); | ||||||
|  |  	test_func (test_strv_count, "/util/strv_count"); | ||||||
|  |  	test_func (test_check_nt_time_string_lifetime, "/util/check_nt_time_string_lifetime"); | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
| @ -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 | ||||||
|  | 
 | ||||||
							
								
								
									
										44
									
								
								0001-coverity-add-missing-NULL-checks.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								0001-coverity-add-missing-NULL-checks.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | |||||||
|  | From 13fe79c0a78028ccfe8e3d4e5ee16cfb9e143924 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 f693e58..c726093 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -3046,6 +3046,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 | ||||||
|  | 
 | ||||||
							
								
								
									
										71
									
								
								0001-create-user-add-nis-domain-option.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								0001-create-user-add-nis-domain-option.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | |||||||
|  | From 1457b4a7623a8ae58fb8d6a652d1cc44904b8863 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 18 Mar 2019 11:02:57 +0100 | ||||||
|  | Subject: [PATCH 1/2] create-user: add nis-domain option | ||||||
|  | 
 | ||||||
|  | Related to https://gitlab.freedesktop.org/realmd/adcli/issues/2 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml | 8 ++++++++ | ||||||
|  |  tools/entry.c | 6 ++++++ | ||||||
|  |  2 files changed, 14 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index 4722c3a..18620c0 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -531,6 +531,14 @@ $ adcli create-user Fry --domain=domain.example.com \
 | ||||||
|  |  			the new created user account, which should be the user's | ||||||
|  |  			numeric primary user id.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--nis-domain=<parameter>nis_domain</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Set the <code>msSFU30NisDomain</code> attribute of
 | ||||||
|  | +			the new created user account, which should be the user's
 | ||||||
|  | +			NIS domain is the NIS/YP service of Active Directory's Services for Unix (SFU)
 | ||||||
|  | +			are used. This is needed to let the 'UNIX attributes' tab of older Active
 | ||||||
|  | +			Directoy versions show the set UNIX specific attributes.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  |  	</variablelist> | ||||||
|  |   | ||||||
|  |  </refsect1> | ||||||
|  | diff --git a/tools/entry.c b/tools/entry.c
 | ||||||
|  | index 7b6a200..69ce62c 100644
 | ||||||
|  | --- a/tools/entry.c
 | ||||||
|  | +++ b/tools/entry.c
 | ||||||
|  | @@ -52,6 +52,7 @@ typedef enum {
 | ||||||
|  |  	opt_unix_uid, | ||||||
|  |  	opt_unix_gid, | ||||||
|  |  	opt_unix_shell, | ||||||
|  | +	opt_nis_domain,
 | ||||||
|  |  } Option; | ||||||
|  |   | ||||||
|  |  static adcli_tool_desc common_usages[] = { | ||||||
|  | @@ -62,6 +63,7 @@ static adcli_tool_desc common_usages[] = {
 | ||||||
|  |  	{ opt_unix_uid, "unix uid number" }, | ||||||
|  |  	{ opt_unix_gid, "unix gid number" }, | ||||||
|  |  	{ opt_unix_shell, "unix shell" }, | ||||||
|  | +	{ opt_nis_domain, "NIS domain" },
 | ||||||
|  |  	{ opt_domain, "active directory domain name" }, | ||||||
|  |  	{ opt_domain_realm, "kerberos realm for the domain" }, | ||||||
|  |  	{ opt_domain_controller, "domain directory server to connect to" }, | ||||||
|  | @@ -159,6 +161,7 @@ adcli_tool_user_create (adcli_conn *conn,
 | ||||||
|  |  		{ "unix-uid", required_argument, NULL, opt_unix_uid }, | ||||||
|  |  		{ "unix-gid", required_argument, NULL, opt_unix_gid }, | ||||||
|  |  		{ "unix-shell", required_argument, NULL, opt_unix_shell }, | ||||||
|  | +		{ "nis-domain", required_argument, NULL, opt_nis_domain },
 | ||||||
|  |  		{ "domain-ou", required_argument, NULL, opt_domain_ou }, | ||||||
|  |  		{ "domain", required_argument, NULL, opt_domain }, | ||||||
|  |  		{ "domain-realm", required_argument, NULL, opt_domain_realm }, | ||||||
|  | @@ -200,6 +203,9 @@ adcli_tool_user_create (adcli_conn *conn,
 | ||||||
|  |  		case opt_unix_shell: | ||||||
|  |  			adcli_attrs_add (attrs, "loginShell", optarg, NULL); | ||||||
|  |  			break; | ||||||
|  | +		case opt_nis_domain:
 | ||||||
|  | +			adcli_attrs_add (attrs, "msSFU30NisDomain", optarg, NULL);
 | ||||||
|  | +			break;
 | ||||||
|  |  		case opt_domain_ou: | ||||||
|  |  			ou = optarg; | ||||||
|  |  			break; | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										32
									
								
								0001-delete-do-not-exit-if-keytab-cannot-be-read.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								0001-delete-do-not-exit-if-keytab-cannot-be-read.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | From 40d3be22f6e518e4354aa7c3d0278291fcbed32f Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 5 Jun 2020 17:06:58 +0200 | ||||||
|  | Subject: [PATCH] delete: do not exit if keytab cannot be read | ||||||
|  | 
 | ||||||
|  | Reading the keytab is not required when deleting a host object in AD. It | ||||||
|  | is only needed in the case where the host was added with a manual set | ||||||
|  | NetBIOS name (--computer-name option) which does not match the short | ||||||
|  | hostname and no computer name was given at the delete-computer command | ||||||
|  | line. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1840752 | ||||||
|  | ---
 | ||||||
|  |  tools/computer.c | 2 -- | ||||||
|  |  1 file changed, 2 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index 292c4d8..a90c4b2 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -952,8 +952,6 @@ adcli_tool_computer_delete (adcli_conn *conn,
 | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  |  		warnx ("couldn't lookup domain info from keytab: %s", | ||||||
|  |  		       adcli_get_last_error ()); | ||||||
|  | -		adcli_enroll_unref (enroll);
 | ||||||
|  | -		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	res = adcli_conn_connect (conn); | ||||||
|  | -- 
 | ||||||
|  | 2.26.2 | ||||||
|  | 
 | ||||||
							
								
								
									
										27
									
								
								0001-discovery-fix.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								0001-discovery-fix.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | From 08bac0946de29f3e5de90743ce6dfc7118d4ad20 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 11 Feb 2020 17:42:03 +0100 | ||||||
|  | Subject: [PATCH] discovery fix | ||||||
|  | 
 | ||||||
|  | Do not continue processing on closed connection. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1802258 | ||||||
|  | ---
 | ||||||
|  |  library/addisco.c | 1 + | ||||||
|  |  1 file changed, 1 insertion(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/addisco.c b/library/addisco.c
 | ||||||
|  | index 6e73ead..f3b3546 100644
 | ||||||
|  | --- a/library/addisco.c
 | ||||||
|  | +++ b/library/addisco.c
 | ||||||
|  | @@ -622,6 +622,7 @@ ldap_disco (const char *domain,
 | ||||||
|  |  			                            "Couldn't perform discovery search"); | ||||||
|  |  			ldap_unbind_ext_s (ldap[i], NULL, NULL); | ||||||
|  |  			ldap[i] = NULL; | ||||||
|  | +			continue;
 | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  		/* From https://msdn.microsoft.com/en-us/library/ff718294.aspx first | ||||||
|  | -- 
 | ||||||
|  | 2.26.2 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,25 @@ | |||||||
|  | From 2edc26afda17db1a92703deb16658e9de9f79e14 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 3 Sep 2019 14:39:37 +0200 | ||||||
|  | Subject: [PATCH] doc: add missing samba_data_tool_path.xml(.in) to EXTRA_DIST | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  doc/Makefile.am | 2 ++ | ||||||
|  |  1 file changed, 2 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/Makefile.am b/doc/Makefile.am
 | ||||||
|  | index 3a53843..4490688 100644
 | ||||||
|  | --- a/doc/Makefile.am
 | ||||||
|  | +++ b/doc/Makefile.am
 | ||||||
|  | @@ -31,6 +31,8 @@ EXTRA_DIST = \
 | ||||||
|  |  	static \ | ||||||
|  |  	version.xml.in \ | ||||||
|  |  	version.xml \ | ||||||
|  | +	samba_data_tool_path.xml.in \
 | ||||||
|  | +	samba_data_tool_path.xml \
 | ||||||
|  |  	$(NULL) | ||||||
|  |   | ||||||
|  |  CLEANFILES = \ | ||||||
|  | -- 
 | ||||||
|  | 2.28.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										30
									
								
								0001-doc-explain-how-to-force-password-reset.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								0001-doc-explain-how-to-force-password-reset.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | From 9b187095edb8c914238419ed51fef6041864f4fc Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 26 Aug 2019 13:33:24 +0200 | ||||||
|  | Subject: [PATCH] doc: explain how to force password reset | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1738573 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml | 6 +++++- | ||||||
|  |  1 file changed, 5 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index 094f577..4f201e0 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -330,7 +330,11 @@ Password for Administrator:
 | ||||||
|  |  			important here is currently the | ||||||
|  |  			<option>workgroup</option> option, see | ||||||
|  |  			<citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> | ||||||
|  | -			for details.</para></listitem>
 | ||||||
|  | +			for details.</para>
 | ||||||
|  | +			<para>Note that if the machine account password is not
 | ||||||
|  | +			older than 30 days, you have to pass
 | ||||||
|  | +			<option>--computer-password-lifetime=0</option> to
 | ||||||
|  | +			force the update.</para></listitem>
 | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term> | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										242
									
								
								0001-doc-explain-required-AD-permissions.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								0001-doc-explain-required-AD-permissions.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,242 @@ | |||||||
|  | From fa5c5fb4f8e7bcadf3e5a3798bd060720fd35eaa Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 20 Oct 2020 13:34:41 +0200 | ||||||
|  | Subject: [PATCH] doc: explain required AD permissions | ||||||
|  | 
 | ||||||
|  | When using a restricted account with adcli some operations might fail | ||||||
|  | because the account might not have all required permissions. The man | ||||||
|  | page is extended and now explains which permissions are needed under | ||||||
|  | given circumstances. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1852080 | ||||||
|  | Resolves: https://gitlab.freedesktop.org/realmd/adcli/-/issues/20 | ||||||
|  | ---
 | ||||||
|  |  doc/Makefile.am    |  10 ++++ | ||||||
|  |  doc/adcli.xml      | 132 +++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  library/adenroll.c |  30 ++++++----- | ||||||
|  |  3 files changed, 160 insertions(+), 12 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/Makefile.am b/doc/Makefile.am
 | ||||||
|  | index 4490688..50fb777 100644
 | ||||||
|  | --- a/doc/Makefile.am
 | ||||||
|  | +++ b/doc/Makefile.am
 | ||||||
|  | @@ -33,14 +33,17 @@ EXTRA_DIST = \
 | ||||||
|  |  	version.xml \ | ||||||
|  |  	samba_data_tool_path.xml.in \ | ||||||
|  |  	samba_data_tool_path.xml \ | ||||||
|  | +	permissions.xml \
 | ||||||
|  |  	$(NULL) | ||||||
|  |   | ||||||
|  |  CLEANFILES = \ | ||||||
|  |  	$(man8_MANS) \ | ||||||
|  | +	permissions.xml \
 | ||||||
|  |  	$(NULL) | ||||||
|  |   | ||||||
|  |  XSLTPROC_FLAGS = \ | ||||||
|  |  	--nonet \ | ||||||
|  | +	--xinclude \
 | ||||||
|  |  	--stringparam man.output.quietly 1 \ | ||||||
|  |  	--stringparam funcsynopsis.style ansi \ | ||||||
|  |  	--stringparam man.th.extra1.suppress 1 \ | ||||||
|  | @@ -50,6 +53,13 @@ XSLTPROC_FLAGS = \
 | ||||||
|  |  XSLTPROC_MAN = \ | ||||||
|  |  	$(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl | ||||||
|  |   | ||||||
|  | +permissions.xml: ../library/adenroll.c adcli.xml
 | ||||||
|  | +	echo "<itemizedlist>" > $@
 | ||||||
|  | +	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' >> $@
 | ||||||
|  | +	echo "</itemizedlist>" >> $@
 | ||||||
|  | +
 | ||||||
|  | +$(man8_MANS): permissions.xml
 | ||||||
|  | +
 | ||||||
|  |  .xml.8: | ||||||
|  |  	$(AM_V_GEN) $(XSLTPROC_MAN) $< | ||||||
|  |   | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index 1437679..cc44fd8 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -885,6 +885,138 @@ Password for Administrator:
 | ||||||
|  |   | ||||||
|  |  </refsect1> | ||||||
|  |   | ||||||
|  | +<refsect1 id='delegation'>
 | ||||||
|  | +	<title>Delegated Permissions</title>
 | ||||||
|  | +	<para>It is common practice in AD to not use an account from the Domain
 | ||||||
|  | +	Administrators group to join a machine to a domain but use a dedicated
 | ||||||
|  | +	account which only has permissions to join a machine to one or more OUs
 | ||||||
|  | +	in the Active Directory tree. Giving the needed permissions to a single
 | ||||||
|  | +	account or a group in Active Directory is called Delegation. A typical
 | ||||||
|  | +	example on how to configured Delegation can be found in the Delegation
 | ||||||
|  | +	section of the blog post
 | ||||||
|  | +	<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>.
 | ||||||
|  | +	</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>When using an account with delegated permissions with adcli
 | ||||||
|  | +	basically the same applies as well. However some aspects are explained
 | ||||||
|  | +	here in a bit more details to better illustrate different concepts of
 | ||||||
|  | +	Active Directory and to make it more easy to debug permissions issues
 | ||||||
|  | +	during the join. Please note that the following is not specific to
 | ||||||
|  | +	adcli but applies to all applications which would like to modify
 | ||||||
|  | +	certain properties or objects in Active Directory with an account with
 | ||||||
|  | +	limited permissions.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>First, as said in the blog post it is sufficient to have
 | ||||||
|  | +	<literal>"Create computer object"</literal> permissions to join a
 | ||||||
|  | +	computer to a domain. But this would only work as expected if the
 | ||||||
|  | +	computer object does not exist in Active Directory before the join.
 | ||||||
|  | +	Because only when a new object is created Active Directory does not
 | ||||||
|  | +	apply additional permission checks on the attributes of the new
 | ||||||
|  | +	computer object. This means the delegated user can add any kind of
 | ||||||
|  | +	attribute with any value to a new computer object also long as they
 | ||||||
|  | +	meet general constraints like e.g. that the attribute must be defined
 | ||||||
|  | +	in the schema and is allowed in a objectclass of the object, the value
 | ||||||
|  | +	must match the syntax defined in the schema or that the
 | ||||||
|  | +	<option>sAMAccountName</option> must be unique in the domain.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>If you want to use the account with delegated permission to
 | ||||||
|  | +	remove computer objects in Active Directory (adcli delete-computer) you
 | ||||||
|  | +	should of course make sure that the account has
 | ||||||
|  | +	<literal>"Delete computer object"</literal> permissions.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>If the computer object already exists the
 | ||||||
|  | +	<literal>"Create computer object"</literal> permission does not apply
 | ||||||
|  | +	anymore since now an existing object must be modified. Now permissions
 | ||||||
|  | +	on the individual attributes are needed. e.g.
 | ||||||
|  | +	<literal>"Read and write Account Restrictions"</literal> or
 | ||||||
|  | +	<literal>"Reset Password"</literal>. For some attributes Active
 | ||||||
|  | +	Directory has two types of permissions the plain
 | ||||||
|  | +	<literal>"Read and Write"</literal> permissions and the
 | ||||||
|  | +	<literal>"Validated Write"</literal> permissions. For the latter case
 | ||||||
|  | +	there are two specific permissions relevant for adcli, namely
 | ||||||
|  | +		<itemizedlist>
 | ||||||
|  | +			<listitem><para>Validated write to DNS host name</para></listitem>
 | ||||||
|  | +			<listitem><para>Validated write to service principal name</para></listitem>
 | ||||||
|  | +		</itemizedlist>
 | ||||||
|  | +	Details about the validation of the values can be found in the
 | ||||||
|  | +	<literal>"Validated Writes"</literal> section of
 | ||||||
|  | +	<literal>[MS-ADTS]</literal>, especially
 | ||||||
|  | +	<ulink url="https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/5c578b15-d619-408d-ba17-380714b89fd1">dNSHostName</ulink>
 | ||||||
|  | +	and
 | ||||||
|  | +	<ulink url="https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/28ca4eca-0e0b-4666-9175-a37ccb8edada">servicePrincipalName</ulink>.
 | ||||||
|  | +	To cut it short for <literal>"Validated write to DNS host name"</literal>
 | ||||||
|  | +	the domain part of the fully-qualified hostname must either match the
 | ||||||
|  | +	domain name of the domain you want to join to or must be listed in the
 | ||||||
|  | +	<option>msDS-AllowedDNSSuffixes</option> attribute. And for
 | ||||||
|  | +	<literal>"Validated write to service principal name"</literal> the
 | ||||||
|  | +	hostname part of the service principal name must match the name stored
 | ||||||
|  | +	in <option>dNSHostName</option> or some other attributes which are
 | ||||||
|  | +	not handled by adcli. This also means that
 | ||||||
|  | +	<option>dNSHostName</option> cannot be empty or only contain a short
 | ||||||
|  | +	name if the service principal name should contain a fully-qualified
 | ||||||
|  | +	name.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>To summarize, if you only have validated write permissions you
 | ||||||
|  | +	should make sure the domain part of the hostname matches the domain you
 | ||||||
|  | +	want to join or use the <option>--host-fqdn</option> with a matching
 | ||||||
|  | +	name.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>The plain read write permissions do not run additional
 | ||||||
|  | +	validations but the attribute values must still be in agreement with
 | ||||||
|  | +	the general constraints mentioned above. If the computer object already
 | ||||||
|  | +	exists adcli might need the following permissions which are also needed
 | ||||||
|  | +	by Windows clients to modify existing attributes:
 | ||||||
|  | +		<itemizedlist>
 | ||||||
|  | +			<listitem><para>Reset Password</para></listitem>
 | ||||||
|  | +			<listitem><para>Read and write Account Restrictions</para></listitem>
 | ||||||
|  | +			<listitem><para>Read and (validated) write to DNS host name</para></listitem>
 | ||||||
|  | +			<listitem><para>Read and (validated) write to service principal name</para></listitem>
 | ||||||
|  | +		</itemizedlist>
 | ||||||
|  | +	additionally adcli needs
 | ||||||
|  | +		<itemizedlist>
 | ||||||
|  | +			<listitem><para>Read and write msDS-supportedEncryptionTypes</para></listitem>
 | ||||||
|  | +		</itemizedlist>
 | ||||||
|  | +	This is added for security reasons to avoid that Active Directory
 | ||||||
|  | +	stores Kerberos keys with (potentially weaker) encryption types than
 | ||||||
|  | +	the client supports since Active Directory is often configured to still
 | ||||||
|  | +	support older (weaker) encryption types for compatibility reasons.
 | ||||||
|  | +	</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>All other attributes are only set or modified on demand, i.e.
 | ||||||
|  | +	adcli must be called with an option the would set or modify the given
 | ||||||
|  | +	attribute. In the following the attributes adcli can modify together
 | ||||||
|  | +	with the required permissions are listed:
 | ||||||
|  | +	<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="permissions.xml" />
 | ||||||
|  | +	</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>For the management of users and groups (adcli create-user,
 | ||||||
|  | +	adcli delete-user, adcli create-group, adcli delete-group) the same
 | ||||||
|  | +	applies only for different types of objects, i.e. users and groups.
 | ||||||
|  | +	Since currently adcli only supports the creation and the removal of
 | ||||||
|  | +	user and group objects it is sufficient to have the
 | ||||||
|  | +	<literal>"Create/Delete User objects"</literal> and
 | ||||||
|  | +	<literal>"Create/Delete Group objects"</literal> permissions.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>If you want to manage group members as well (adcli add-member,
 | ||||||
|  | +	adcli remove-member) <literal>"Read/Write Members"</literal> permissions
 | ||||||
|  | +	are needed as well.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>Depending on the version of Active Directory the
 | ||||||
|  | +	<literal>"Delegation of Control Wizard"</literal> might offer some
 | ||||||
|  | +	shortcuts for common task like e.g.
 | ||||||
|  | +		<itemizedlist>
 | ||||||
|  | +			<listitem><para>Create, delete and manage user accounts</para></listitem>
 | ||||||
|  | +			<listitem><para>Create, delete and manage groups</para></listitem>
 | ||||||
|  | +			<listitem><para>Modify the membership of a group</para></listitem>
 | ||||||
|  | +		</itemizedlist>
 | ||||||
|  | +	The first 2 shortcuts will provided full access to user and group
 | ||||||
|  | +	objects which, as explained above, is more than currently is needed.
 | ||||||
|  | +	After using those shortcut it is a good idea to verify in the
 | ||||||
|  | +	<literal>"Security"</literal> tab in the <literal>"Properties"</literal>
 | ||||||
|  | +	of the related Active Directory container that the assigned permissions
 | ||||||
|  | +	meet the expectations.</para>
 | ||||||
|  | +</refsect1>
 | ||||||
|  | +
 | ||||||
|  |  <refsect1 id='bugs'> | ||||||
|  |  	<title>Bugs</title> | ||||||
|  |  	<para> | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index e745295..98e9786 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -71,19 +71,25 @@ static krb5_enctype v51_earlier_enctypes[] = {
 | ||||||
|  |  	0 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +/* The following list containst all attributes handled by adcli, some are
 | ||||||
|  | + * read-only and the others can be written as well. To properly document the
 | ||||||
|  | + * required permissions each attribute which adcli tries to modify should have
 | ||||||
|  | + * a comment starting with ':ADPermissions:' and the related permissions in AD
 | ||||||
|  | + * on the same line. Multiple permissions can be seperated with a '*'. For all
 | ||||||
|  | + * other attribute a suitable comment is very welcome. */
 | ||||||
|  |  static char *default_ad_ldap_attrs[] =  { | ||||||
|  | -	"sAMAccountName",
 | ||||||
|  | -	"userPrincipalName",
 | ||||||
|  | -	"msDS-KeyVersionNumber",
 | ||||||
|  | -	"msDS-supportedEncryptionTypes",
 | ||||||
|  | -	"dNSHostName",
 | ||||||
|  | -	"servicePrincipalName",
 | ||||||
|  | -	"operatingSystem",
 | ||||||
|  | -	"operatingSystemVersion",
 | ||||||
|  | -	"operatingSystemServicePack",
 | ||||||
|  | -	"pwdLastSet",
 | ||||||
|  | -	"userAccountControl",
 | ||||||
|  | -	"description",
 | ||||||
|  | +	"sAMAccountName", /* Only set during creation */
 | ||||||
|  | +	"userPrincipalName",   /* :ADPermissions: Read/Write userPrincipal Name */
 | ||||||
|  | +	"msDS-KeyVersionNumber", /* Manages by AD */
 | ||||||
|  | +	"msDS-supportedEncryptionTypes", /* :ADPermissions: Read/Write msDS-SupportedEncryptionTypes */
 | ||||||
|  | +	"dNSHostName", /* :ADPermissions: Read/Write dNSHostName * Read and write DNS host name attributes * Validated write to DNS host name */
 | ||||||
|  | +	"servicePrincipalName", /* :ADPermissions: Read/Write servicePrincipalName * Validated write to service principal name */
 | ||||||
|  | +	"operatingSystem", /* :ADPermissions: Read/Write Operating System */
 | ||||||
|  | +	"operatingSystemVersion", /* :ADPermissions: Read/Write Operating System Version */
 | ||||||
|  | +	"operatingSystemServicePack", /* :ADPermissions: Read/Write operatingSystemServicePack */
 | ||||||
|  | +	"pwdLastSet", /* Managed by AD */
 | ||||||
|  | +	"userAccountControl", /* :ADPermissions: Read/Write userAccountControl */
 | ||||||
|  | +	"description", /* :ADPermissions: Read/Write Description */
 | ||||||
|  |  	NULL, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.28.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										66
									
								
								0001-enroll-add-is_service-member.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								0001-enroll-add-is_service-member.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | |||||||
|  | From 4e4dbf8d2b437808863f8be85e7f30865d88c7fc Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 23 Oct 2020 16:46:43 +0200 | ||||||
|  | Subject: [PATCH 1/7] enroll: add is_service member | ||||||
|  | 
 | ||||||
|  | Add helpers to indicate a managed service account. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1854112 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 17 +++++++++++++++++ | ||||||
|  |  library/adenroll.h |  4 ++++ | ||||||
|  |  2 files changed, 21 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 98e9786..5ae1f7b 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -103,6 +103,8 @@ static char *default_ad_ldap_attrs[] =  {
 | ||||||
|  |  struct _adcli_enroll { | ||||||
|  |  	int refs; | ||||||
|  |  	adcli_conn *conn; | ||||||
|  | +	bool is_service;
 | ||||||
|  | +	bool is_service_explicit;
 | ||||||
|  |   | ||||||
|  |  	char *host_fqdn; | ||||||
|  |  	int host_fqdn_explicit; | ||||||
|  | @@ -2942,6 +2944,21 @@ adcli_enroll_get_desciption (adcli_enroll *enroll)
 | ||||||
|  |  	return enroll->description; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void
 | ||||||
|  | +adcli_enroll_set_is_service (adcli_enroll *enroll, bool value)
 | ||||||
|  | +{
 | ||||||
|  | +	return_if_fail (enroll != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	enroll->is_service = value;
 | ||||||
|  | +	enroll->is_service_explicit = true;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +bool
 | ||||||
|  | +adcli_enroll_get_is_service (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	return enroll->is_service;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  const char ** | ||||||
|  |  adcli_enroll_get_service_principals_to_add (adcli_enroll *enroll) | ||||||
|  |  { | ||||||
|  | diff --git a/library/adenroll.h b/library/adenroll.h
 | ||||||
|  | index 0606169..7765ed4 100644
 | ||||||
|  | --- a/library/adenroll.h
 | ||||||
|  | +++ b/library/adenroll.h
 | ||||||
|  | @@ -130,6 +130,10 @@ const char *       adcli_enroll_get_desciption          (adcli_enroll *enroll);
 | ||||||
|  |  void               adcli_enroll_set_description         (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);
 | ||||||
|  | +
 | ||||||
|  |  krb5_kvno          adcli_enroll_get_kvno                (adcli_enroll *enroll); | ||||||
|  |   | ||||||
|  |  void               adcli_enroll_set_kvno                (adcli_enroll *enroll, | ||||||
|  | -- 
 | ||||||
|  | 2.28.0 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,72 @@ | |||||||
|  | From 3a84c2469c31967bc22c0490456f07723ef5fc86 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 20 Mar 2019 11:01:50 +0100 | ||||||
|  | Subject: [PATCH 1/4] ensure_keytab_principals: do not leak memory when called | ||||||
|  |  twice | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1630187 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 32 +++++++++++++++++++++----------- | ||||||
|  |  1 file changed, 21 insertions(+), 11 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index d1f746c..48cb4cf 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -413,6 +413,25 @@ ensure_service_principals (adcli_result res,
 | ||||||
|  |  	return res; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static void enroll_clear_keytab_principals (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	krb5_context k5;
 | ||||||
|  | +	size_t c;
 | ||||||
|  | +
 | ||||||
|  | +	if (enroll->keytab_principals) {
 | ||||||
|  | +		k5 = adcli_conn_get_krb5_context (enroll->conn);
 | ||||||
|  | +		return_if_fail (k5 != NULL);
 | ||||||
|  | +
 | ||||||
|  | +		for (c = 0; enroll->keytab_principals[c] != NULL; c++)
 | ||||||
|  | +			krb5_free_principal (k5, enroll->keytab_principals[c]);
 | ||||||
|  | +
 | ||||||
|  | +		free (enroll->keytab_principals);
 | ||||||
|  | +		enroll->keytab_principals = NULL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static adcli_result | ||||||
|  |  ensure_keytab_principals (adcli_result res, | ||||||
|  |                            adcli_enroll *enroll) | ||||||
|  | @@ -430,6 +449,7 @@ ensure_keytab_principals (adcli_result res,
 | ||||||
|  |  	k5 = adcli_conn_get_krb5_context (enroll->conn); | ||||||
|  |  	return_unexpected_if_fail (k5 != NULL); | ||||||
|  |   | ||||||
|  | +	enroll_clear_keytab_principals (enroll);
 | ||||||
|  |  	enroll->keytab_principals = calloc (count + 3, sizeof (krb5_principal)); | ||||||
|  |  	return_unexpected_if_fail (enroll->keytab_principals != NULL); | ||||||
|  |  	at = 0; | ||||||
|  | @@ -1860,18 +1880,8 @@ static void
 | ||||||
|  |  enroll_clear_state (adcli_enroll *enroll) | ||||||
|  |  { | ||||||
|  |  	krb5_context k5; | ||||||
|  | -	int i;
 | ||||||
|  | -
 | ||||||
|  | -	if (enroll->keytab_principals) {
 | ||||||
|  | -		k5 = adcli_conn_get_krb5_context (enroll->conn);
 | ||||||
|  | -		return_if_fail (k5 != NULL);
 | ||||||
|  | -
 | ||||||
|  | -		for (i = 0; enroll->keytab_principals[i] != NULL; i++)
 | ||||||
|  | -			krb5_free_principal (k5, enroll->keytab_principals[i]);
 | ||||||
|  |   | ||||||
|  | -		free (enroll->keytab_principals);
 | ||||||
|  | -		enroll->keytab_principals = NULL;
 | ||||||
|  | -	}
 | ||||||
|  | +	enroll_clear_keytab_principals (enroll);
 | ||||||
|  |   | ||||||
|  |  	if (enroll->keytab) { | ||||||
|  |  		k5 = adcli_conn_get_krb5_context (enroll->conn); | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										25
									
								
								0001-fix-typo-in-flag-value.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								0001-fix-typo-in-flag-value.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | From 870ecd8f982ebb97092a93d730ad4006bd78505c Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 8 Aug 2018 12:03:01 +0200 | ||||||
|  | Subject: [PATCH 1/4] fix typo in flag value | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.h | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.h b/library/adenroll.h
 | ||||||
|  | index f87dffa..abbbfd4 100644
 | ||||||
|  | --- a/library/adenroll.h
 | ||||||
|  | +++ b/library/adenroll.h
 | ||||||
|  | @@ -30,7 +30,7 @@ typedef enum {
 | ||||||
|  |  	ADCLI_ENROLL_NO_KEYTAB = 1 << 1, | ||||||
|  |  	ADCLI_ENROLL_ALLOW_OVERWRITE = 1 << 2, | ||||||
|  |  	ADCLI_ENROLL_PASSWORD_VALID = 1 << 3, | ||||||
|  | -	ADCLI_ENROLL_ADD_SAMBA_DATA = 1 << 3,
 | ||||||
|  | +	ADCLI_ENROLL_ADD_SAMBA_DATA = 1 << 4,
 | ||||||
|  |  } adcli_enroll_flags; | ||||||
|  |   | ||||||
|  |  typedef struct _adcli_enroll adcli_enroll; | ||||||
|  | -- 
 | ||||||
|  | 2.17.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										86
									
								
								0001-join-always-add-service-principals.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								0001-join-always-add-service-principals.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,86 @@ | |||||||
|  | From cd296bf24e7cc56fb8d00bad7e9a56c539894309 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 19 Mar 2019 20:44:36 +0100 | ||||||
|  | Subject: [PATCH 1/2] join: always add service principals | ||||||
|  | 
 | ||||||
|  | If currently --service-name is given during the join only the service | ||||||
|  | names given by this option are added as service principal names. As a | ||||||
|  | result the default 'host' service principal name might be missing which | ||||||
|  | might cause issues e.g. with SSSD and sshd. | ||||||
|  | 
 | ||||||
|  | The patch makes sure the default service principals 'host' and | ||||||
|  | 'RestrictedKrbHost' are always added during join. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1644311 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 36 ++++++++++++++++++++++++++++++------ | ||||||
|  |  1 file changed, 30 insertions(+), 6 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 58362c2..d1f746c 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -288,16 +288,23 @@ ensure_computer_password (adcli_result res,
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static adcli_result | ||||||
|  | -ensure_service_names (adcli_result res,
 | ||||||
|  | -                      adcli_enroll *enroll)
 | ||||||
|  | +ensure_default_service_names (adcli_enroll *enroll)
 | ||||||
|  |  { | ||||||
|  |  	int length = 0; | ||||||
|  |   | ||||||
|  | -	if (res != ADCLI_SUCCESS)
 | ||||||
|  | -		return res;
 | ||||||
|  | +	if (enroll->service_names != NULL) {
 | ||||||
|  | +		length = seq_count (enroll->service_names);
 | ||||||
|  |   | ||||||
|  | -	if (enroll->service_names || enroll->service_principals)
 | ||||||
|  | -		return ADCLI_SUCCESS;
 | ||||||
|  | +		/* Make sure there is no entry with an unexpected case. AD
 | ||||||
|  | +		 * would not care but since the client side is case-sensitive
 | ||||||
|  | +		 * we should make sure we use the expected spelling. */
 | ||||||
|  | +		seq_remove_unsorted (enroll->service_names,
 | ||||||
|  | +		                     &length, "host",
 | ||||||
|  | +		                     (seq_compar)strcasecmp, free);
 | ||||||
|  | +		seq_remove_unsorted (enroll->service_names,
 | ||||||
|  | +		                     &length, "RestrictedKrbHost",
 | ||||||
|  | +		                     (seq_compar)strcasecmp, free);
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	/* The default ones specified by MS */ | ||||||
|  |  	enroll->service_names = _adcli_strv_add (enroll->service_names, | ||||||
|  | @@ -307,6 +314,19 @@ ensure_service_names (adcli_result res,
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static adcli_result
 | ||||||
|  | +ensure_service_names (adcli_result res,
 | ||||||
|  | +                      adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	if (res != ADCLI_SUCCESS)
 | ||||||
|  | +		return res;
 | ||||||
|  | +
 | ||||||
|  | +	if (enroll->service_names || enroll->service_principals)
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  | +
 | ||||||
|  | +	return ensure_default_service_names (enroll);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static adcli_result | ||||||
|  |  add_service_names_to_service_principals (adcli_enroll *enroll) | ||||||
|  |  { | ||||||
|  | @@ -2039,6 +2059,10 @@ adcli_enroll_join (adcli_enroll *enroll,
 | ||||||
|  |  	if (res != ADCLI_SUCCESS) | ||||||
|  |  		return res; | ||||||
|  |   | ||||||
|  | +	res = ensure_default_service_names (enroll);
 | ||||||
|  | +	if (res != ADCLI_SUCCESS)
 | ||||||
|  | +		return res;
 | ||||||
|  | +
 | ||||||
|  |  	res = adcli_enroll_prepare (enroll, flags); | ||||||
|  |  	if (res != ADCLI_SUCCESS) | ||||||
|  |  		return res; | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										59
									
								
								0001-join-update-set-dNSHostName-if-not-set.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								0001-join-update-set-dNSHostName-if-not-set.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | |||||||
|  | From beb7abfacc0010987d2cd8ab70f7c373d309eed9 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 15 Oct 2020 18:01:12 +0200 | ||||||
|  | Subject: [PATCH] join/update: set dNSHostName if not set | ||||||
|  | 
 | ||||||
|  | If during a join or update an existing AD computer object does not have | ||||||
|  | the dNSHostName attribute set it will be set with the current hostname. | ||||||
|  | This is important for cases where the user doing the join or update only | ||||||
|  | has "Validated write to service principal name" for the computer object. | ||||||
|  | The validated write with fully-qualified names can only be successful if | ||||||
|  | dNSHostName is set, see [MS-ADTS] section 3.1.1.5.3.1.1.4 "Validated | ||||||
|  | Writes - servicePrincipalName" for details. | ||||||
|  | 
 | ||||||
|  | Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1734764 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 16 ++++++++++++---- | ||||||
|  |  1 file changed, 12 insertions(+), 4 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 246f658..e745295 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -1403,21 +1403,29 @@ update_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  { | ||||||
|  |  	int res = 0; | ||||||
|  |  	LDAP *ldap; | ||||||
|  | +	char *value = NULL;
 | ||||||
|  |   | ||||||
|  |  	ldap = adcli_conn_get_ldap_connection (enroll->conn); | ||||||
|  |  	return_if_fail (ldap != NULL); | ||||||
|  |   | ||||||
|  |  	/* Only update attributes which are explicitly given on the command | ||||||
|  | -	 * line. Otherwise 'adcli update' must be always called with the same
 | ||||||
|  | -	 * set of options to make sure existing attributes are not deleted or
 | ||||||
|  | -	 * overwritten with different values. */
 | ||||||
|  | -	if (enroll->host_fqdn_explicit) {
 | ||||||
|  | +	 * line or not set in the existing AD object. Otherwise 'adcli update'
 | ||||||
|  | +	 * must be always called with the same set of options to make sure
 | ||||||
|  | +	 * existing attributes are not deleted or overwritten with different
 | ||||||
|  | +	 * values. */
 | ||||||
|  | +	if (enroll->computer_attributes != NULL) {
 | ||||||
|  | +		value = _adcli_ldap_parse_value (ldap,
 | ||||||
|  | +		                                 enroll->computer_attributes,
 | ||||||
|  | +		                                 "dNSHostName");
 | ||||||
|  | +	}
 | ||||||
|  | +	if (enroll->host_fqdn_explicit || value == NULL ) {
 | ||||||
|  |  		char *vals_dNSHostName[] = { enroll->host_fqdn, NULL }; | ||||||
|  |  		LDAPMod dNSHostName = { LDAP_MOD_REPLACE, "dNSHostName", { vals_dNSHostName, } }; | ||||||
|  |  		LDAPMod *mods[] = { &dNSHostName, NULL }; | ||||||
|  |   | ||||||
|  |  		res |= update_computer_attribute (enroll, ldap, mods); | ||||||
|  |  	} | ||||||
|  | +	free (value);
 | ||||||
|  |   | ||||||
|  |  	if (res == ADCLI_SUCCESS && enroll->trusted_for_delegation_explicit) { | ||||||
|  |  		char *vals_userAccountControl[] = { NULL , NULL }; | ||||||
|  | -- 
 | ||||||
|  | 2.28.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										34
									
								
								0001-library-add-missing-strdup.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								0001-library-add-missing-strdup.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | From a64cce9830c2e9c26e120f671b247ee71b45c888 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 12 Apr 2019 17:31:41 +0200 | ||||||
|  | Subject: [PATCH] library: add missing strdup | ||||||
|  | 
 | ||||||
|  | In add_server_side_service_principals _adcli_strv_add_unique is called | ||||||
|  | which only adds a string to a list without copying to. Since the | ||||||
|  | original list will be freed later the value must be copied. | ||||||
|  | 
 | ||||||
|  | This issue was introduce with 972f1a2f35829ed89f5353bd204683aa9ad6a2d2 | ||||||
|  | and hence | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1630187 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 3 ++- | ||||||
|  |  1 file changed, 2 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 1cce86a..52aa8a8 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -1987,7 +1987,8 @@ add_server_side_service_principals (adcli_enroll *enroll)
 | ||||||
|  |  		_adcli_info ("Checking %s", spn_list[c]); | ||||||
|  |  		if (!_adcli_strv_has_ex (enroll->service_principals_to_remove, spn_list[c], strcasecmp)) { | ||||||
|  |  			enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals, | ||||||
|  | -		                                                             spn_list[c], &length, false);
 | ||||||
|  | +			                                                     strdup (spn_list[c]),
 | ||||||
|  | +			                                                     &length, false);
 | ||||||
|  |  			assert (enroll->service_principals != NULL); | ||||||
|  |  			_adcli_info ("   Added %s", spn_list[c]); | ||||||
|  |  		} | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,50 @@ | |||||||
|  | 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/3] 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,13 +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_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 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,92 @@ | |||||||
|  | From 85b835f8258a57e3b23de47a255dddd822d5bfb3 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 15 Mar 2019 17:33:44 +0100 | ||||||
|  | Subject: [PATCH] library: use getaddrinfo with AI_CANONNAME to find a FQDN | ||||||
|  | 
 | ||||||
|  | Currently adcli creates service principals only with a short name if the | ||||||
|  | hostname of the client is a short name. This would fail is | ||||||
|  | Kerberos/GSSAPI clients will use the fully-qualified domain name (FQDN) | ||||||
|  | to access the host. | ||||||
|  | 
 | ||||||
|  | With this patch adcli tries to expand the short name by calling | ||||||
|  | getaddrinfo with the AI_CANONNAME hint. | ||||||
|  | 
 | ||||||
|  | Related to https://gitlab.freedesktop.org/realmd/adcli/issues/1 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml    |  6 +++++- | ||||||
|  |  library/adconn.c | 30 +++++++++++++++++++++++++++++- | ||||||
|  |  2 files changed, 34 insertions(+), 2 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index 97dec08..4722c3a 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -228,7 +228,11 @@ Password for Administrator:
 | ||||||
|  |  			<term><option>-H, --host-fqdn=<parameter>host</parameter></option></term> | ||||||
|  |  			<listitem><para>Override the local machine's fully qualified | ||||||
|  |  			domain name. If not specified, the local machine's hostname | ||||||
|  | -			will be retrieved via <function>gethostname()</function>.</para></listitem>
 | ||||||
|  | +			will be retrieved via <function>gethostname()</function>.
 | ||||||
|  | +			If <function>gethostname()</function> only returns a short name
 | ||||||
|  | +			<function>getaddrinfo()</function> with the AI_CANONNAME hint
 | ||||||
|  | +			is called to expand the name to a fully qualified domain
 | ||||||
|  | +			name.</para></listitem>
 | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-K, --host-keytab=<parameter>/path/to/keytab</parameter></option></term> | ||||||
|  | diff --git a/library/adconn.c b/library/adconn.c
 | ||||||
|  | index e2250e3..f6c23d3 100644
 | ||||||
|  | --- a/library/adconn.c
 | ||||||
|  | +++ b/library/adconn.c
 | ||||||
|  | @@ -86,11 +86,36 @@ struct _adcli_conn_ctx {
 | ||||||
|  |  	krb5_keytab keytab; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +static char *try_to_get_fqdn (const char *host_name)
 | ||||||
|  | +{
 | ||||||
|  | +	int ret;
 | ||||||
|  | +	char *fqdn = NULL;
 | ||||||
|  | +	struct addrinfo *res;
 | ||||||
|  | +	struct addrinfo hints;
 | ||||||
|  | +
 | ||||||
|  | +	memset (&hints, 0, sizeof (struct addrinfo));
 | ||||||
|  | +	hints.ai_socktype = SOCK_DGRAM;
 | ||||||
|  | +	hints.ai_flags = AI_CANONNAME;
 | ||||||
|  | +
 | ||||||
|  | +	ret = getaddrinfo (host_name, NULL, &hints, &res);
 | ||||||
|  | +	if (ret != 0) {
 | ||||||
|  | +		_adcli_err ("Failed to find FQDN: %s", gai_strerror (ret));
 | ||||||
|  | +		return NULL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	fqdn = strdup (res->ai_canonname);
 | ||||||
|  | +
 | ||||||
|  | +	freeaddrinfo (res);
 | ||||||
|  | +
 | ||||||
|  | +	return fqdn;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static adcli_result | ||||||
|  |  ensure_host_fqdn (adcli_result res, | ||||||
|  |                    adcli_conn *conn) | ||||||
|  |  { | ||||||
|  |  	char hostname[HOST_NAME_MAX + 1]; | ||||||
|  | +	char *fqdn = NULL;
 | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  |  	if (res != ADCLI_SUCCESS) | ||||||
|  | @@ -107,7 +132,10 @@ ensure_host_fqdn (adcli_result res,
 | ||||||
|  |  		return ADCLI_ERR_UNEXPECTED; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	conn->host_fqdn = strdup (hostname);
 | ||||||
|  | +	if (strchr (hostname, '.') == NULL) {
 | ||||||
|  | +		fqdn = try_to_get_fqdn (hostname);
 | ||||||
|  | +	}
 | ||||||
|  | +	conn->host_fqdn = fqdn != NULL ? fqdn : strdup (hostname);
 | ||||||
|  |  	return_unexpected_if_fail (conn->host_fqdn != NULL); | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,44 @@ | |||||||
|  | From 93a39bd12db11dd407676f428cfbc30406a88c36 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 15 Jun 2020 15:57:47 +0200 | ||||||
|  | Subject: [PATCH] man: explain optional parameter of login-ccache better | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1791545 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml | 20 +++++++++++++------- | ||||||
|  |  1 file changed, 13 insertions(+), 7 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index acced25..ecf8726 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -155,13 +155,19 @@ $ LDAPTLS_CACERT=/path/to/ad_dc_ca_cert.pem adcli join --use-ldaps -D domain.exa
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-C, --login-ccache=<parameter>ccache_name</parameter></option></term> | ||||||
|  |  			<listitem><para>Use the specified kerberos credential | ||||||
|  | -                        cache to authenticate with the domain. If no credential
 | ||||||
|  | -                        cache is specified, the default kerberos credential
 | ||||||
|  | -                        cache will be used. Credential caches of type FILE can
 | ||||||
|  | -                        be given with the path to the file. For other
 | ||||||
|  | -                        credential cache types, e.g. DIR, KEYRING or KCM, the
 | ||||||
|  | -                        type must be specified explicitly together with a
 | ||||||
|  | -                        suitable identifier.</para></listitem>
 | ||||||
|  | +			cache to authenticate with the domain. If no credential
 | ||||||
|  | +			cache is specified, the default kerberos credential
 | ||||||
|  | +			cache will be used. Credential caches of type FILE can
 | ||||||
|  | +			be given with the path to the file. For other
 | ||||||
|  | +			credential cache types, e.g. DIR, KEYRING or KCM, the
 | ||||||
|  | +			type must be specified explicitly together with a
 | ||||||
|  | +			suitable identifier.</para>
 | ||||||
|  | +			<para>Please note that since the
 | ||||||
|  | +			<parameter>ccache_name</parameter> is optional the
 | ||||||
|  | +			=(equal) sign is mandatory. If = is missing the
 | ||||||
|  | +			parameter is treated as optionless extra argument. How
 | ||||||
|  | +			this is handled depends on the specific sub-command.
 | ||||||
|  | +			</para></listitem>
 | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-U, --login-user=<parameter>User</parameter></option></term> | ||||||
|  | -- 
 | ||||||
|  | 2.26.2 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,41 @@ | |||||||
|  | From 88fbb7e2395dec20b37697a213a097909870c21f Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 13 Aug 2020 17:10:01 +0200 | ||||||
|  | Subject: [PATCH] man: make handling of optional credential cache more clear | ||||||
|  | 
 | ||||||
|  | The optional Kerberos credential cache can only be used with the long | ||||||
|  | option name --login-ccache and not with the short version -C. To make | ||||||
|  | this more clear each option get its own entry. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1791545 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml | 12 +++++++++--- | ||||||
|  |  1 file changed, 9 insertions(+), 3 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index ecf8726..1437679 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -153,10 +153,16 @@ $ LDAPTLS_CACERT=/path/to/ad_dc_ca_cert.pem adcli join --use-ldaps -D domain.exa
 | ||||||
|  |  			</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  | -			<term><option>-C, --login-ccache=<parameter>ccache_name</parameter></option></term>
 | ||||||
|  | -			<listitem><para>Use the specified kerberos credential
 | ||||||
|  | +			<term><option>-C</option></term>
 | ||||||
|  | +			<listitem><para>Use the default Kerberos credential
 | ||||||
|  | +			cache to authenticate with the domain.
 | ||||||
|  | +			</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--login-ccache<parameter>[=ccache_name]</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Use the specified Kerberos credential
 | ||||||
|  |  			cache to authenticate with the domain. If no credential | ||||||
|  | -			cache is specified, the default kerberos credential
 | ||||||
|  | +			cache is specified, the default Kerberos credential
 | ||||||
|  |  			cache will be used. Credential caches of type FILE can | ||||||
|  |  			be given with the path to the file. For other | ||||||
|  |  			credential cache types, e.g. DIR, KEYRING or KCM, the | ||||||
|  | -- 
 | ||||||
|  | 2.26.2 | ||||||
|  | 
 | ||||||
							
								
								
									
										48
									
								
								0001-man-move-note-to-the-right-section.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								0001-man-move-note-to-the-right-section.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | From d2d3879bdfcea70757a8b0527882e79e8b5c6e70 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 27 Nov 2019 18:26:44 +0100 | ||||||
|  | Subject: [PATCH] man: move note to the right section | ||||||
|  | 
 | ||||||
|  | Unfortunately the note about the password lifetime was added to the join | ||||||
|  | section. This patch move it to the update section where it belongs to. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1738573 | ||||||
|  |            https://bugzilla.redhat.com/show_bug.cgi?id=1745931 | ||||||
|  |            https://bugzilla.redhat.com/show_bug.cgi?id=1774622 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml | 12 ++++++------ | ||||||
|  |  1 file changed, 6 insertions(+), 6 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index 4f201e0..9faf96a 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -330,11 +330,7 @@ Password for Administrator:
 | ||||||
|  |  			important here is currently the | ||||||
|  |  			<option>workgroup</option> option, see | ||||||
|  |  			<citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> | ||||||
|  | -			for details.</para>
 | ||||||
|  | -			<para>Note that if the machine account password is not
 | ||||||
|  | -			older than 30 days, you have to pass
 | ||||||
|  | -			<option>--computer-password-lifetime=0</option> to
 | ||||||
|  | -			force the update.</para></listitem>
 | ||||||
|  | +			for details.</para></listitem>
 | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term> | ||||||
|  | @@ -472,7 +468,11 @@ $ adcli update --login-ccache=/tmp/krbcc_123
 | ||||||
|  |  			important here is currently the | ||||||
|  |  			<option>workgroup</option> option, see | ||||||
|  |  			<citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> | ||||||
|  | -			for details.</para></listitem>
 | ||||||
|  | +			for details.</para>
 | ||||||
|  | +			<para>Note that if the machine account password is not
 | ||||||
|  | +			older than 30 days, you have to pass
 | ||||||
|  | +			<option>--computer-password-lifetime=0</option> to
 | ||||||
|  | +			force the update.</para></listitem>
 | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term> | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										35
									
								
								0001-service-account-fix-typo-in-the-man-page-entry.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								0001-service-account-fix-typo-in-the-man-page-entry.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | From 637cc53953ef61c90530ae5eaf26eb4911336465 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 10 Dec 2020 18:29:18 +0100 | ||||||
|  | Subject: [PATCH] service-account: fix typo in the man page entry | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1906303 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml | 4 ++-- | ||||||
|  |  1 file changed, 2 insertions(+), 2 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index 14921f9..a64687a 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -943,7 +943,7 @@ Password for Administrator:
 | ||||||
|  |  	of the managed service account as a suffix. On most systems it would be | ||||||
|  |  	<filename>/etc/krb5.keytab</filename> with a suffix of | ||||||
|  |  	'domain.example.com', e.g. | ||||||
|  | -	<filename>/etc/krb5.keytad.domain.example.com</filename>.</para>
 | ||||||
|  | +	<filename>/etc/krb5.keytab.domain.example.com</filename>.</para>
 | ||||||
|  |   | ||||||
|  |  	<para><command>adcli create-msa</command> can be called multiple | ||||||
|  |  	times to reset the password of the managed service account. To identify | ||||||
|  | @@ -955,7 +955,7 @@ Password for Administrator:
 | ||||||
|  |   | ||||||
|  |  	<para>The managed service account password can be updated with | ||||||
|  |  <programlisting> | ||||||
|  | -$ adcli update --domain=domain.example.com --host-keytab=/etc/krb5.keytad.domain.example.com
 | ||||||
|  | +$ adcli update --domain=domain.example.com --host-keytab=/etc/krb5.keytab.domain.example.com
 | ||||||
|  |  </programlisting> | ||||||
|  |  	and the managed service account can be deleted with | ||||||
|  |  <programlisting> | ||||||
|  | -- 
 | ||||||
|  | 2.29.2 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,36 @@ | |||||||
|  | From 76ca1e6737742208d83e016d43a3379e378f8d90 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 14 Oct 2020 17:44:10 +0200 | ||||||
|  | Subject: [PATCH] tools: add missing use-ldaps option to update and testjoin | ||||||
|  | 
 | ||||||
|  | When adding the use-ldaps option the update and testjoin sub-commands | ||||||
|  | were forgotten. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1883467 | ||||||
|  | ---
 | ||||||
|  |  tools/computer.c | 2 ++ | ||||||
|  |  1 file changed, 2 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index 24ea258..5a97d8b 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -491,6 +491,7 @@ adcli_tool_computer_update (adcli_conn *conn,
 | ||||||
|  |  	struct option options[] = { | ||||||
|  |  		{ "domain", required_argument, NULL, opt_domain }, | ||||||
|  |  		{ "domain-controller", required_argument, NULL, opt_domain_controller }, | ||||||
|  | +		{ "use-ldaps", no_argument, 0, opt_use_ldaps },
 | ||||||
|  |  		{ "host-fqdn", required_argument, 0, opt_host_fqdn }, | ||||||
|  |  		{ "computer-name", required_argument, 0, opt_computer_name }, | ||||||
|  |  		{ "host-keytab", required_argument, 0, opt_host_keytab }, | ||||||
|  | @@ -612,6 +613,7 @@ adcli_tool_computer_testjoin (adcli_conn *conn,
 | ||||||
|  |  	struct option options[] = { | ||||||
|  |  		{ "domain", required_argument, NULL, opt_domain }, | ||||||
|  |  		{ "domain-controller", required_argument, NULL, opt_domain_controller }, | ||||||
|  | +		{ "use-ldaps", no_argument, 0, opt_use_ldaps },
 | ||||||
|  |  		{ "host-keytab", required_argument, 0, opt_host_keytab }, | ||||||
|  |  		{ "verbose", no_argument, NULL, opt_verbose }, | ||||||
|  |  		{ "help", no_argument, NULL, 'h' }, | ||||||
|  | -- 
 | ||||||
|  | 2.28.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										338
									
								
								0001-tools-add-show-computer-command.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								0001-tools-add-show-computer-command.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,338 @@ | |||||||
|  | From 0a169bd9b2687293f74bb57694eb82f9769610c9 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 27 Nov 2019 12:34:45 +0100 | ||||||
|  | Subject: [PATCH 1/2] tools: add show-computer command | ||||||
|  | 
 | ||||||
|  | The show-computer command prints the LDAP attributes of the related | ||||||
|  | computer object from AD. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1737342 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml      | 28 ++++++++++++++ | ||||||
|  |  library/adenroll.c | 78 +++++++++++++++++++++++++++++--------- | ||||||
|  |  library/adenroll.h |  5 +++ | ||||||
|  |  tools/computer.c   | 93 ++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  tools/tools.c      |  1 + | ||||||
|  |  tools/tools.h      |  4 ++ | ||||||
|  |  6 files changed, 191 insertions(+), 18 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index 9faf96a..1f93186 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -93,6 +93,11 @@
 | ||||||
|  |  		<arg choice="opt">--domain=domain.example.com</arg> | ||||||
|  |  		<arg choice="plain">computer</arg> | ||||||
|  |  	</cmdsynopsis> | ||||||
|  | +	<cmdsynopsis>
 | ||||||
|  | +		<command>adcli show-computer</command>
 | ||||||
|  | +		<arg choice="opt">--domain=domain.example.com</arg>
 | ||||||
|  | +		<arg choice="plain">computer</arg>
 | ||||||
|  | +	</cmdsynopsis>
 | ||||||
|  |  </refsynopsisdiv> | ||||||
|  |   | ||||||
|  |  <refsect1 id='general_overview'> | ||||||
|  | @@ -811,6 +816,29 @@ Password for Administrator:
 | ||||||
|  |   | ||||||
|  |  </refsect1> | ||||||
|  |   | ||||||
|  | +<refsect1 id='show_computer_account'>
 | ||||||
|  | +	<title>Show Computer Account Attributes</title>
 | ||||||
|  | +
 | ||||||
|  | +	<para><command>adcli show-computer</command> show the computer account
 | ||||||
|  | +	attributes stored in AD. The account must already exist.</para>
 | ||||||
|  | +
 | ||||||
|  | +<programlisting>
 | ||||||
|  | +$ adcli show-computer --domain=domain.example.com host2
 | ||||||
|  | +Password for Administrator:
 | ||||||
|  | +</programlisting>
 | ||||||
|  | +
 | ||||||
|  | +	<para>If the computer name contains a dot, then it is
 | ||||||
|  | +	treated as fully qualified host name, otherwise it is treated
 | ||||||
|  | +	as short computer name.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>If no computer name is specified, then the host name of the
 | ||||||
|  | +	computer adcli is running on is used, as returned by
 | ||||||
|  | +	<literal>gethostname()</literal>.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>The various global options can be used.</para>
 | ||||||
|  | +
 | ||||||
|  | +</refsect1>
 | ||||||
|  | +
 | ||||||
|  |  <refsect1 id='bugs'> | ||||||
|  |  	<title>Bugs</title> | ||||||
|  |  	<para> | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 524663a..8d2adeb 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -71,6 +71,21 @@ static krb5_enctype v51_earlier_enctypes[] = {
 | ||||||
|  |  	0 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +static char *default_ad_ldap_attrs[] =  {
 | ||||||
|  | +	"sAMAccountName",
 | ||||||
|  | +	"userPrincipalName",
 | ||||||
|  | +	"msDS-KeyVersionNumber",
 | ||||||
|  | +	"msDS-supportedEncryptionTypes",
 | ||||||
|  | +	"dNSHostName",
 | ||||||
|  | +	"servicePrincipalName",
 | ||||||
|  | +	"operatingSystem",
 | ||||||
|  | +	"operatingSystemVersion",
 | ||||||
|  | +	"operatingSystemServicePack",
 | ||||||
|  | +	"pwdLastSet",
 | ||||||
|  | +	"userAccountControl",
 | ||||||
|  | +	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. */ | ||||||
|  | @@ -1213,19 +1228,6 @@ retrieve_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  	char *end; | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  | -	char *attrs[] =  {
 | ||||||
|  | -		"msDS-KeyVersionNumber",
 | ||||||
|  | -		"msDS-supportedEncryptionTypes",
 | ||||||
|  | -		"dNSHostName",
 | ||||||
|  | -		"servicePrincipalName",
 | ||||||
|  | -		"operatingSystem",
 | ||||||
|  | -		"operatingSystemVersion",
 | ||||||
|  | -		"operatingSystemServicePack",
 | ||||||
|  | -		"pwdLastSet",
 | ||||||
|  | -		"userAccountControl",
 | ||||||
|  | -		NULL,
 | ||||||
|  | -	};
 | ||||||
|  | -
 | ||||||
|  |  	assert (enroll->computer_dn != NULL); | ||||||
|  |  	assert (enroll->computer_attributes == NULL); | ||||||
|  |   | ||||||
|  | @@ -1233,7 +1235,8 @@ retrieve_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  	assert (ldap != NULL); | ||||||
|  |   | ||||||
|  |  	ret = ldap_search_ext_s (ldap, enroll->computer_dn, LDAP_SCOPE_BASE, | ||||||
|  | -	                         "(objectClass=*)", attrs, 0, NULL, NULL, NULL, -1,
 | ||||||
|  | +	                         "(objectClass=*)", default_ad_ldap_attrs,
 | ||||||
|  | +	                         0, NULL, NULL, NULL, -1,
 | ||||||
|  |  	                         &enroll->computer_attributes); | ||||||
|  |   | ||||||
|  |  	if (ret != LDAP_SUCCESS) { | ||||||
|  | @@ -2179,12 +2182,11 @@ adcli_enroll_load (adcli_enroll *enroll)
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  adcli_result | ||||||
|  | -adcli_enroll_update (adcli_enroll *enroll,
 | ||||||
|  | -		     adcli_enroll_flags flags)
 | ||||||
|  | +adcli_enroll_read_computer_account (adcli_enroll *enroll,
 | ||||||
|  | +		                    adcli_enroll_flags flags)
 | ||||||
|  |  { | ||||||
|  |  	adcli_result res = ADCLI_SUCCESS; | ||||||
|  |  	LDAP *ldap; | ||||||
|  | -	char *value;
 | ||||||
|  |   | ||||||
|  |  	return_unexpected_if_fail (enroll != NULL); | ||||||
|  |   | ||||||
|  | @@ -2214,7 +2216,18 @@ adcli_enroll_update (adcli_enroll *enroll,
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	/* Get information about the computer account */ | ||||||
|  | -	res = retrieve_computer_account (enroll);
 | ||||||
|  | +	return retrieve_computer_account (enroll);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +adcli_result
 | ||||||
|  | +adcli_enroll_update (adcli_enroll *enroll,
 | ||||||
|  | +		     adcli_enroll_flags flags)
 | ||||||
|  | +{
 | ||||||
|  | +	adcli_result res = ADCLI_SUCCESS;
 | ||||||
|  | +	LDAP *ldap;
 | ||||||
|  | +	char *value;
 | ||||||
|  | +
 | ||||||
|  | +	res = adcli_enroll_read_computer_account (enroll, flags);
 | ||||||
|  |  	if (res != ADCLI_SUCCESS) | ||||||
|  |  		return res; | ||||||
|  |   | ||||||
|  | @@ -2242,6 +2255,35 @@ adcli_enroll_update (adcli_enroll *enroll,
 | ||||||
|  |  	return enroll_join_or_update_tasks (enroll, flags); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +adcli_result
 | ||||||
|  | +adcli_enroll_show_computer_attribute (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	LDAP *ldap;
 | ||||||
|  | +	size_t c;
 | ||||||
|  | +	char **vals;
 | ||||||
|  | +	size_t v;
 | ||||||
|  | +
 | ||||||
|  | +	ldap = adcli_conn_get_ldap_connection (enroll->conn);
 | ||||||
|  | +	assert (ldap != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	for (c = 0; default_ad_ldap_attrs[c] != NULL; c++) {
 | ||||||
|  | +		vals = _adcli_ldap_parse_values (ldap,
 | ||||||
|  | +		                                 enroll->computer_attributes,
 | ||||||
|  | +		                                 default_ad_ldap_attrs[c]);
 | ||||||
|  | +		printf ("%s:\n", default_ad_ldap_attrs[c]);
 | ||||||
|  | +		if (vals == NULL) {
 | ||||||
|  | +			printf (" - not set -\n");
 | ||||||
|  | +		} else {
 | ||||||
|  | +			for (v = 0; vals[v] != NULL; v++) {
 | ||||||
|  | +				printf (" %s\n", vals[v]);
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  | +		_adcli_strv_free (vals);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return ADCLI_SUCCESS;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  adcli_result | ||||||
|  |  adcli_enroll_delete (adcli_enroll *enroll, | ||||||
|  |                       adcli_enroll_flags delete_flags) | ||||||
|  | diff --git a/library/adenroll.h b/library/adenroll.h
 | ||||||
|  | index 1d5d00d..11eb517 100644
 | ||||||
|  | --- a/library/adenroll.h
 | ||||||
|  | +++ b/library/adenroll.h
 | ||||||
|  | @@ -46,6 +46,11 @@ adcli_result       adcli_enroll_join                    (adcli_enroll *enroll,
 | ||||||
|  |  adcli_result       adcli_enroll_update                  (adcli_enroll *enroll, | ||||||
|  |  		                                         adcli_enroll_flags flags); | ||||||
|  |   | ||||||
|  | +adcli_result       adcli_enroll_read_computer_account   (adcli_enroll *enroll,
 | ||||||
|  | +                                                         adcli_enroll_flags flags);
 | ||||||
|  | +
 | ||||||
|  | +adcli_result       adcli_enroll_show_computer_attribute (adcli_enroll *enroll);
 | ||||||
|  | +
 | ||||||
|  |  adcli_result       adcli_enroll_delete                  (adcli_enroll *enroll, | ||||||
|  |                                                           adcli_enroll_flags delete_flags); | ||||||
|  |   | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index ac8a203..c8b96a4 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -964,3 +964,96 @@ adcli_tool_computer_delete (adcli_conn *conn,
 | ||||||
|  |  	adcli_enroll_unref (enroll); | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +int
 | ||||||
|  | +adcli_tool_computer_show (adcli_conn *conn,
 | ||||||
|  | +                          int argc,
 | ||||||
|  | +                          char *argv[])
 | ||||||
|  | +{
 | ||||||
|  | +	adcli_enroll *enroll;
 | ||||||
|  | +	adcli_result res;
 | ||||||
|  | +	int opt;
 | ||||||
|  | +
 | ||||||
|  | +	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 },
 | ||||||
|  | +		{ "login-user", required_argument, NULL, opt_login_user },
 | ||||||
|  | +		{ "login-ccache", optional_argument, NULL, opt_login_ccache },
 | ||||||
|  | +		{ "login-type", required_argument, NULL, opt_login_type },
 | ||||||
|  | +		{ "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 show-computer --domain=xxxx host1.example.com" },
 | ||||||
|  | +		{ 0 },
 | ||||||
|  | +	};
 | ||||||
|  | +
 | ||||||
|  | +	enroll = adcli_enroll_new (conn);
 | ||||||
|  | +	if (enroll == NULL) {
 | ||||||
|  | +		warnx ("unexpected memory problems");
 | ||||||
|  | +		return -1;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	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);
 | ||||||
|  | +			adcli_enroll_unref (enroll);
 | ||||||
|  | +			return opt == 'h' ? 0 : 2;
 | ||||||
|  | +		default:
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				adcli_enroll_unref (enroll);
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  | +			break;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	argc -= optind;
 | ||||||
|  | +	argv += optind;
 | ||||||
|  | +
 | ||||||
|  | +	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_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (argc == 1) {
 | ||||||
|  | +		parse_fqdn_or_name (enroll, argv[0]);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	res = adcli_enroll_read_computer_account (enroll, 0);
 | ||||||
|  | +	if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +		warnx ("couldn't read data for %s: %s",
 | ||||||
|  | +		       adcli_enroll_get_host_fqdn (enroll) != NULL
 | ||||||
|  | +		           ? adcli_enroll_get_host_fqdn (enroll)
 | ||||||
|  | +		           : adcli_enroll_get_computer_name (enroll),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	res = adcli_enroll_show_computer_attribute (enroll);
 | ||||||
|  | +	if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +		warnx ("couldn't print data for %s: %s",
 | ||||||
|  | +		       argv[0], adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	adcli_enroll_unref (enroll);
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | diff --git a/tools/tools.c b/tools/tools.c
 | ||||||
|  | index fc9fa9a..9d422f2 100644
 | ||||||
|  | --- a/tools/tools.c
 | ||||||
|  | +++ b/tools/tools.c
 | ||||||
|  | @@ -59,6 +59,7 @@ struct {
 | ||||||
|  |  	{ "preset-computer", adcli_tool_computer_preset, "Pre setup computers accounts", }, | ||||||
|  |  	{ "reset-computer", adcli_tool_computer_reset, "Reset a computer account", }, | ||||||
|  |  	{ "delete-computer", adcli_tool_computer_delete, "Delete a computer account", }, | ||||||
|  | +	{ "show-computer", adcli_tool_computer_show, "Show computer account attributes stored in AD", },
 | ||||||
|  |  	{ "create-user", adcli_tool_user_create, "Create a user account", }, | ||||||
|  |  	{ "delete-user", adcli_tool_user_delete, "Delete a user account", }, | ||||||
|  |  	{ "create-group", adcli_tool_group_create, "Create a group", }, | ||||||
|  | diff --git a/tools/tools.h b/tools/tools.h
 | ||||||
|  | index 8cebbf9..3702875 100644
 | ||||||
|  | --- a/tools/tools.h
 | ||||||
|  | +++ b/tools/tools.h
 | ||||||
|  | @@ -78,6 +78,10 @@ int       adcli_tool_computer_delete   (adcli_conn *conn,
 | ||||||
|  |                                          int argc, | ||||||
|  |                                          char *argv[]); | ||||||
|  |   | ||||||
|  | +int       adcli_tool_computer_show     (adcli_conn *conn,
 | ||||||
|  | +                                        int argc,
 | ||||||
|  | +                                        char *argv[]);
 | ||||||
|  | +
 | ||||||
|  |  int       adcli_tool_user_create       (adcli_conn *conn, | ||||||
|  |                                          int argc, | ||||||
|  |                                          char *argv[]); | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										41
									
								
								0001-tools-disable-SSSD-s-locator-plugin.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								0001-tools-disable-SSSD-s-locator-plugin.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | From 50d580c58dab5928cadfc6ca82aedccee58eaced Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 5 Jun 2020 17:28:28 +0200 | ||||||
|  | Subject: [PATCH] tools: disable SSSD's locator plugin | ||||||
|  | 
 | ||||||
|  | MIT's libkrb5 checks available locator plugins first before checking the | ||||||
|  | config file. This might cause issues when the locator plugin returns a | ||||||
|  | different DC than the one used for the LDAP connection if some data must
 | ||||||
|  | be replicated. | ||||||
|  | 
 | ||||||
|  | This patch sets the SSSD_KRB5_LOCATOR_DISABLE environment variable to | ||||||
|  | 'true' to disable SSSD's locator plugin for adcli. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1762633 | ||||||
|  | ---
 | ||||||
|  |  tools/tools.c | 2 ++ | ||||||
|  |  1 file changed, 2 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/tools.c b/tools/tools.c
 | ||||||
|  | index 9d422f2..1b6d879 100644
 | ||||||
|  | --- a/tools/tools.c
 | ||||||
|  | +++ b/tools/tools.c
 | ||||||
|  | @@ -296,6 +296,7 @@ cleanup_krb5_conf_directory (void)
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	unsetenv ("KRB5_CONFIG"); | ||||||
|  | +	unsetenv ("SSSD_KRB5_LOCATOR_DISABLE");
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  | @@ -394,6 +395,7 @@ setup_krb5_conf_directory (adcli_conn *conn)
 | ||||||
|  |  		adcli_krb5_conf_filename = filename; | ||||||
|  |  		adcli_krb5_d_directory = snippets; | ||||||
|  |  		setenv ("KRB5_CONFIG", adcli_krb5_conf_filename, 1); | ||||||
|  | +		setenv ("SSSD_KRB5_LOCATOR_DISABLE", "true", 1);
 | ||||||
|  |   | ||||||
|  |  	} else { | ||||||
|  |  		free (filename); | ||||||
|  | -- 
 | ||||||
|  | 2.26.2 | ||||||
|  | 
 | ||||||
							
								
								
									
										26
									
								
								0001-tools-fix-typo-in-show-password-help-output.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								0001-tools-fix-typo-in-show-password-help-output.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | From d70075c597e7ebc1683d407409c45b04110676a0 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 15 Jun 2020 15:41:53 +0200 | ||||||
|  | Subject: [PATCH] tools: fix typo in show-password help output | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1791611 | ||||||
|  | ---
 | ||||||
|  |  tools/computer.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index a90c4b2..24ea258 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -154,7 +154,7 @@ static adcli_tool_desc common_usages[] = {
 | ||||||
|  |  	                         "accounts" }, | ||||||
|  |  	{ opt_show_details, "show information about joining the domain after\n" | ||||||
|  |  	                     "a successful join" }, | ||||||
|  | -	{ opt_show_password, "show computer account password after after a\n"
 | ||||||
|  | +	{ opt_show_password, "show computer account password after a\n"
 | ||||||
|  |  	                     "successful join" }, | ||||||
|  |  	{ opt_add_samba_data, "add domain SID and computer account password\n" | ||||||
|  |  	                      "to the Samba specific configuration database" }, | ||||||
|  | -- 
 | ||||||
|  | 2.26.2 | ||||||
|  | 
 | ||||||
							
								
								
									
										328
									
								
								0001-tools-remove-errx-from-computer-commands.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										328
									
								
								0001-tools-remove-errx-from-computer-commands.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,328 @@ | |||||||
|  | From fa7926c7a9d92bc7c42c610ba6f1706c635aa901 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 15 Apr 2019 17:54:27 +0200 | ||||||
|  | Subject: [PATCH 1/7] tools: remove errx from computer commands | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596 | ||||||
|  | ---
 | ||||||
|  |  tools/computer.c | 166 ++++++++++++++++++++++++++++++----------------- | ||||||
|  |  1 file changed, 107 insertions(+), 59 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index bee695c..9cbbb28 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -379,8 +379,10 @@ adcli_tool_computer_join (adcli_conn *conn,
 | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  |  	enroll = adcli_enroll_new (conn); | ||||||
|  | -	if (enroll == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	if (enroll == NULL) {
 | ||||||
|  | +		warnx ("unexpected memory problems");
 | ||||||
|  | +		return -1;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) { | ||||||
|  |  		switch (opt) { | ||||||
|  | @@ -415,21 +417,28 @@ adcli_tool_computer_join (adcli_conn *conn,
 | ||||||
|  |   | ||||||
|  |  	if (argc == 1) | ||||||
|  |  		adcli_conn_set_domain_name (conn, argv[0]); | ||||||
|  | -	else if (argc > 1)
 | ||||||
|  | -		errx (2, "extra arguments specified");
 | ||||||
|  | +	else if (argc > 1) {
 | ||||||
|  | +		warnx ("extra arguments specified");
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return 2;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	res = adcli_conn_connect (conn); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't connect to %s domain: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	res = adcli_enroll_join (enroll, flags); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "joining domain %s failed: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("joining domain %s failed: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (details) | ||||||
|  | @@ -486,8 +495,10 @@ adcli_tool_computer_update (adcli_conn *conn,
 | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  |  	enroll = adcli_enroll_new (conn); | ||||||
|  | -	if (enroll == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	if (enroll == NULL) {
 | ||||||
|  | +		warnx ("unexpected memory problems");
 | ||||||
|  | +		return -1;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) { | ||||||
|  |  		switch (opt) { | ||||||
|  | @@ -525,22 +536,28 @@ adcli_tool_computer_update (adcli_conn *conn,
 | ||||||
|  |   | ||||||
|  |  	res = adcli_enroll_load (enroll); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "couldn't lookup domain info from keytab: %s",
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't lookup domain info from keytab: %s",
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	res = adcli_conn_connect (conn); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't connect to %s domain: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	res = adcli_enroll_update (enroll, flags); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "updating membership with domain %s failed: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("updating membership with domain %s failed: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (details) | ||||||
|  | @@ -578,8 +595,10 @@ adcli_tool_computer_testjoin (adcli_conn *conn,
 | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  |  	enroll = adcli_enroll_new (conn); | ||||||
|  | -	if (enroll == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	if (enroll == NULL) {
 | ||||||
|  | +		warnx ("unexpected memory problems");
 | ||||||
|  | +		return -1;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) { | ||||||
|  |  		switch (opt) { | ||||||
|  | @@ -604,18 +623,18 @@ adcli_tool_computer_testjoin (adcli_conn *conn,
 | ||||||
|  |  	res = adcli_enroll_load (enroll); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  |  		adcli_enroll_unref (enroll); | ||||||
|  | -		adcli_conn_unref (conn);
 | ||||||
|  | -		errx (-res, "couldn't lookup domain info from keytab: %s",
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't lookup domain info from keytab: %s",
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	res = adcli_conn_connect (conn); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  |  		adcli_enroll_unref (enroll); | ||||||
|  | -		adcli_conn_unref (conn);
 | ||||||
|  | -		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | +		warnx ("couldn't connect to %s domain: %s",
 | ||||||
|  |  		      adcli_conn_get_domain_name (conn), | ||||||
|  |  		      adcli_get_last_error ()); | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	printf ("Sucessfully validated join to domain %s\n", | ||||||
|  | @@ -665,8 +684,10 @@ adcli_tool_computer_preset (adcli_conn *conn,
 | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  |  	enroll = adcli_enroll_new (conn); | ||||||
|  | -	if (enroll == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	if (enroll == NULL) {
 | ||||||
|  | +		warnx ("unexpected memory problems");
 | ||||||
|  | +		return -1;
 | ||||||
|  | +	}
 | ||||||
|  |  	flags = ADCLI_ENROLL_NO_KEYTAB; | ||||||
|  |   | ||||||
|  |  	while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) { | ||||||
|  | @@ -694,17 +715,22 @@ adcli_tool_computer_preset (adcli_conn *conn,
 | ||||||
|  |  	argc -= optind; | ||||||
|  |  	argv += optind; | ||||||
|  |   | ||||||
|  | -	if (argc < 1)
 | ||||||
|  | -		errx (EUSAGE, "specify one or more host names of computer accounts to preset");
 | ||||||
|  | +	if (argc < 1) {
 | ||||||
|  | +		warnx ("specify one or more host names of computer accounts to preset");
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return EUSAGE;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT); | ||||||
|  |  	reset_password = (adcli_enroll_get_computer_password (enroll) == NULL); | ||||||
|  |   | ||||||
|  |  	res = adcli_conn_connect (conn); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't connect to %s domain: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	for (i = 0; i < argc; i++) { | ||||||
|  | @@ -715,9 +741,11 @@ adcli_tool_computer_preset (adcli_conn *conn,
 | ||||||
|  |   | ||||||
|  |  		res = adcli_enroll_join (enroll, flags); | ||||||
|  |  		if (res != ADCLI_SUCCESS) { | ||||||
|  | -			errx (-res, "presetting %s in %s domain failed: %s", argv[i],
 | ||||||
|  | -			      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -			      adcli_get_last_error ());
 | ||||||
|  | +			warnx ("presetting %s in %s domain failed: %s", argv[i],
 | ||||||
|  | +			       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +			       adcli_get_last_error ());
 | ||||||
|  | +			adcli_enroll_unref (enroll);
 | ||||||
|  | +			return -res;
 | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  		printf ("computer-name: %s\n", adcli_enroll_get_computer_name (enroll)); | ||||||
|  | @@ -758,8 +786,10 @@ adcli_tool_computer_reset (adcli_conn *conn,
 | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  |  	enroll = adcli_enroll_new (conn); | ||||||
|  | -	if (enroll == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	if (enroll == NULL) {
 | ||||||
|  | +		warnx ("unexpected memory problems");
 | ||||||
|  | +		return -1;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) { | ||||||
|  |  		switch (opt) { | ||||||
|  | @@ -779,14 +809,19 @@ adcli_tool_computer_reset (adcli_conn *conn,
 | ||||||
|  |  	argc -= optind; | ||||||
|  |  	argv += optind; | ||||||
|  |   | ||||||
|  | -	if (argc != 1)
 | ||||||
|  | -		errx (EUSAGE, "specify one host name of computer account to reset");
 | ||||||
|  | +	if (argc != 1) {
 | ||||||
|  | +		warnx ("specify one host name of computer account to reset");
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return EUSAGE;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	res = adcli_conn_connect (conn); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't connect to %s domain: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	parse_fqdn_or_name (enroll, argv[0]); | ||||||
|  | @@ -794,9 +829,11 @@ adcli_tool_computer_reset (adcli_conn *conn,
 | ||||||
|  |   | ||||||
|  |  	res = adcli_enroll_password (enroll, 0); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "resetting %s in %s domain failed: %s", argv[0],
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("resetting %s in %s domain failed: %s", argv[0],
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	adcli_enroll_unref (enroll); | ||||||
|  | @@ -832,8 +869,10 @@ adcli_tool_computer_delete (adcli_conn *conn,
 | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  |  	enroll = adcli_enroll_new (conn); | ||||||
|  | -	if (enroll == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	if (enroll == NULL) {
 | ||||||
|  | +		warnx ("unexpected memory problems");
 | ||||||
|  | +		return -1;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) { | ||||||
|  |  		switch (opt) { | ||||||
|  | @@ -853,22 +892,29 @@ adcli_tool_computer_delete (adcli_conn *conn,
 | ||||||
|  |  	argc -= optind; | ||||||
|  |  	argv += optind; | ||||||
|  |   | ||||||
|  | -	if (argc > 1)
 | ||||||
|  | -		errx (EUSAGE, "specify one host name of computer account to delete");
 | ||||||
|  | +	if (argc > 1) {
 | ||||||
|  | +		warnx ("specify one host name of computer account to delete");
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return EUSAGE;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT); | ||||||
|  |   | ||||||
|  |  	res = adcli_enroll_load (enroll); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "couldn't lookup domain info from keytab: %s",
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't lookup domain info from keytab: %s",
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	res = adcli_conn_connect (conn); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't connect to %s domain: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (argc == 1) | ||||||
|  | @@ -876,9 +922,11 @@ adcli_tool_computer_delete (adcli_conn *conn,
 | ||||||
|  |   | ||||||
|  |  	res = adcli_enroll_delete (enroll, 0); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "deleting %s in %s domain failed: %s", argv[0],
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("deleting %s in %s domain failed: %s", argv[0],
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	adcli_enroll_unref (enroll); | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										191
									
								
								0002-Add-delattr-option.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								0002-Add-delattr-option.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,191 @@ | |||||||
|  | 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 2/2] 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,5 +151,6 @@ struct _adcli_enroll {
 | ||||||
|  |  	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, | ||||||
|  |  } 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 | ||||||
|  | 
 | ||||||
							
								
								
									
										241
									
								
								0002-Add-dont-expire-password-option.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								0002-Add-dont-expire-password-option.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,241 @@ | |||||||
|  | From 74b52a30c2b142118b7f26f78c014e7bee825e84 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 | 58 +++++++++++++++++++++++++++++++++++++++++----- | ||||||
|  |  library/adenroll.h |  4 ++++ | ||||||
|  |  tools/computer.c   | 12 ++++++++++ | ||||||
|  |  4 files changed, 96 insertions(+), 6 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index a64687a..7c2e126 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>--add-service-principal=<parameter>service/hostname</parameter></option></term> | ||||||
|  |  			<listitem><para>Add a service principal name. In | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index c726093..01f149c 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -152,6 +152,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;
 | ||||||
|  |  	char *description; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | @@ -829,6 +831,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, | ||||||
|  | @@ -849,11 +853,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; | ||||||
|  | @@ -868,6 +882,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); | ||||||
|  |   | ||||||
|  |  	/* | ||||||
|  | @@ -1566,10 +1581,20 @@ static char *get_user_account_control (adcli_enroll *enroll)
 | ||||||
|  |  		uac = UAC_WORKSTATION_TRUST_ACCOUNT | UAC_DONT_EXPIRE_PASSWORD; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if (adcli_enroll_get_trusted_for_delegation (enroll)) {
 | ||||||
|  | -		uac |= UAC_TRUSTED_FOR_DELEGATION;
 | ||||||
|  | -	} else {
 | ||||||
|  | -		uac &= ~(UAC_TRUSTED_FOR_DELEGATION);
 | ||||||
|  | +	if (enroll->trusted_for_delegation_explicit) {
 | ||||||
|  | +		if (adcli_enroll_get_trusted_for_delegation (enroll)) {
 | ||||||
|  | +			uac |= UAC_TRUSTED_FOR_DELEGATION;
 | ||||||
|  | +		} else {
 | ||||||
|  | +			uac &= ~(UAC_TRUSTED_FOR_DELEGATION);
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	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 (asprintf (&uac_str, "%d", uac) < 0) { | ||||||
|  | @@ -1613,7 +1640,8 @@ update_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  	} | ||||||
|  |  	free (value); | ||||||
|  |   | ||||||
|  | -	if (res == ADCLI_SUCCESS && enroll->trusted_for_delegation_explicit) {
 | ||||||
|  | +	if (res == ADCLI_SUCCESS && (enroll->trusted_for_delegation_explicit ||
 | ||||||
|  | +	                             enroll->dont_expire_password_explicit)) {
 | ||||||
|  |  		char *vals_userAccountControl[] = { NULL , NULL }; | ||||||
|  |  		LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } }; | ||||||
|  |  		LDAPMod *mods[] = { &userAccountControl, NULL }; | ||||||
|  | @@ -3194,6 +3222,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;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  void | ||||||
|  |  adcli_enroll_set_description (adcli_enroll *enroll, const char *value) | ||||||
|  |  { | ||||||
|  | diff --git a/library/adenroll.h b/library/adenroll.h
 | ||||||
|  | index 11a30c8..5190eb6 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);
 | ||||||
|  | +
 | ||||||
|  |  const char *       adcli_enroll_get_desciption          (adcli_enroll *enroll); | ||||||
|  |  void               adcli_enroll_set_description         (adcli_enroll *enroll, | ||||||
|  |                                                           const char *value); | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index 98a0472..954066a 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, | ||||||
|  | @@ -143,6 +144,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_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" }, | ||||||
|  | @@ -304,6 +307,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_add_service_principal: | ||||||
|  |  		adcli_enroll_add_service_principal_to_add (enroll, optarg); | ||||||
|  |  		return ADCLI_SUCCESS; | ||||||
|  | @@ -383,6 +393,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 }, | ||||||
|  | @@ -504,6 +515,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 },
 | ||||||
|  |  		{ "add-service-principal", required_argument, NULL, opt_add_service_principal }, | ||||||
|  |  		{ "remove-service-principal", required_argument, NULL, opt_remove_service_principal }, | ||||||
|  |  		{ "show-details", no_argument, NULL, opt_show_details }, | ||||||
|  | -- 
 | ||||||
|  | 2.31.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										31
									
								
								0002-Use-strdup-if-offset-are-used.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								0002-Use-strdup-if-offset-are-used.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | From 4ba49015ca1ad98c03a209a11862f8e00d00fbd0 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 24 Aug 2016 16:19:36 +0200 | ||||||
|  | Subject: [PATCH 02/23] Use strdup() if offset are used | ||||||
|  | 
 | ||||||
|  | Strings with an offset to the original starting point must be copied | ||||||
|  | because otherwise they cannot be properly freed later. | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 6 +++--- | ||||||
|  |  1 file changed, 3 insertions(+), 3 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index d1020e9..05885d0 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -1318,9 +1318,9 @@ load_keytab_entry (krb5_context k5,
 | ||||||
|  |   | ||||||
|  |  		} else if (!enroll->host_fqdn && _adcli_str_has_prefix (name, "host/") && strchr (name, '.')) { | ||||||
|  |  			/* Skip host/ prefix */ | ||||||
|  | -			enroll->host_fqdn = name + 5;
 | ||||||
|  | -			_adcli_info ("Found host qualified name in keytab: %s", name);
 | ||||||
|  | -			name = NULL;
 | ||||||
|  | +			enroll->host_fqdn = strdup (name + 5);
 | ||||||
|  | +			return_val_if_fail (enroll->host_fqdn != NULL, FALSE);
 | ||||||
|  | +			_adcli_info ("Found host qualified name in keytab: %s", enroll->host_fqdn);
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,25 @@ | |||||||
|  | From 8cc4ef1cae7d4d753f2cf9aeb8021dd96cb75d36 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 8 Aug 2018 12:17:18 +0200 | ||||||
|  | Subject: [PATCH 2/4] _adcli_call_external_program: silence noisy debug message | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  library/adutil.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adutil.c b/library/adutil.c
 | ||||||
|  | index 6334b52..17d2caa 100644
 | ||||||
|  | --- a/library/adutil.c
 | ||||||
|  | +++ b/library/adutil.c
 | ||||||
|  | @@ -672,7 +672,7 @@ done:
 | ||||||
|  |  		if (wret == -1) { | ||||||
|  |  			_adcli_err ("No sure what happend to net command."); | ||||||
|  |  		} else { | ||||||
|  | -			if (WIFEXITED (status)) {
 | ||||||
|  | +			if (WIFEXITED (status) && WEXITSTATUS (status) != 0) {
 | ||||||
|  |  				_adcli_err ("net command failed with %d.", | ||||||
|  |  				            WEXITSTATUS (status)); | ||||||
|  |  			} | ||||||
|  | -- 
 | ||||||
|  | 2.17.1 | ||||||
|  | 
 | ||||||
| @ -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/3] 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 | ||||||
|  | 
 | ||||||
							
								
								
									
										52
									
								
								0002-adconn-add-adcli_conn_set_krb5_context.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								0002-adconn-add-adcli_conn_set_krb5_context.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | From 2fc259a88be618871cea8ff8b8a13bd3e040aea4 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 13 Jun 2019 17:23:47 +0200 | ||||||
|  | Subject: [PATCH 2/4] adconn: add adcli_conn_set_krb5_context | ||||||
|  | 
 | ||||||
|  | Related to https://gitlab.freedesktop.org/realmd/adcli/issues/3 | ||||||
|  | ---
 | ||||||
|  |  library/adconn.c | 13 +++++++++++++ | ||||||
|  |  library/adconn.h |  3 +++ | ||||||
|  |  2 files changed, 16 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adconn.c b/library/adconn.c
 | ||||||
|  | index f6c23d3..bcaced8 100644
 | ||||||
|  | --- a/library/adconn.c
 | ||||||
|  | +++ b/library/adconn.c
 | ||||||
|  | @@ -1406,6 +1406,19 @@ adcli_conn_get_krb5_context (adcli_conn *conn)
 | ||||||
|  |  	return conn->k5; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void
 | ||||||
|  | +adcli_conn_set_krb5_context (adcli_conn *conn,
 | ||||||
|  | +                             krb5_context k5)
 | ||||||
|  | +{
 | ||||||
|  | +	return_if_fail (conn != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	if (conn->k5 != NULL) {
 | ||||||
|  | +		krb5_free_context (conn->k5);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	conn->k5 = k5;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  const char * | ||||||
|  |  adcli_conn_get_login_user (adcli_conn *conn) | ||||||
|  |  { | ||||||
|  | diff --git a/library/adconn.h b/library/adconn.h
 | ||||||
|  | index 13cfd32..1ad5715 100644
 | ||||||
|  | --- a/library/adconn.h
 | ||||||
|  | +++ b/library/adconn.h
 | ||||||
|  | @@ -97,6 +97,9 @@ LDAP *              adcli_conn_get_ldap_connection   (adcli_conn *conn);
 | ||||||
|  |   | ||||||
|  |  krb5_context        adcli_conn_get_krb5_context      (adcli_conn *conn); | ||||||
|  |   | ||||||
|  | +void                adcli_conn_set_krb5_context      (adcli_conn *conn,
 | ||||||
|  | +                                                      krb5_context k5);
 | ||||||
|  | +
 | ||||||
|  |  const char *        adcli_conn_get_computer_name     (adcli_conn *conn); | ||||||
|  |   | ||||||
|  |  void                adcli_conn_set_computer_name     (adcli_conn *conn, | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										183
									
								
								0002-add-description-option-to-join-and-update.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								0002-add-description-option-to-join-and-update.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,183 @@ | |||||||
|  | From 3937a2a7db90611aa7a93248233b0c5d31e85a3e Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 27 Nov 2019 14:48:32 +0100 | ||||||
|  | Subject: [PATCH 2/2] add description option to join and update | ||||||
|  | 
 | ||||||
|  | This new option allows to set the description LDAP attribute for the AD | ||||||
|  | computer object. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1737342 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml      | 10 ++++++++++ | ||||||
|  |  library/adenroll.c | 29 +++++++++++++++++++++++++++++ | ||||||
|  |  library/adenroll.h |  4 ++++ | ||||||
|  |  tools/computer.c   |  7 +++++++ | ||||||
|  |  4 files changed, 50 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index 1f93186..dd30435 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -275,6 +275,11 @@ Password for Administrator:
 | ||||||
|  |  			<listitem><para>Set the operating system version on the computer | ||||||
|  |  			account. Not set by default.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--description=<parameter>description</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Set the description attribute on the computer
 | ||||||
|  | +			account. Not set by default.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>--service-name=<parameter>service</parameter></option></term> | ||||||
|  |  			<listitem><para>Additional service name for a kerberos | ||||||
|  | @@ -416,6 +421,11 @@ $ adcli update --login-ccache=/tmp/krbcc_123
 | ||||||
|  |  			<listitem><para>Set the operating system version on the computer | ||||||
|  |  			account. Not set by default.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--description=<parameter>description</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Set the description attribute on the computer
 | ||||||
|  | +			account. Not set by default.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>--service-name=<parameter>service</parameter></option></term> | ||||||
|  |  			<listitem><para>Additional service name for a Kerberos | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 8d2adeb..246f658 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -83,6 +83,7 @@ static char *default_ad_ldap_attrs[] =  {
 | ||||||
|  |  	"operatingSystemServicePack", | ||||||
|  |  	"pwdLastSet", | ||||||
|  |  	"userAccountControl", | ||||||
|  | +	"description",
 | ||||||
|  |  	NULL, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | @@ -143,6 +144,7 @@ struct _adcli_enroll {
 | ||||||
|  |  	char *samba_data_tool; | ||||||
|  |  	bool trusted_for_delegation; | ||||||
|  |  	int trusted_for_delegation_explicit; | ||||||
|  | +	char *description;
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static adcli_result | ||||||
|  | @@ -756,6 +758,8 @@ create_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	char *vals_userPrincipalName[] = { enroll->user_principal, NULL }; | ||||||
|  |  	LDAPMod userPrincipalName = { LDAP_MOD_ADD, "userPrincipalName", { vals_userPrincipalName, }, }; | ||||||
|  |  	LDAPMod servicePrincipalName = { LDAP_MOD_ADD, "servicePrincipalName", { enroll->service_principals, } }; | ||||||
|  | +	char *vals_description[] = { enroll->description, NULL };
 | ||||||
|  | +	LDAPMod description = { LDAP_MOD_ADD, "description", { vals_description, }, };
 | ||||||
|  |   | ||||||
|  |  	char *val = NULL; | ||||||
|  |   | ||||||
|  | @@ -774,6 +778,7 @@ create_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  		&operatingSystemServicePack, | ||||||
|  |  		&userPrincipalName, | ||||||
|  |  		&servicePrincipalName, | ||||||
|  | +		&description,
 | ||||||
|  |  		NULL | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  | @@ -1460,6 +1465,14 @@ update_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  		res |= update_computer_attribute (enroll, ldap, mods); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	if (res == ADCLI_SUCCESS && enroll->description != NULL) {
 | ||||||
|  | +		char *vals_description[] = { enroll->description, NULL };
 | ||||||
|  | +		LDAPMod description = { LDAP_MOD_REPLACE, "description", { vals_description, }, };
 | ||||||
|  | +		LDAPMod *mods[] = { &description, NULL, };
 | ||||||
|  | +
 | ||||||
|  | +		res |= update_computer_attribute (enroll, ldap, mods);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	if (res != 0) | ||||||
|  |  		_adcli_info ("Updated existing computer account: %s", enroll->computer_dn); | ||||||
|  |  } | ||||||
|  | @@ -2899,6 +2912,22 @@ adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
 | ||||||
|  |  	enroll->trusted_for_delegation_explicit = 1; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void
 | ||||||
|  | +adcli_enroll_set_description (adcli_enroll *enroll, const char *value)
 | ||||||
|  | +{
 | ||||||
|  | +	return_if_fail (enroll != NULL);
 | ||||||
|  | +	if (value != NULL && value[0] != '\0') {
 | ||||||
|  | +		_adcli_str_set (&enroll->description, value);
 | ||||||
|  | +	}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +const char *
 | ||||||
|  | +adcli_enroll_get_desciption (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	return_val_if_fail (enroll != NULL, NULL);
 | ||||||
|  | +	return enroll->description;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  const char ** | ||||||
|  |  adcli_enroll_get_service_principals_to_add (adcli_enroll *enroll) | ||||||
|  |  { | ||||||
|  | diff --git a/library/adenroll.h b/library/adenroll.h
 | ||||||
|  | index 11eb517..0606169 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); | ||||||
|  |   | ||||||
|  | +const char *       adcli_enroll_get_desciption          (adcli_enroll *enroll);
 | ||||||
|  | +void               adcli_enroll_set_description         (adcli_enroll *enroll,
 | ||||||
|  | +                                                         const char *value);
 | ||||||
|  | +
 | ||||||
|  |  krb5_kvno          adcli_enroll_get_kvno                (adcli_enroll *enroll); | ||||||
|  |   | ||||||
|  |  void               adcli_enroll_set_kvno                (adcli_enroll *enroll, | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index c8b96a4..840e334 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -112,6 +112,7 @@ typedef enum {
 | ||||||
|  |  	opt_trusted_for_delegation, | ||||||
|  |  	opt_add_service_principal, | ||||||
|  |  	opt_remove_service_principal, | ||||||
|  | +	opt_description,
 | ||||||
|  |  } Option; | ||||||
|  |   | ||||||
|  |  static adcli_tool_desc common_usages[] = { | ||||||
|  | @@ -142,6 +143,7 @@ static adcli_tool_desc common_usages[] = {
 | ||||||
|  |  	                              "in the userAccountControl attribute", }, | ||||||
|  |  	{ 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_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" | ||||||
|  | @@ -306,6 +308,9 @@ parse_option (Option opt,
 | ||||||
|  |  	case opt_remove_service_principal: | ||||||
|  |  		adcli_enroll_add_service_principal_to_remove (enroll, optarg); | ||||||
|  |  		return ADCLI_SUCCESS; | ||||||
|  | +	case opt_description:
 | ||||||
|  | +		adcli_enroll_set_description (enroll, optarg);
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_verbose: | ||||||
|  |  		return ADCLI_SUCCESS; | ||||||
|  |   | ||||||
|  | @@ -369,6 +374,7 @@ adcli_tool_computer_join (adcli_conn *conn,
 | ||||||
|  |  		{ "os-name", required_argument, NULL, opt_os_name }, | ||||||
|  |  		{ "os-version", required_argument, NULL, opt_os_version }, | ||||||
|  |  		{ "os-service-pack", optional_argument, NULL, opt_os_service_pack }, | ||||||
|  | +		{ "description", optional_argument, NULL, opt_description },
 | ||||||
|  |  		{ "user-principal", optional_argument, NULL, opt_user_principal }, | ||||||
|  |  		{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation }, | ||||||
|  |  		{ "add-service-principal", required_argument, NULL, opt_add_service_principal }, | ||||||
|  | @@ -487,6 +493,7 @@ adcli_tool_computer_update (adcli_conn *conn,
 | ||||||
|  |  		{ "os-name", required_argument, NULL, opt_os_name }, | ||||||
|  |  		{ "os-version", required_argument, NULL, opt_os_version }, | ||||||
|  |  		{ "os-service-pack", optional_argument, NULL, opt_os_service_pack }, | ||||||
|  | +		{ "description", optional_argument, NULL, opt_description },
 | ||||||
|  |  		{ "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.21.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										378
									
								
								0002-add-option-use-ldaps.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										378
									
								
								0002-add-option-use-ldaps.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,378 @@ | |||||||
|  | From 85097245b57f190337225dbdbf6e33b58616c092 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 19 Dec 2019 07:22:33 +0100 | ||||||
|  | Subject: [PATCH 2/2] add option use-ldaps | ||||||
|  | 
 | ||||||
|  | In general using the LDAP port with GSS-SPNEGO should satifiy all | ||||||
|  | requirements an AD DC should have for authentication on an encrypted | ||||||
|  | LDAP connection. | ||||||
|  | 
 | ||||||
|  | But if e.g. the LDAP port is blocked by a firewall using the LDAPS port | ||||||
|  | with TLS encryption might be an alternative. For this use case the | ||||||
|  | --use-ldaps option is added.
 | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1762420 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml    | 24 +++++++++++++++ | ||||||
|  |  library/adconn.c | 79 ++++++++++++++++++++++++++++++++++++++++++------ | ||||||
|  |  library/adconn.h |  4 +++ | ||||||
|  |  tools/computer.c | 10 ++++++ | ||||||
|  |  tools/entry.c    | 11 +++++++ | ||||||
|  |  5 files changed, 119 insertions(+), 9 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index dd30435..acced25 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -128,6 +128,30 @@
 | ||||||
|  |  			If not specified, then an appropriate domain controller | ||||||
|  |  			is automatically discovered.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--use-ldaps</option></term>
 | ||||||
|  | +			<listitem><para>Connect to the domain controller
 | ||||||
|  | +			with LDAPS. By default the LDAP port is used and SASL
 | ||||||
|  | +			GSS-SPNEGO or GSSAPI is used for authentication and to
 | ||||||
|  | +			establish encryption. This should satisfy all
 | ||||||
|  | +			requirements set on the server side and LDAPS should
 | ||||||
|  | +			only be used if the LDAP port is not accessible due to
 | ||||||
|  | +			firewalls or other reasons.</para>
 | ||||||
|  | +			<para> Please note that the place where CA certificates
 | ||||||
|  | +			can be found to validate the AD DC certificates
 | ||||||
|  | +			must be configured in the OpenLDAP configuration
 | ||||||
|  | +			file, e.g. <filename>/etc/openldap/ldap.conf</filename>.
 | ||||||
|  | +			As an alternative it can be specified with the help of
 | ||||||
|  | +			an environment variable, e.g.
 | ||||||
|  | +<programlisting>
 | ||||||
|  | +$ LDAPTLS_CACERT=/path/to/ad_dc_ca_cert.pem adcli join --use-ldaps -D domain.example.com
 | ||||||
|  | +...
 | ||||||
|  | +</programlisting>
 | ||||||
|  | +			Please see
 | ||||||
|  | +			<citerefentry><refentrytitle>ldap.conf</refentrytitle>
 | ||||||
|  | +			<manvolnum>5</manvolnum></citerefentry> for details.
 | ||||||
|  | +			</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-C, --login-ccache=<parameter>ccache_name</parameter></option></term> | ||||||
|  |  			<listitem><para>Use the specified kerberos credential | ||||||
|  | diff --git a/library/adconn.c b/library/adconn.c
 | ||||||
|  | index ffb54f9..7bab852 100644
 | ||||||
|  | --- a/library/adconn.c
 | ||||||
|  | +++ b/library/adconn.c
 | ||||||
|  | @@ -70,6 +70,7 @@ struct _adcli_conn_ctx {
 | ||||||
|  |  	char *domain_name; | ||||||
|  |  	char *domain_realm; | ||||||
|  |  	char *domain_controller; | ||||||
|  | +	bool use_ldaps;
 | ||||||
|  |  	char *canonical_host; | ||||||
|  |  	char *domain_short; | ||||||
|  |  	char *domain_sid; | ||||||
|  | @@ -773,7 +774,8 @@ int ldap_init_fd (ber_socket_t fd, int proto, LDAP_CONST char *url, struct ldap
 | ||||||
|  |   | ||||||
|  |  static LDAP * | ||||||
|  |  connect_to_address (const char *host, | ||||||
|  | -                    const char *canonical_host)
 | ||||||
|  | +                    const char *canonical_host,
 | ||||||
|  | +                    bool use_ldaps)
 | ||||||
|  |  { | ||||||
|  |  	struct addrinfo *res = NULL; | ||||||
|  |  	struct addrinfo *ai; | ||||||
|  | @@ -783,6 +785,16 @@ connect_to_address (const char *host,
 | ||||||
|  |  	char *url; | ||||||
|  |  	int sock; | ||||||
|  |  	int rc; | ||||||
|  | +	int opt_rc;
 | ||||||
|  | +	const char *port = "389";
 | ||||||
|  | +	const char *proto = "ldap";
 | ||||||
|  | +	const char *errmsg = NULL;
 | ||||||
|  | +
 | ||||||
|  | +	if (use_ldaps) {
 | ||||||
|  | +		port = "636";
 | ||||||
|  | +		proto = "ldaps";
 | ||||||
|  | +		_adcli_info ("Using LDAPS to connect to %s", host);
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	memset (&hints, '\0', sizeof(hints)); | ||||||
|  |  #ifdef AI_ADDRCONFIG | ||||||
|  | @@ -794,7 +806,7 @@ connect_to_address (const char *host,
 | ||||||
|  |  	if (!canonical_host) | ||||||
|  |  		canonical_host = host; | ||||||
|  |   | ||||||
|  | -	rc = getaddrinfo (host, "389", &hints, &res);
 | ||||||
|  | +	rc = getaddrinfo (host, port, &hints, &res);
 | ||||||
|  |  	if (rc != 0) { | ||||||
|  |  		_adcli_err ("Couldn't resolve host name: %s: %s", host, gai_strerror (rc)); | ||||||
|  |  		return NULL; | ||||||
|  | @@ -810,7 +822,7 @@ connect_to_address (const char *host,
 | ||||||
|  |  			close (sock); | ||||||
|  |  		} else { | ||||||
|  |  			error = 0; | ||||||
|  | -			if (asprintf (&url, "ldap://%s", canonical_host) < 0)
 | ||||||
|  | +			if (asprintf (&url, "%s://%s", proto, canonical_host) < 0)
 | ||||||
|  |  				return_val_if_reached (NULL); | ||||||
|  |  			rc = ldap_init_fd (sock, 1, url, &ldap); | ||||||
|  |  			free (url); | ||||||
|  | @@ -820,6 +832,25 @@ connect_to_address (const char *host,
 | ||||||
|  |  				            ldap_err2string (rc)); | ||||||
|  |  				break; | ||||||
|  |  			} | ||||||
|  | +
 | ||||||
|  | +			if (use_ldaps) {
 | ||||||
|  | +				rc = ldap_install_tls (ldap);
 | ||||||
|  | +				if (rc != LDAP_SUCCESS) {
 | ||||||
|  | +					opt_rc = ldap_get_option (ldap,
 | ||||||
|  | +					                          LDAP_OPT_DIAGNOSTIC_MESSAGE,
 | ||||||
|  | +					                          (void *) &errmsg);
 | ||||||
|  | +					if (opt_rc != LDAP_SUCCESS) {
 | ||||||
|  | +						errmsg = NULL;
 | ||||||
|  | +					}
 | ||||||
|  | +					_adcli_err ("Couldn't initialize TLS [%s]: %s",
 | ||||||
|  | +					            ldap_err2string (rc),
 | ||||||
|  | +					            errmsg == NULL ? "- no details -"
 | ||||||
|  | +					                           : errmsg);
 | ||||||
|  | +					ldap_unbind_ext_s (ldap, NULL, NULL);
 | ||||||
|  | +					ldap = NULL;
 | ||||||
|  | +					break;
 | ||||||
|  | +				}
 | ||||||
|  | +			}
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -856,7 +887,8 @@ connect_and_lookup_naming (adcli_conn *conn,
 | ||||||
|  |  	if (!canonical_host) | ||||||
|  |  		canonical_host = disco->host_addr; | ||||||
|  |   | ||||||
|  | -	ldap = connect_to_address (disco->host_addr, canonical_host);
 | ||||||
|  | +	ldap = connect_to_address (disco->host_addr, canonical_host,
 | ||||||
|  | +	                           adcli_conn_get_use_ldaps (conn));
 | ||||||
|  |  	if (ldap == NULL) | ||||||
|  |  		return ADCLI_ERR_DIRECTORY; | ||||||
|  |   | ||||||
|  | @@ -1041,14 +1073,28 @@ authenticate_to_directory (adcli_conn *conn)
 | ||||||
|  |  	status = gss_krb5_ccache_name (&minor, conn->login_ccache_name, NULL); | ||||||
|  |  	return_unexpected_if_fail (status == 0); | ||||||
|  |   | ||||||
|  | -	/* Clumsily tell ldap + cyrus-sasl that we want encryption */
 | ||||||
|  | -	ssf = 1;
 | ||||||
|  | -	ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MIN, &ssf);
 | ||||||
|  | -	return_unexpected_if_fail (ret == 0);
 | ||||||
|  | +	if (adcli_conn_get_use_ldaps (conn)) {
 | ||||||
|  | +		/* do not use SASL encryption on LDAPS connection */
 | ||||||
|  | +		ssf = 0;
 | ||||||
|  | +		ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MIN, &ssf);
 | ||||||
|  | +		return_unexpected_if_fail (ret == 0);
 | ||||||
|  | +		ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MAX, &ssf);
 | ||||||
|  | +		return_unexpected_if_fail (ret == 0);
 | ||||||
|  | +	} else {
 | ||||||
|  | +		/* Clumsily tell ldap + cyrus-sasl that we want encryption */
 | ||||||
|  | +		ssf = 1;
 | ||||||
|  | +		ret = ldap_set_option (conn->ldap, LDAP_OPT_X_SASL_SSF_MIN, &ssf);
 | ||||||
|  | +		return_unexpected_if_fail (ret == 0);
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  | -	if (adcli_conn_server_has_sasl_mech (conn, "GSS-SPNEGO")) {
 | ||||||
|  | +	/* There are issues with cryrus-sasl and GSS-SPNEGO with TLS even if
 | ||||||
|  | +	 * ssf_max is set to 0. To be on the safe side GSS-SPNEGO is only used
 | ||||||
|  | +	 * without LDAPS. */
 | ||||||
|  | +	if (adcli_conn_server_has_sasl_mech (conn, "GSS-SPNEGO")
 | ||||||
|  | +	                     && !adcli_conn_get_use_ldaps (conn)) {
 | ||||||
|  |  		mech =  "GSS-SPNEGO"; | ||||||
|  |  	} | ||||||
|  | +	_adcli_info ("Using %s for SASL bind", mech);
 | ||||||
|  |   | ||||||
|  |  	ret = ldap_sasl_interactive_bind_s (conn->ldap, NULL, mech, NULL, NULL, | ||||||
|  |  	                                    LDAP_SASL_QUIET, sasl_interact, NULL); | ||||||
|  | @@ -1230,6 +1276,7 @@ adcli_conn_new (const char *domain_name)
 | ||||||
|  |  	conn->refs = 1; | ||||||
|  |  	conn->logins_allowed = ADCLI_LOGIN_COMPUTER_ACCOUNT | ADCLI_LOGIN_USER_ACCOUNT; | ||||||
|  |  	adcli_conn_set_domain_name (conn, domain_name); | ||||||
|  | +	adcli_conn_set_use_ldaps (conn, false);
 | ||||||
|  |  	return conn; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -1389,6 +1436,20 @@ adcli_conn_set_domain_controller (adcli_conn *conn,
 | ||||||
|  |  	no_more_disco (conn); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +bool
 | ||||||
|  | +adcli_conn_get_use_ldaps (adcli_conn *conn)
 | ||||||
|  | +{
 | ||||||
|  | +	return_val_if_fail (conn != NULL, NULL);
 | ||||||
|  | +	return conn->use_ldaps;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +adcli_conn_set_use_ldaps (adcli_conn *conn, bool value)
 | ||||||
|  | +{
 | ||||||
|  | +	return_if_fail (conn != NULL);
 | ||||||
|  | +	conn->use_ldaps = value;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  const char * | ||||||
|  |  adcli_conn_get_domain_short (adcli_conn *conn) | ||||||
|  |  { | ||||||
|  | diff --git a/library/adconn.h b/library/adconn.h
 | ||||||
|  | index 37ebdd9..1d5faa8 100644
 | ||||||
|  | --- a/library/adconn.h
 | ||||||
|  | +++ b/library/adconn.h
 | ||||||
|  | @@ -89,6 +89,10 @@ const char *        adcli_conn_get_domain_controller (adcli_conn *conn);
 | ||||||
|  |  void                adcli_conn_set_domain_controller (adcli_conn *conn, | ||||||
|  |                                                        const char *value); | ||||||
|  |   | ||||||
|  | +bool                adcli_conn_get_use_ldaps         (adcli_conn *conn);
 | ||||||
|  | +void                adcli_conn_set_use_ldaps         (adcli_conn *conn,
 | ||||||
|  | +                                                      bool value);
 | ||||||
|  | +
 | ||||||
|  |  const char *        adcli_conn_get_domain_short      (adcli_conn *conn); | ||||||
|  |   | ||||||
|  |  const char *        adcli_conn_get_domain_sid        (adcli_conn *conn); | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index 840e334..292c4d8 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -113,12 +113,14 @@ typedef enum {
 | ||||||
|  |  	opt_add_service_principal, | ||||||
|  |  	opt_remove_service_principal, | ||||||
|  |  	opt_description, | ||||||
|  | +	opt_use_ldaps,
 | ||||||
|  |  } Option; | ||||||
|  |   | ||||||
|  |  static adcli_tool_desc common_usages[] = { | ||||||
|  |  	{ opt_domain, "active directory domain name" }, | ||||||
|  |  	{ opt_domain_realm, "kerberos realm for the domain" }, | ||||||
|  |  	{ opt_domain_controller, "domain controller to connect to" }, | ||||||
|  | +	{ opt_use_ldaps, "use LDAPS port for communication" },
 | ||||||
|  |  	{ opt_host_fqdn, "override the fully qualified domain name of the\n" | ||||||
|  |  	                 "local machine" }, | ||||||
|  |  	{ opt_host_keytab, "filename for the host kerberos keytab" }, | ||||||
|  | @@ -311,6 +313,9 @@ parse_option (Option opt,
 | ||||||
|  |  	case opt_description: | ||||||
|  |  		adcli_enroll_set_description (enroll, optarg); | ||||||
|  |  		return ADCLI_SUCCESS; | ||||||
|  | +	case opt_use_ldaps:
 | ||||||
|  | +		adcli_conn_set_use_ldaps (conn, true);
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_verbose: | ||||||
|  |  		return ADCLI_SUCCESS; | ||||||
|  |   | ||||||
|  | @@ -357,6 +362,7 @@ adcli_tool_computer_join (adcli_conn *conn,
 | ||||||
|  |  		{ "domain-realm", required_argument, NULL, opt_domain_realm }, | ||||||
|  |  		{ "domain-controller", required_argument, NULL, opt_domain_controller }, | ||||||
|  |  		{ "domain-server", required_argument, NULL, opt_domain_controller }, /* compat */ | ||||||
|  | +		{ "use-ldaps", no_argument, 0, opt_use_ldaps },
 | ||||||
|  |  		{ "login-user", required_argument, NULL, opt_login_user }, | ||||||
|  |  		{ "user", required_argument, NULL, opt_login_user }, /* compat */ | ||||||
|  |  		{ "login-ccache", optional_argument, NULL, opt_login_ccache }, | ||||||
|  | @@ -688,6 +694,7 @@ adcli_tool_computer_preset (adcli_conn *conn,
 | ||||||
|  |  		{ "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 },
 | ||||||
|  |  		{ "domain-ou", required_argument, NULL, opt_domain_ou }, | ||||||
|  |  		{ "login-user", required_argument, NULL, opt_login_user }, | ||||||
|  |  		{ "login-ccache", optional_argument, NULL, opt_login_ccache }, | ||||||
|  | @@ -800,6 +807,7 @@ adcli_tool_computer_reset (adcli_conn *conn,
 | ||||||
|  |  		{ "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 }, | ||||||
|  |  		{ "login-type", required_argument, NULL, opt_login_type }, | ||||||
|  | @@ -888,6 +896,7 @@ adcli_tool_computer_delete (adcli_conn *conn,
 | ||||||
|  |  		{ "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 }, | ||||||
|  | @@ -985,6 +994,7 @@ adcli_tool_computer_show (adcli_conn *conn,
 | ||||||
|  |  		{ "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 }, | ||||||
|  |  		{ "login-type", required_argument, NULL, opt_login_type }, | ||||||
|  | diff --git a/tools/entry.c b/tools/entry.c
 | ||||||
|  | index f361845..05e4313 100644
 | ||||||
|  | --- a/tools/entry.c
 | ||||||
|  | +++ b/tools/entry.c
 | ||||||
|  | @@ -53,6 +53,7 @@ typedef enum {
 | ||||||
|  |  	opt_unix_gid, | ||||||
|  |  	opt_unix_shell, | ||||||
|  |  	opt_nis_domain, | ||||||
|  | +	opt_use_ldaps,
 | ||||||
|  |  } Option; | ||||||
|  |   | ||||||
|  |  static adcli_tool_desc common_usages[] = { | ||||||
|  | @@ -67,6 +68,7 @@ static adcli_tool_desc common_usages[] = {
 | ||||||
|  |  	{ opt_domain, "active directory domain name" }, | ||||||
|  |  	{ opt_domain_realm, "kerberos realm for the domain" }, | ||||||
|  |  	{ opt_domain_controller, "domain directory server to connect to" }, | ||||||
|  | +	{ opt_use_ldaps, "use LDAPS port for communication" },
 | ||||||
|  |  	{ opt_login_ccache, "kerberos credential cache file which contains\n" | ||||||
|  |  	                    "ticket to used to connect to the domain" }, | ||||||
|  |  	{ opt_login_user, "user (usually administrative) login name of\n" | ||||||
|  | @@ -136,6 +138,9 @@ parse_option (Option opt,
 | ||||||
|  |  			stdin_password = 1; | ||||||
|  |  		} | ||||||
|  |  		return ADCLI_SUCCESS; | ||||||
|  | +	case opt_use_ldaps:
 | ||||||
|  | +		adcli_conn_set_use_ldaps (conn, true);
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_verbose: | ||||||
|  |  		return ADCLI_SUCCESS; | ||||||
|  |  	default: | ||||||
|  | @@ -172,6 +177,7 @@ adcli_tool_user_create (adcli_conn *conn,
 | ||||||
|  |  		{ "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 }, | ||||||
|  | @@ -306,6 +312,7 @@ adcli_tool_user_delete (adcli_conn *conn,
 | ||||||
|  |  		{ "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 }, | ||||||
|  | @@ -394,6 +401,7 @@ adcli_tool_group_create (adcli_conn *conn,
 | ||||||
|  |  		{ "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 },
 | ||||||
|  |  		{ "domain-ou", required_argument, NULL, opt_domain_ou }, | ||||||
|  |  		{ "login-user", required_argument, NULL, opt_login_user }, | ||||||
|  |  		{ "login-ccache", optional_argument, NULL, opt_login_ccache }, | ||||||
|  | @@ -496,6 +504,7 @@ adcli_tool_group_delete (adcli_conn *conn,
 | ||||||
|  |  		{ "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 }, | ||||||
|  | @@ -622,6 +631,7 @@ adcli_tool_member_add (adcli_conn *conn,
 | ||||||
|  |  		{ "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 }, | ||||||
|  | @@ -722,6 +732,7 @@ adcli_tool_member_remove (adcli_conn *conn,
 | ||||||
|  |  		{ "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 }, | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,83 @@ | |||||||
|  | From 0c027538f398b3823bedbfbf5f388ad97784a0ec Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 16 Nov 2018 13:32:59 +0100 | ||||||
|  | Subject: [PATCH 2/2] adenroll: use _adcli_strv_add_unique for service | ||||||
|  |  principals | ||||||
|  | 
 | ||||||
|  | Check if service principals is already in the list before adding it. | ||||||
|  | 
 | ||||||
|  | Related to https://gitlab.freedesktop.org/realmd/adcli/issues/16 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 31 ++++++++----------------------- | ||||||
|  |  1 file changed, 8 insertions(+), 23 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index de2242a..e02f403 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -313,7 +313,6 @@ add_service_names_to_service_principals (adcli_enroll *enroll)
 | ||||||
|  |  	char *name; | ||||||
|  |  	int length = 0; | ||||||
|  |  	int i; | ||||||
|  | -	size_t c;
 | ||||||
|  |   | ||||||
|  |  	if (enroll->service_principals != NULL) { | ||||||
|  |  		length = seq_count (enroll->service_principals); | ||||||
|  | @@ -322,28 +321,14 @@ add_service_names_to_service_principals (adcli_enroll *enroll)
 | ||||||
|  |  	for (i = 0; enroll->service_names[i] != NULL; i++) { | ||||||
|  |  		if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->computer_name) < 0) | ||||||
|  |  			return_unexpected_if_reached (); | ||||||
|  | -		for (c = 0; enroll->service_principals != NULL && enroll->service_principals[c] != NULL; c++) {
 | ||||||
|  | -			if (strcmp (name, enroll->service_principals[c]) == 0) {
 | ||||||
|  | -				break;
 | ||||||
|  | -			}
 | ||||||
|  | -		}
 | ||||||
|  | -		if (enroll->service_principals == NULL || enroll->service_principals[c] == NULL) {
 | ||||||
|  | -			enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | -				                                      name, &length);
 | ||||||
|  | -		}
 | ||||||
|  | +		enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals,
 | ||||||
|  | +		                                                     name, &length, false);
 | ||||||
|  |   | ||||||
|  |  		if (enroll->host_fqdn) { | ||||||
|  |  			if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->host_fqdn) < 0) | ||||||
|  |  				return_unexpected_if_reached (); | ||||||
|  | -			for (c = 0; enroll->service_principals != NULL && enroll->service_principals[c] != NULL; c++) {
 | ||||||
|  | -				if (strcmp (name, enroll->service_principals[c]) == 0) {
 | ||||||
|  | -					break;
 | ||||||
|  | -				}
 | ||||||
|  | -			}
 | ||||||
|  | -			if (enroll->service_principals == NULL || enroll->service_principals[c] == NULL) {
 | ||||||
|  | -				enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | -					                                      name, &length);
 | ||||||
|  | -			}
 | ||||||
|  | +			enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals,
 | ||||||
|  | +			                                                     name, &length, false);
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -364,9 +349,9 @@ add_and_remove_service_principals (adcli_enroll *enroll)
 | ||||||
|  |  	list = adcli_enroll_get_service_principals_to_add (enroll); | ||||||
|  |  	if (list != NULL) { | ||||||
|  |  		for (c = 0; list[c] != NULL; c++) { | ||||||
|  | -			enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | -			                                              strdup (list[c]),
 | ||||||
|  | -			                                              &length);
 | ||||||
|  | +			enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals,
 | ||||||
|  | +			                                                     strdup (list[c]),
 | ||||||
|  | +			                                                     &length, false);
 | ||||||
|  |  			if (enroll->service_principals == NULL) { | ||||||
|  |  				return ADCLI_ERR_UNEXPECTED; | ||||||
|  |  			} | ||||||
|  | @@ -1525,7 +1510,7 @@ load_keytab_entry (krb5_context k5,
 | ||||||
|  |  			value = strdup (name); | ||||||
|  |  			return_val_if_fail (value != NULL, FALSE); | ||||||
|  |  			_adcli_info ("Found service principal in keytab: %s", value); | ||||||
|  | -			enroll->service_principals = _adcli_strv_add (enroll->service_principals, value, NULL);
 | ||||||
|  | +			enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals, value, NULL, false);
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										646
									
								
								0002-computer-add-create-msa-sub-command.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										646
									
								
								0002-computer-add-create-msa-sub-command.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,646 @@ | |||||||
|  | From 41379f7ad6a9442dd55cc43d832427911e86db31 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 23 Oct 2020 16:53:43 +0200 | ||||||
|  | Subject: [PATCH 2/7] computer: add create-msa sub-command | ||||||
|  | 
 | ||||||
|  | Add new sub-command to create a managed service account in AD. This can | ||||||
|  | be used if LDAP access to AD is needed but the host is already joined to | ||||||
|  | a different domain. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1854112 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml      | 140 ++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  library/adenroll.c | 164 ++++++++++++++++++++++++++++++++++++++------- | ||||||
|  |  tools/computer.c   | 125 ++++++++++++++++++++++++++++++++++ | ||||||
|  |  tools/tools.c      |   1 + | ||||||
|  |  tools/tools.h      |   4 ++ | ||||||
|  |  5 files changed, 409 insertions(+), 25 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index cc44fd8..14921f9 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -98,6 +98,10 @@
 | ||||||
|  |  		<arg choice="opt">--domain=domain.example.com</arg> | ||||||
|  |  		<arg choice="plain">computer</arg> | ||||||
|  |  	</cmdsynopsis> | ||||||
|  | +	<cmdsynopsis>
 | ||||||
|  | +		<command>adcli create-msa</command>
 | ||||||
|  | +		<arg choice="opt">--domain=domain.example.com</arg>
 | ||||||
|  | +	</cmdsynopsis>
 | ||||||
|  |  </refsynopsisdiv> | ||||||
|  |   | ||||||
|  |  <refsect1 id='general_overview'> | ||||||
|  | @@ -885,6 +889,142 @@ Password for Administrator:
 | ||||||
|  |   | ||||||
|  |  </refsect1> | ||||||
|  |   | ||||||
|  | +<refsect1 id='managed_service_account'>
 | ||||||
|  | +	<title>Create a managed service account</title>
 | ||||||
|  | +
 | ||||||
|  | +	<para><command>adcli create-msa</command> creates a managed service
 | ||||||
|  | +	account (MSA) in the given Active Directory domain. This is useful if a
 | ||||||
|  | +	computer should not fully join the Active Directory domain but LDAP
 | ||||||
|  | +	access is needed. A typical use case is that the computer is already
 | ||||||
|  | +	joined an Active Directory domain and needs access to another Active
 | ||||||
|  | +	Directory domain in the same or a trusted forest where the host
 | ||||||
|  | +	credentials from the joined Active Directory domain are
 | ||||||
|  | +	not valid, e.g. there is only a one-way trust.</para>
 | ||||||
|  | +
 | ||||||
|  | +<programlisting>
 | ||||||
|  | +$ adcli create-msa --domain=domain.example.com
 | ||||||
|  | +Password for Administrator:
 | ||||||
|  | +</programlisting>
 | ||||||
|  | +
 | ||||||
|  | +	<para>The managed service account, as maintained by adcli, cannot have
 | ||||||
|  | +	additional service principals names (SPNs) associated with it. An SPN
 | ||||||
|  | +	is defined within the context of a Kerberos service which is tied to a
 | ||||||
|  | +	machine account in Active Directory. Since a machine can be joined to a
 | ||||||
|  | +	single Active Directory domain, managed service account in a different
 | ||||||
|  | +	Active Directory domain will not have the SPNs that otherwise are part
 | ||||||
|  | +	of another Active Directory domain's machine.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>Since it is expected that a client will most probably join to the
 | ||||||
|  | +	Active Directory domain matching its DNS domain the managed service
 | ||||||
|  | +	account will be needed for a different Active directory domain and as a
 | ||||||
|  | +	result the Active Directory domain name is a mandatory option. If
 | ||||||
|  | +	called with no other options <command>adcli create-msa</command>
 | ||||||
|  | +	will use the short hostname with an additional random suffix as
 | ||||||
|  | +	computer name to avoid name collisions.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>LDAP attribute sAMAccountName has a limit of 20 characters.
 | ||||||
|  | +	However, machine account's NetBIOS name must be at most 16 characters
 | ||||||
|  | +	long, including a trailing '$' sign. Since it is not expected that the
 | ||||||
|  | +	managed service accounts created by adcli will be used on the NetBIOS
 | ||||||
|  | +	level the remaining 4 characters can be used to add uniqueness. Managed
 | ||||||
|  | +	service account names will have a suffix of 3 random characters from
 | ||||||
|  | +	number and upper- and lowercase ASCII ranges appended to the chosen
 | ||||||
|  | +	short host name, using '!' as a separator. For a host with the
 | ||||||
|  | +	shortname 'myhost', a managed service account will have a common name
 | ||||||
|  | +	(CN attribute) 'myhost!A2c' and a NetBIOS name
 | ||||||
|  | +	(sAMAccountName attribute) will be 'myhost!A2c$'. A corresponding
 | ||||||
|  | +	Kerberos principal in the Active Directory domain where the managed
 | ||||||
|  | +	service account was created would be
 | ||||||
|  | +	'myhost!A2c$@DOMAIN.EXAMPLE.COM'.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>A keytab for the managed service account is stored into a file
 | ||||||
|  | +	specified with -K option. If it is not specified, the file is named
 | ||||||
|  | +	after the default keytab file, with lowercase Active Directory domain
 | ||||||
|  | +	of the managed service account as a suffix. On most systems it would be
 | ||||||
|  | +	<filename>/etc/krb5.keytab</filename> with a suffix of
 | ||||||
|  | +	'domain.example.com', e.g.
 | ||||||
|  | +	<filename>/etc/krb5.keytad.domain.example.com</filename>.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para><command>adcli create-msa</command> can be called multiple
 | ||||||
|  | +	times to reset the password of the managed service account. To identify
 | ||||||
|  | +	the right account with the random component in the name the
 | ||||||
|  | +	corresponding principal is read from the keytab. If the keytab got
 | ||||||
|  | +	deleted <command>adcli</command> will try to identify an existing
 | ||||||
|  | +	managed service account with the help of the fully-qualified name, if
 | ||||||
|  | +	this fails a new managed service account will be created.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>The managed service account password can be updated with
 | ||||||
|  | +<programlisting>
 | ||||||
|  | +$ adcli update --domain=domain.example.com --host-keytab=/etc/krb5.keytad.domain.example.com
 | ||||||
|  | +</programlisting>
 | ||||||
|  | +	and the managed service account can be deleted with
 | ||||||
|  | +<programlisting>
 | ||||||
|  | +$ adcli delete-computer --domain=domain.example.com 'myhost!A2c'
 | ||||||
|  | +</programlisting>
 | ||||||
|  | +	</para>
 | ||||||
|  | +
 | ||||||
|  | +	<para>In addition to the global options, you can specify the following
 | ||||||
|  | +	options to control how this operation is done.</para>
 | ||||||
|  | +
 | ||||||
|  | +	<variablelist>
 | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>-N, --computer-name=<parameter>computer</parameter></option></term>
 | ||||||
|  | +			<listitem><para>The short non-dotted name of the managed
 | ||||||
|  | +			service account that will be created in the Active
 | ||||||
|  | +			Directory domain. The long option name
 | ||||||
|  | +			<option>--computer-name</option> is
 | ||||||
|  | +			kept to underline the similarity with the same option
 | ||||||
|  | +			of the other sub-commands. If not specified,
 | ||||||
|  | +			then the first portion of the <option>--host-fqdn</option>
 | ||||||
|  | +			or its default is used with a random suffix.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>-O, --domain-ou=<parameter>OU=xxx</parameter></option></term>
 | ||||||
|  | +			<listitem><para>The full distinguished name of the OU in
 | ||||||
|  | +			which to create the managed service account. If not
 | ||||||
|  | +			specified, then the managed service account will be
 | ||||||
|  | +			created in a default location.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>-H, --host-fqdn=<parameter>host</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Override the local machine's fully
 | ||||||
|  | +			qualified DNS domain name. If not specified, the local
 | ||||||
|  | +			machine's hostname will be retrieved via
 | ||||||
|  | +			<function>gethostname()</function>.
 | ||||||
|  | +			If <function>gethostname()</function> only returns a short name
 | ||||||
|  | +			<function>getaddrinfo()</function> with the AI_CANONNAME hint
 | ||||||
|  | +			is called to expand the name to a fully qualified DNS
 | ||||||
|  | +			domain name.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>-K, --host-keytab=<parameter>/path/to/keytab</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Specify the path to the host keytab where
 | ||||||
|  | +			credentials of the managed service account will be
 | ||||||
|  | +			written after a successful creation. If not specified,
 | ||||||
|  | +			the default location will be used, usually
 | ||||||
|  | +			<filename>/etc/krb5.keytab</filename> with
 | ||||||
|  | +			the lower-cased Active Directory domain name added as a
 | ||||||
|  | +			suffix e.g.
 | ||||||
|  | +			<filename>/etc/krb5.keytab.domain.example.com</filename>.
 | ||||||
|  | +			</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--show-details</option></term>
 | ||||||
|  | +			<listitem><para>After a successful creation print out
 | ||||||
|  | +			information about the created object. This is output in
 | ||||||
|  | +			a format that should be both human and machine
 | ||||||
|  | +			readable.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--show-password</option></term>
 | ||||||
|  | +			<listitem><para>After a successful creation print out
 | ||||||
|  | +			the managed service account password. This is output in
 | ||||||
|  | +			a format that should be both human and machine
 | ||||||
|  | +			readable.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  | +	</variablelist>
 | ||||||
|  | +</refsect1>
 | ||||||
|  | +
 | ||||||
|  |  <refsect1 id='delegation'> | ||||||
|  |  	<title>Delegated Permissions</title> | ||||||
|  |  	<para>It is common practice in AD to not use an account from the Domain | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 5ae1f7b..dbfda36 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -155,6 +155,20 @@ struct _adcli_enroll {
 | ||||||
|  |  	char *description; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +static void
 | ||||||
|  | +check_if_service (adcli_enroll *enroll,
 | ||||||
|  | +                  LDAP *ldap,
 | ||||||
|  | +                  LDAPMessage *results)
 | ||||||
|  | +{
 | ||||||
|  | +	char **objectclasses = NULL;
 | ||||||
|  | +
 | ||||||
|  | +	objectclasses = _adcli_ldap_parse_values (ldap, results, "objectClass");
 | ||||||
|  | +	enroll->is_service = _adcli_strv_has_ex (objectclasses,
 | ||||||
|  | +	                                         "msDS-ManagedServiceAccount",
 | ||||||
|  | +	                                         strcasecmp) == 1 ? true : false;
 | ||||||
|  | +	_adcli_strv_free (objectclasses);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static adcli_result | ||||||
|  |  ensure_host_fqdn (adcli_result res, | ||||||
|  |                    adcli_enroll *enroll) | ||||||
|  | @@ -471,13 +485,15 @@ ensure_keytab_principals (adcli_result res,
 | ||||||
|  |  { | ||||||
|  |  	krb5_context k5; | ||||||
|  |  	krb5_error_code code; | ||||||
|  | -	int count;
 | ||||||
|  | +	int count = 0;
 | ||||||
|  |  	int at, i; | ||||||
|  |   | ||||||
|  |  	/* Prepare the principals we're going to add to the keytab */ | ||||||
|  |   | ||||||
|  | -	return_unexpected_if_fail (enroll->service_principals);
 | ||||||
|  | -	count = _adcli_strv_len (enroll->service_principals);
 | ||||||
|  | +	if (!enroll->is_service) {
 | ||||||
|  | +		return_unexpected_if_fail (enroll->service_principals);
 | ||||||
|  | +		count = _adcli_strv_len (enroll->service_principals);
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	k5 = adcli_conn_get_krb5_context (enroll->conn); | ||||||
|  |  	return_unexpected_if_fail (k5 != NULL); | ||||||
|  | @@ -556,8 +572,12 @@ static adcli_result
 | ||||||
|  |  lookup_computer_container (adcli_enroll *enroll, | ||||||
|  |                             LDAP *ldap) | ||||||
|  |  { | ||||||
|  | -	char *attrs[] = { "wellKnownObjects", NULL };
 | ||||||
|  | -	char *prefix = "B:32:AA312825768811D1ADED00C04FD8D5CD:";
 | ||||||
|  | +	char *attrs[] = { enroll->is_service ? "otherWellKnownObjects"
 | ||||||
|  | +	                                     : "wellKnownObjects", NULL };
 | ||||||
|  | +	const char *prefix = enroll->is_service ? "B:32:1EB93889E40C45DF9F0C64D23BBB6237:"
 | ||||||
|  | +	                                        : "B:32:AA312825768811D1ADED00C04FD8D5CD:";
 | ||||||
|  | +	const char *filter = enroll->is_service ? "(&(objectClass=container)(cn=Managed Service Accounts))"
 | ||||||
|  | +	                                        : "(&(objectClass=container)(cn=Computers))";
 | ||||||
|  |  	int prefix_len; | ||||||
|  |  	LDAPMessage *results; | ||||||
|  |  	const char *base; | ||||||
|  | @@ -586,7 +606,7 @@ lookup_computer_container (adcli_enroll *enroll,
 | ||||||
|  |  		                                   "Couldn't lookup computer container: %s", base); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	values = _adcli_ldap_parse_values (ldap, results, "wellKnownObjects");
 | ||||||
|  | +	values = _adcli_ldap_parse_values (ldap, results, attrs[0]);
 | ||||||
|  |  	ldap_msgfree (results); | ||||||
|  |   | ||||||
|  |  	prefix_len = strlen (prefix); | ||||||
|  | @@ -604,8 +624,7 @@ lookup_computer_container (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  	/* Try harder */ | ||||||
|  |  	if (!enroll->computer_container) { | ||||||
|  | -		ret = ldap_search_ext_s (ldap, base, LDAP_SCOPE_BASE,
 | ||||||
|  | -		                         "(&(objectClass=container)(cn=Computers))",
 | ||||||
|  | +		ret = ldap_search_ext_s (ldap, base, LDAP_SCOPE_BASE, filter,
 | ||||||
|  |  		                         attrs, 0, NULL, NULL, NULL, -1, &results); | ||||||
|  |  		if (ret == LDAP_SUCCESS) { | ||||||
|  |  			enroll->computer_container = _adcli_ldap_parse_dn (ldap, results); | ||||||
|  | @@ -747,7 +766,7 @@ static adcli_result
 | ||||||
|  |  create_computer_account (adcli_enroll *enroll, | ||||||
|  |                           LDAP *ldap) | ||||||
|  |  { | ||||||
|  | -	char *vals_objectClass[] = { "computer", NULL };
 | ||||||
|  | +	char *vals_objectClass[] = { enroll->is_service ? "msDS-ManagedServiceAccount" : "computer", NULL };
 | ||||||
|  |  	LDAPMod objectClass = { LDAP_MOD_ADD, "objectClass", { vals_objectClass, } }; | ||||||
|  |  	char *vals_sAMAccountName[] = { enroll->computer_sam, NULL }; | ||||||
|  |  	LDAPMod sAMAccountName = { LDAP_MOD_ADD, "sAMAccountName", { vals_sAMAccountName, } }; | ||||||
|  | @@ -806,7 +825,7 @@ create_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	m = 0; | ||||||
|  |  	for (c = 0; c < mods_count - 1; c++) { | ||||||
|  |  		/* Skip empty LDAP sttributes */ | ||||||
|  | -		if (all_mods[c]->mod_vals.modv_strvals[0] != NULL) {
 | ||||||
|  | +		if (all_mods[c]->mod_vals.modv_strvals != NULL && all_mods[c]->mod_vals.modv_strvals[0] != NULL) {
 | ||||||
|  |  			mods[m++] = all_mods[c]; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -936,7 +955,7 @@ locate_computer_account (adcli_enroll *enroll,
 | ||||||
|  |                           LDAPMessage **rresults, | ||||||
|  |                           LDAPMessage **rentry) | ||||||
|  |  { | ||||||
|  | -	char *attrs[] = { "1.1", NULL };
 | ||||||
|  | +	char *attrs[] = { "objectClass", NULL };
 | ||||||
|  |  	LDAPMessage *results = NULL; | ||||||
|  |  	LDAPMessage *entry = NULL; | ||||||
|  |  	const char *base; | ||||||
|  | @@ -948,7 +967,9 @@ locate_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	/* If we don't yet know our computer dn, then try and find it */ | ||||||
|  |  	value = _adcli_ldap_escape_filter (enroll->computer_sam); | ||||||
|  |  	return_unexpected_if_fail (value != NULL); | ||||||
|  | -	if (asprintf (&filter, "(&(objectClass=computer)(sAMAccountName=%s))", value) < 0)
 | ||||||
|  | +	if (asprintf (&filter, "(&(objectClass=%s)(sAMAccountName=%s))",
 | ||||||
|  | +	              enroll->is_service ? "msDS-ManagedServiceAccount" : "computer",
 | ||||||
|  | +	              value) < 0)
 | ||||||
|  |  		return_unexpected_if_reached (); | ||||||
|  |  	free (value); | ||||||
|  |   | ||||||
|  | @@ -962,8 +983,11 @@ locate_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	if (ret == LDAP_SUCCESS) { | ||||||
|  |  		entry = ldap_first_entry (ldap, results); | ||||||
|  |   | ||||||
|  | -		/* If we found a computer account, make note of dn */
 | ||||||
|  | +		/* If we found a computer/service account, make note of dn */
 | ||||||
|  |  		if (entry) { | ||||||
|  | +			if (!enroll->is_service_explicit) {
 | ||||||
|  | +				check_if_service ( enroll, ldap, results);
 | ||||||
|  | +			}
 | ||||||
|  |  			dn = ldap_get_dn (ldap, entry); | ||||||
|  |  			free (enroll->computer_dn); | ||||||
|  |  			enroll->computer_dn = strdup (dn); | ||||||
|  | @@ -1003,7 +1027,7 @@ load_computer_account (adcli_enroll *enroll,
 | ||||||
|  |                         LDAPMessage **rresults, | ||||||
|  |                         LDAPMessage **rentry) | ||||||
|  |  { | ||||||
|  | -	char *attrs[] = { "1.1", NULL };
 | ||||||
|  | +	char *attrs[] = { "objectClass", NULL };
 | ||||||
|  |  	LDAPMessage *results = NULL; | ||||||
|  |  	LDAPMessage *entry = NULL; | ||||||
|  |  	int ret; | ||||||
|  | @@ -1081,6 +1105,12 @@ locate_or_create_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	if (res == ADCLI_SUCCESS && entry == NULL) | ||||||
|  |  		res = create_computer_account (enroll, ldap); | ||||||
|  |   | ||||||
|  | +	/* Service account already exists, just continue and update the
 | ||||||
|  | +	 * password */
 | ||||||
|  | +	if (enroll->is_service && entry != NULL) {
 | ||||||
|  | +		res = ADCLI_SUCCESS;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	if (results) | ||||||
|  |  		ldap_msgfree (results); | ||||||
|  |   | ||||||
|  | @@ -1413,6 +1443,11 @@ update_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  	LDAP *ldap; | ||||||
|  |  	char *value = NULL; | ||||||
|  |   | ||||||
|  | +	/* No updates for service accounts */
 | ||||||
|  | +	if (enroll->is_service) {
 | ||||||
|  | +		return;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	ldap = adcli_conn_get_ldap_connection (enroll->conn); | ||||||
|  |  	return_if_fail (ldap != NULL); | ||||||
|  |   | ||||||
|  | @@ -1501,6 +1536,11 @@ update_service_principals (adcli_enroll *enroll)
 | ||||||
|  |  	LDAP *ldap; | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  | +	/* No updates for service accounts */
 | ||||||
|  | +	if (enroll->is_service) {
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	ldap = adcli_conn_get_ldap_connection (enroll->conn); | ||||||
|  |  	return_unexpected_if_fail (ldap != NULL); | ||||||
|  |   | ||||||
|  | @@ -1614,6 +1654,8 @@ load_keytab_entry (krb5_context k5,
 | ||||||
|  |  			enroll->computer_name = name; | ||||||
|  |  			name[len - 1] = '\0'; | ||||||
|  |  			_adcli_info ("Found computer name in keytab: %s", name); | ||||||
|  | +			adcli_conn_set_computer_name (enroll->conn,
 | ||||||
|  | +			                              enroll->computer_name);
 | ||||||
|  |  			name = NULL; | ||||||
|  |   | ||||||
|  |  		} else if (!enroll->host_fqdn && _adcli_str_has_prefix (name, "host/") && strchr (name, '.')) { | ||||||
|  | @@ -2002,17 +2044,25 @@ adcli_enroll_prepare (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  	adcli_clear_last_error (); | ||||||
|  |   | ||||||
|  | -	/* Basic discovery and figuring out enroll params */
 | ||||||
|  | -	res = ensure_host_fqdn (res, enroll);
 | ||||||
|  | -	res = ensure_computer_name (res, enroll);
 | ||||||
|  | -	res = ensure_computer_sam (res, enroll);
 | ||||||
|  | -	res = ensure_user_principal (res, enroll);
 | ||||||
|  | -	res = ensure_computer_password (res, enroll);
 | ||||||
|  | -	if (!(flags & ADCLI_ENROLL_NO_KEYTAB))
 | ||||||
|  | +	if (enroll->is_service) {
 | ||||||
|  | +		/* Ensure basic params for service accounts */
 | ||||||
|  | +		res = ensure_computer_sam (res, enroll);
 | ||||||
|  | +		res = ensure_computer_password (res, enroll);
 | ||||||
|  |  		res = ensure_host_keytab (res, enroll); | ||||||
|  | -	res = ensure_service_names (res, enroll);
 | ||||||
|  | -	res = ensure_service_principals (res, enroll);
 | ||||||
|  | -	res = ensure_keytab_principals (res, enroll);
 | ||||||
|  | +		res = ensure_keytab_principals (res, enroll);
 | ||||||
|  | +	} else {
 | ||||||
|  | +		/* Basic discovery and figuring out enroll params */
 | ||||||
|  | +		res = ensure_host_fqdn (res, enroll);
 | ||||||
|  | +		res = ensure_computer_name (res, enroll);
 | ||||||
|  | +		res = ensure_computer_sam (res, enroll);
 | ||||||
|  | +		res = ensure_user_principal (res, enroll);
 | ||||||
|  | +		res = ensure_computer_password (res, enroll);
 | ||||||
|  | +		if (!(flags & ADCLI_ENROLL_NO_KEYTAB))
 | ||||||
|  | +			res = ensure_host_keytab (res, enroll);
 | ||||||
|  | +		res = ensure_service_names (res, enroll);
 | ||||||
|  | +		res = ensure_service_principals (res, enroll);
 | ||||||
|  | +		res = ensure_keytab_principals (res, enroll);
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	return res; | ||||||
|  |  } | ||||||
|  | @@ -2157,6 +2207,58 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
 | ||||||
|  |  	return update_keytab_for_principals (enroll, flags); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static adcli_result
 | ||||||
|  | +adcli_enroll_add_description_for_service_account (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	const char *fqdn;
 | ||||||
|  | +	char *desc;
 | ||||||
|  | +
 | ||||||
|  | +	fqdn = adcli_conn_get_host_fqdn (enroll->conn);
 | ||||||
|  | +	return_unexpected_if_fail (fqdn != NULL);
 | ||||||
|  | +	if (asprintf (&desc, "Please do not edit, Service account for %s, "
 | ||||||
|  | +	                     "managed by adcli.", fqdn) < 0) {
 | ||||||
|  | +		return_unexpected_if_reached ();
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	adcli_enroll_set_description (enroll, desc);
 | ||||||
|  | +	free (desc);
 | ||||||
|  | +
 | ||||||
|  | +	return ADCLI_SUCCESS;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static adcli_result
 | ||||||
|  | +adcli_enroll_add_keytab_for_service_account (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	krb5_context k5;
 | ||||||
|  | +	krb5_error_code code;
 | ||||||
|  | +	char def_keytab_name[MAX_KEYTAB_NAME_LEN];
 | ||||||
|  | +	char *lc_dom_name;
 | ||||||
|  | +	int ret;
 | ||||||
|  | +
 | ||||||
|  | +	if (adcli_enroll_get_keytab_name (enroll) == NULL) {
 | ||||||
|  | +		k5 = adcli_conn_get_krb5_context (enroll->conn);
 | ||||||
|  | +		return_unexpected_if_fail (k5 != NULL);
 | ||||||
|  | +
 | ||||||
|  | +		code = krb5_kt_default_name (k5, def_keytab_name,
 | ||||||
|  | +		                             sizeof (def_keytab_name));
 | ||||||
|  | +		return_unexpected_if_fail (code == 0);
 | ||||||
|  | +
 | ||||||
|  | +		lc_dom_name = strdup (adcli_conn_get_domain_name (enroll->conn));
 | ||||||
|  | +		return_unexpected_if_fail (lc_dom_name != NULL);
 | ||||||
|  | +		_adcli_str_down (lc_dom_name);
 | ||||||
|  | +
 | ||||||
|  | +
 | ||||||
|  | +		ret = asprintf (&enroll->keytab_name, "%s.%s", def_keytab_name,
 | ||||||
|  | +		                                             lc_dom_name);
 | ||||||
|  | +		free (lc_dom_name);
 | ||||||
|  | +		return_unexpected_if_fail (ret > 0);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	_adcli_info ("Using service account keytab: %s", enroll->keytab_name);
 | ||||||
|  | +
 | ||||||
|  | +	return ADCLI_SUCCESS;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  adcli_result | ||||||
|  |  adcli_enroll_join (adcli_enroll *enroll, | ||||||
|  |                     adcli_enroll_flags flags) | ||||||
|  | @@ -2172,7 +2274,14 @@ adcli_enroll_join (adcli_enroll *enroll,
 | ||||||
|  |  	if (res != ADCLI_SUCCESS) | ||||||
|  |  		return res; | ||||||
|  |   | ||||||
|  | -	res = ensure_default_service_names (enroll);
 | ||||||
|  | +	if (enroll->is_service) {
 | ||||||
|  | +		res = adcli_enroll_add_description_for_service_account (enroll);
 | ||||||
|  | +		if (res == ADCLI_SUCCESS) {
 | ||||||
|  | +			res = adcli_enroll_add_keytab_for_service_account (enroll);
 | ||||||
|  | +		}
 | ||||||
|  | +	} else {
 | ||||||
|  | +		res = ensure_default_service_names (enroll);
 | ||||||
|  | +	}
 | ||||||
|  |  	if (res != ADCLI_SUCCESS) | ||||||
|  |  		return res; | ||||||
|  |   | ||||||
|  | @@ -2281,6 +2390,11 @@ adcli_enroll_update (adcli_enroll *enroll,
 | ||||||
|  |  	} | ||||||
|  |  	free (value); | ||||||
|  |   | ||||||
|  | +	/* We only support password changes for service accounts */
 | ||||||
|  | +	if (enroll->is_service && (flags & ADCLI_ENROLL_PASSWORD_VALID)) {
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	return enroll_join_or_update_tasks (enroll, flags); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index 5a97d8b..63fd374 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -1074,3 +1074,128 @@ adcli_tool_computer_show (adcli_conn *conn,
 | ||||||
|  |  	adcli_enroll_unref (enroll); | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +int
 | ||||||
|  | +adcli_tool_computer_managed_service_account (adcli_conn *conn,
 | ||||||
|  | +                                             int argc,
 | ||||||
|  | +                                             char *argv[])
 | ||||||
|  | +{
 | ||||||
|  | +	adcli_enroll *enroll;
 | ||||||
|  | +	adcli_result res;
 | ||||||
|  | +	int show_password = 0;
 | ||||||
|  | +	int details = 0;
 | ||||||
|  | +	int opt;
 | ||||||
|  | +
 | ||||||
|  | +	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 },
 | ||||||
|  | +		{ "host-fqdn", required_argument, 0, opt_host_fqdn },
 | ||||||
|  | +		{ "computer-name", required_argument, 0, opt_computer_name },
 | ||||||
|  | +		{ "host-keytab", required_argument, 0, opt_host_keytab },
 | ||||||
|  | +		{ "no-password", no_argument, 0, opt_no_password },
 | ||||||
|  | +		{ "stdin-password", no_argument, 0, opt_stdin_password },
 | ||||||
|  | +		{ "prompt-password", no_argument, 0, opt_prompt_password },
 | ||||||
|  | +		{ "domain-ou", required_argument, NULL, opt_domain_ou },
 | ||||||
|  | +		{ "show-details", no_argument, NULL, opt_show_details },
 | ||||||
|  | +		{ "show-password", no_argument, NULL, opt_show_password },
 | ||||||
|  | +		{ "verbose", no_argument, NULL, opt_verbose },
 | ||||||
|  | +		{ "help", no_argument, NULL, 'h' },
 | ||||||
|  | +		{ 0 },
 | ||||||
|  | +	};
 | ||||||
|  | +
 | ||||||
|  | +	static adcli_tool_desc usages[] = {
 | ||||||
|  | +		{ 0, "usage: adcli create-msa --domain=xxxx" },
 | ||||||
|  | +		{ 0 },
 | ||||||
|  | +	};
 | ||||||
|  | +
 | ||||||
|  | +	enroll = adcli_enroll_new (conn);
 | ||||||
|  | +	if (enroll == NULL) {
 | ||||||
|  | +		warnx ("unexpected memory problems");
 | ||||||
|  | +		return -1;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) {
 | ||||||
|  | +		switch (opt) {
 | ||||||
|  | +		case opt_one_time_password:
 | ||||||
|  | +			adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_COMPUTER_ACCOUNT);
 | ||||||
|  | +			adcli_conn_set_computer_password (conn, optarg);
 | ||||||
|  | +			break;
 | ||||||
|  | +		case opt_show_details:
 | ||||||
|  | +			details = 1;
 | ||||||
|  | +			break;
 | ||||||
|  | +		case opt_show_password:
 | ||||||
|  | +			show_password = 1;
 | ||||||
|  | +			break;
 | ||||||
|  | +		case 'h':
 | ||||||
|  | +		case '?':
 | ||||||
|  | +		case ':':
 | ||||||
|  | +			adcli_tool_usage (options, usages);
 | ||||||
|  | +			adcli_tool_usage (options, common_usages);
 | ||||||
|  | +			adcli_enroll_unref (enroll);
 | ||||||
|  | +			return opt == 'h' ? 0 : 2;
 | ||||||
|  | +		default:
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				adcli_enroll_unref (enroll);
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  | +			break;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	argc -= optind;
 | ||||||
|  | +	argv += optind;
 | ||||||
|  | +
 | ||||||
|  | +	if (argc == 1)
 | ||||||
|  | +		adcli_conn_set_domain_name (conn, argv[0]);
 | ||||||
|  | +	else if (argc > 1) {
 | ||||||
|  | +		warnx ("extra arguments specified");
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return 2;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (adcli_conn_get_domain_name (conn) == NULL) {
 | ||||||
|  | +		warnx ("domain name is required");
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return 2;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	adcli_enroll_set_is_service (enroll, true);
 | ||||||
|  | +	adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT);
 | ||||||
|  | +
 | ||||||
|  | +	res = adcli_enroll_load (enroll);
 | ||||||
|  | +	if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +		/* ignored */
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	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_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	res = adcli_enroll_join (enroll, 0);
 | ||||||
|  | +	if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +		warnx ("Adding service account for %s failed: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return -res;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (details)
 | ||||||
|  | +		dump_details (conn, enroll, show_password);
 | ||||||
|  | +	else if (show_password)
 | ||||||
|  | +		dump_password (conn, enroll);
 | ||||||
|  | +
 | ||||||
|  | +	adcli_enroll_unref (enroll);
 | ||||||
|  | +
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | diff --git a/tools/tools.c b/tools/tools.c
 | ||||||
|  | index 1b6d879..d0dcf98 100644
 | ||||||
|  | --- a/tools/tools.c
 | ||||||
|  | +++ b/tools/tools.c
 | ||||||
|  | @@ -60,6 +60,7 @@ struct {
 | ||||||
|  |  	{ "reset-computer", adcli_tool_computer_reset, "Reset a computer account", }, | ||||||
|  |  	{ "delete-computer", adcli_tool_computer_delete, "Delete a computer account", }, | ||||||
|  |  	{ "show-computer", adcli_tool_computer_show, "Show computer account attributes stored in AD", }, | ||||||
|  | +	{ "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", }, | ||||||
|  |  	{ "create-group", adcli_tool_group_create, "Create a group", }, | ||||||
|  | diff --git a/tools/tools.h b/tools/tools.h
 | ||||||
|  | index 3702875..82d5e4e 100644
 | ||||||
|  | --- a/tools/tools.h
 | ||||||
|  | +++ b/tools/tools.h
 | ||||||
|  | @@ -82,6 +82,10 @@ int       adcli_tool_computer_show     (adcli_conn *conn,
 | ||||||
|  |                                          int argc, | ||||||
|  |                                          char *argv[]); | ||||||
|  |   | ||||||
|  | +int       adcli_tool_computer_managed_service_account (adcli_conn *conn,
 | ||||||
|  | +                                                       int argc,
 | ||||||
|  | +                                                       char *argv[]);
 | ||||||
|  | +
 | ||||||
|  |  int       adcli_tool_user_create       (adcli_conn *conn, | ||||||
|  |                                          int argc, | ||||||
|  |                                          char *argv[]); | ||||||
|  | -- 
 | ||||||
|  | 2.28.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										147
									
								
								0002-create-user-try-to-find-NIS-domain-if-needed.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								0002-create-user-try-to-find-NIS-domain-if-needed.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,147 @@ | |||||||
|  | From 408880a11879b1a57a450e25c77ef2e310bdffd5 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 18 Mar 2019 16:45:54 +0100 | ||||||
|  | Subject: [PATCH 2/2] create-user: try to find NIS domain if needed | ||||||
|  | 
 | ||||||
|  | Related to https://gitlab.freedesktop.org/realmd/adcli/issues/2 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml     |  4 +++- | ||||||
|  |  library/adentry.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  library/adentry.h |  2 ++ | ||||||
|  |  tools/entry.c     | 16 ++++++++++++++++ | ||||||
|  |  4 files changed, 65 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index 18620c0..af73433 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -537,7 +537,9 @@ $ adcli create-user Fry --domain=domain.example.com \
 | ||||||
|  |  			the new created user account, which should be the user's | ||||||
|  |  			NIS domain is the NIS/YP service of Active Directory's Services for Unix (SFU) | ||||||
|  |  			are used. This is needed to let the 'UNIX attributes' tab of older Active | ||||||
|  | -			Directoy versions show the set UNIX specific attributes.</para></listitem>
 | ||||||
|  | +			Directoy versions show the set UNIX specific attributes. If not specified
 | ||||||
|  | +			adcli will try to determine the NIS domain automatically if needed.
 | ||||||
|  | +			</para></listitem>
 | ||||||
|  |  		</varlistentry> | ||||||
|  |  	</variablelist> | ||||||
|  |   | ||||||
|  | diff --git a/library/adentry.c b/library/adentry.c
 | ||||||
|  | index 9b9e1c6..1cc0518 100644
 | ||||||
|  | --- a/library/adentry.c
 | ||||||
|  | +++ b/library/adentry.c
 | ||||||
|  | @@ -484,3 +484,47 @@ adcli_entry_new_group (adcli_conn *conn,
 | ||||||
|  |  	return_val_if_fail (sam_name != NULL, NULL); | ||||||
|  |  	return entry_new (conn, "group", group_entry_builder, sam_name); | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +adcli_result
 | ||||||
|  | +adcli_get_nis_domain (adcli_entry *entry,
 | ||||||
|  | +                      adcli_attrs *attrs)
 | ||||||
|  | +{
 | ||||||
|  | +	LDAP *ldap;
 | ||||||
|  | +	const char *ldap_attrs[] = { "cn", NULL };
 | ||||||
|  | +	LDAPMessage *results;
 | ||||||
|  | +	LDAPMessage *ldap_entry;
 | ||||||
|  | +	char *base;
 | ||||||
|  | +	const char *filter = "objectClass=msSFU30DomainInfo";
 | ||||||
|  | +	char *cn;
 | ||||||
|  | +	int ret;
 | ||||||
|  | +
 | ||||||
|  | +	ldap = adcli_conn_get_ldap_connection (entry->conn);
 | ||||||
|  | +	return_unexpected_if_fail (ldap != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	if (asprintf (&base, "CN=ypservers,CN=ypServ30,CN=RpcServices,CN=System,%s",
 | ||||||
|  | +	              adcli_conn_get_default_naming_context (entry->conn)) < 0) {
 | ||||||
|  | +		return_unexpected_if_reached ();
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	ret = ldap_search_ext_s (ldap, base, LDAP_SCOPE_SUB, filter, (char **)ldap_attrs,
 | ||||||
|  | +	                         0, NULL, NULL, NULL, -1, &results);
 | ||||||
|  | +
 | ||||||
|  | +	free (base);
 | ||||||
|  | +
 | ||||||
|  | +	if (ret != LDAP_SUCCESS) {
 | ||||||
|  | +		/* No NIS domain available */
 | ||||||
|  | +		ldap_msgfree (results);
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	ldap_entry = ldap_first_entry (ldap, results);
 | ||||||
|  | +	if (ldap_entry != NULL) {
 | ||||||
|  | +		cn = _adcli_ldap_parse_value (ldap, ldap_entry, "cn");
 | ||||||
|  | +		return_unexpected_if_fail (cn != NULL);
 | ||||||
|  | +
 | ||||||
|  | +		adcli_attrs_add (attrs, "msSFU30NisDomain", cn, NULL);
 | ||||||
|  | +	}
 | ||||||
|  | +	ldap_msgfree (results);
 | ||||||
|  | +
 | ||||||
|  | +	return ADCLI_SUCCESS;
 | ||||||
|  | +}
 | ||||||
|  | diff --git a/library/adentry.h b/library/adentry.h
 | ||||||
|  | index eb8bc00..ae90689 100644
 | ||||||
|  | --- a/library/adentry.h
 | ||||||
|  | +++ b/library/adentry.h
 | ||||||
|  | @@ -58,4 +58,6 @@ const char *       adcli_entry_get_sam_name             (adcli_entry *entry);
 | ||||||
|  |   | ||||||
|  |  const char *       adcli_entry_get_dn                   (adcli_entry *entry); | ||||||
|  |   | ||||||
|  | +adcli_result       adcli_get_nis_domain                 (adcli_entry *entry,
 | ||||||
|  | +                                                         adcli_attrs *attrs);
 | ||||||
|  |  #endif /* ADENTRY_H_ */ | ||||||
|  | diff --git a/tools/entry.c b/tools/entry.c
 | ||||||
|  | index 69ce62c..de56586 100644
 | ||||||
|  | --- a/tools/entry.c
 | ||||||
|  | +++ b/tools/entry.c
 | ||||||
|  | @@ -153,6 +153,8 @@ adcli_tool_user_create (adcli_conn *conn,
 | ||||||
|  |  	adcli_attrs *attrs; | ||||||
|  |  	const char *ou = NULL; | ||||||
|  |  	int opt; | ||||||
|  | +	bool has_unix_attr = false;
 | ||||||
|  | +	bool has_nis_domain = false;
 | ||||||
|  |   | ||||||
|  |  	struct option options[] = { | ||||||
|  |  		{ "display-name", required_argument, NULL, opt_display_name }, | ||||||
|  | @@ -193,18 +195,23 @@ adcli_tool_user_create (adcli_conn *conn,
 | ||||||
|  |  			break; | ||||||
|  |  		case opt_unix_home: | ||||||
|  |  			adcli_attrs_add (attrs, "unixHomeDirectory", optarg, NULL); | ||||||
|  | +			has_unix_attr = true;
 | ||||||
|  |  			break; | ||||||
|  |  		case opt_unix_uid: | ||||||
|  |  			adcli_attrs_add (attrs, "uidNumber", optarg, NULL); | ||||||
|  | +			has_unix_attr = true;
 | ||||||
|  |  			break; | ||||||
|  |  		case opt_unix_gid: | ||||||
|  |  			adcli_attrs_add (attrs, "gidNumber", optarg, NULL); | ||||||
|  | +			has_unix_attr = true;
 | ||||||
|  |  			break; | ||||||
|  |  		case opt_unix_shell: | ||||||
|  |  			adcli_attrs_add (attrs, "loginShell", optarg, NULL); | ||||||
|  | +			has_unix_attr = true;
 | ||||||
|  |  			break; | ||||||
|  |  		case opt_nis_domain: | ||||||
|  |  			adcli_attrs_add (attrs, "msSFU30NisDomain", optarg, NULL); | ||||||
|  | +			has_nis_domain = true;
 | ||||||
|  |  			break; | ||||||
|  |  		case opt_domain_ou: | ||||||
|  |  			ou = optarg; | ||||||
|  | @@ -242,6 +249,15 @@ adcli_tool_user_create (adcli_conn *conn,
 | ||||||
|  |  		      adcli_get_last_error ()); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	if (has_unix_attr && !has_nis_domain) {
 | ||||||
|  | +		res = adcli_get_nis_domain (entry, attrs);
 | ||||||
|  | +		if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +			adcli_entry_unref (entry);
 | ||||||
|  | +			adcli_attrs_free (attrs);
 | ||||||
|  | +			errx (-res, "couldn't get NIS domain");
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	res = adcli_entry_create (entry, attrs); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  |  		errx (-res, "creating user %s in domain %s failed: %s", | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										42
									
								
								0002-library-make-_adcli_strv_has_ex-public.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								0002-library-make-_adcli_strv_has_ex-public.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | From e1b45e66bc185f5db4c252e1f3fb1b4400b4538e Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 22 Mar 2019 10:36:38 +0100 | ||||||
|  | Subject: [PATCH 2/4] library: make _adcli_strv_has_ex public | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1630187 | ||||||
|  | ---
 | ||||||
|  |  library/adprivate.h | 4 ++++ | ||||||
|  |  library/adutil.c    | 2 +- | ||||||
|  |  2 files changed, 5 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adprivate.h b/library/adprivate.h
 | ||||||
|  | index 0806430..55e6234 100644
 | ||||||
|  | --- a/library/adprivate.h
 | ||||||
|  | +++ b/library/adprivate.h
 | ||||||
|  | @@ -125,6 +125,10 @@ void           _adcli_strv_free              (char **strv);
 | ||||||
|  |  int            _adcli_strv_has               (char **strv, | ||||||
|  |                                                const char *str); | ||||||
|  |   | ||||||
|  | +int            _adcli_strv_has_ex            (char **strv,
 | ||||||
|  | +                                              const char *str,
 | ||||||
|  | +                                              int (* compare) (const char *match, const char*value));
 | ||||||
|  | +
 | ||||||
|  |  char **        _adcli_strv_dup               (char **strv) GNUC_WARN_UNUSED; | ||||||
|  |   | ||||||
|  |  char *         _adcli_strv_join              (char **strv, | ||||||
|  | diff --git a/library/adutil.c b/library/adutil.c
 | ||||||
|  | index 76ea158..9b0c47f 100644
 | ||||||
|  | --- a/library/adutil.c
 | ||||||
|  | +++ b/library/adutil.c
 | ||||||
|  | @@ -221,7 +221,7 @@ _adcli_strv_add (char **strv,
 | ||||||
|  |  	return seq_push (strv, length, string); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static int
 | ||||||
|  | +int
 | ||||||
|  |  _adcli_strv_has_ex (char **strv, | ||||||
|  |                      const char *str, | ||||||
|  |                      int (* compare) (const char *match, const char*value)) | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										35
									
								
								0002-library-return-error-if-no-matching-key-was-found.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								0002-library-return-error-if-no-matching-key-was-found.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | From 4987a21f4839ab7ea50e932c72df05075efb89b3 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 21 Mar 2019 15:05:33 +0100 | ||||||
|  | Subject: [PATCH 2/2] library: return error if no matching key was found | ||||||
|  | 
 | ||||||
|  | To avoid a misleading debug message indicating success a proper erro | ||||||
|  | code should be returned the no matching key was found when trying to | ||||||
|  | copy an keytab entry for a new principal. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1644311 | ||||||
|  | ---
 | ||||||
|  |  library/adkrb5.c | 5 ++--- | ||||||
|  |  1 file changed, 2 insertions(+), 3 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adkrb5.c b/library/adkrb5.c
 | ||||||
|  | index 033c181..7f77373 100644
 | ||||||
|  | --- a/library/adkrb5.c
 | ||||||
|  | +++ b/library/adkrb5.c
 | ||||||
|  | @@ -298,11 +298,10 @@ _adcli_krb5_keytab_copy_entries (krb5_context k5,
 | ||||||
|  |   | ||||||
|  |  		code = _adcli_krb5_get_keyblock (k5, keytab, &entry.key, | ||||||
|  |  		                                 match_enctype_and_kvno, &closure); | ||||||
|  | -		if (code != 0) {
 | ||||||
|  | -			return code;
 | ||||||
|  | +		if (code != 0 || closure.matched == 0) {
 | ||||||
|  | +			return code != 0 ? code : ENOKEY;
 | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  | -
 | ||||||
|  |  		entry.principal = principal; | ||||||
|  |  		entry.vno = kvno; | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										398
									
								
								0002-tools-remove-errx-from-user-and-group-commands.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										398
									
								
								0002-tools-remove-errx-from-user-and-group-commands.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,398 @@ | |||||||
|  | From cac0fa9df8888245399f2db187e05e31f93d1471 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 15 Apr 2019 17:56:37 +0200 | ||||||
|  | Subject: [PATCH 2/7] tools: remove errx from user and group commands | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596 | ||||||
|  | ---
 | ||||||
|  |  tools/entry.c | 232 +++++++++++++++++++++++++++++++++----------------- | ||||||
|  |  1 file changed, 154 insertions(+), 78 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/entry.c b/tools/entry.c
 | ||||||
|  | index de56586..97ec6e7 100644
 | ||||||
|  | --- a/tools/entry.c
 | ||||||
|  | +++ b/tools/entry.c
 | ||||||
|  | @@ -232,21 +232,30 @@ adcli_tool_user_create (adcli_conn *conn,
 | ||||||
|  |  	argc -= optind; | ||||||
|  |  	argv += optind; | ||||||
|  |   | ||||||
|  | -	if (argc != 1)
 | ||||||
|  | -		errx (2, "specify one user name to create");
 | ||||||
|  | +	if (argc != 1) {
 | ||||||
|  | +		warnx ("specify one user name to create");
 | ||||||
|  | +		adcli_attrs_free (attrs);
 | ||||||
|  | +		return 2;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	entry = adcli_entry_new_user (conn, argv[0]); | ||||||
|  | -	if (entry == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	if (entry == NULL) {
 | ||||||
|  | +		warnx ("unexpected memory problems");
 | ||||||
|  | +		adcli_attrs_free (attrs);
 | ||||||
|  | +		return -1;
 | ||||||
|  | +	}
 | ||||||
|  |  	adcli_entry_set_domain_ou (entry, ou); | ||||||
|  |   | ||||||
|  |  	adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT); | ||||||
|  |   | ||||||
|  |  	res = adcli_conn_connect (conn); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't connect to %s domain: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_entry_unref (entry);
 | ||||||
|  | +		adcli_attrs_free (attrs);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (has_unix_attr && !has_nis_domain) { | ||||||
|  | @@ -254,16 +263,20 @@ adcli_tool_user_create (adcli_conn *conn,
 | ||||||
|  |  		if (res != ADCLI_SUCCESS) { | ||||||
|  |  			adcli_entry_unref (entry); | ||||||
|  |  			adcli_attrs_free (attrs); | ||||||
|  | -			errx (-res, "couldn't get NIS domain");
 | ||||||
|  | +			warnx ("couldn't get NIS domain");
 | ||||||
|  | +			return -res;
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	res = adcli_entry_create (entry, attrs); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "creating user %s in domain %s failed: %s",
 | ||||||
|  | -		      adcli_entry_get_sam_name (entry),
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("creating 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);
 | ||||||
|  | +		adcli_attrs_free (attrs);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	adcli_entry_unref (entry); | ||||||
|  | @@ -317,28 +330,36 @@ adcli_tool_user_delete (adcli_conn *conn,
 | ||||||
|  |  	argc -= optind; | ||||||
|  |  	argv += optind; | ||||||
|  |   | ||||||
|  | -	if (argc != 1)
 | ||||||
|  | -		errx (2, "specify one user name to delete");
 | ||||||
|  | +	if (argc != 1) {
 | ||||||
|  | +		warnx ("specify one user name to delete");
 | ||||||
|  | +		return 2;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	entry = adcli_entry_new_user (conn, argv[0]); | ||||||
|  | -	if (entry == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	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) { | ||||||
|  | -		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't connect to %s domain: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_entry_unref (entry);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	res = adcli_entry_delete (entry); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "deleting user %s in domain %s failed: %s",
 | ||||||
|  | -		      adcli_entry_get_sam_name (entry),
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("deleting 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); | ||||||
|  | @@ -404,29 +425,41 @@ adcli_tool_group_create (adcli_conn *conn,
 | ||||||
|  |  	argc -= optind; | ||||||
|  |  	argv += optind; | ||||||
|  |   | ||||||
|  | -	if (argc != 1)
 | ||||||
|  | -		errx (2, "specify one group to create");
 | ||||||
|  | +	if (argc != 1) {
 | ||||||
|  | +		warnx ("specify one group to create");
 | ||||||
|  | +		adcli_attrs_free (attrs);
 | ||||||
|  | +		return 2;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	entry = adcli_entry_new_group (conn, argv[0]); | ||||||
|  | -	if (entry == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	if (entry == NULL) {
 | ||||||
|  | +		warnx ("unexpected memory problems");
 | ||||||
|  | +		adcli_attrs_free (attrs);
 | ||||||
|  | +		return -1;
 | ||||||
|  | +	}
 | ||||||
|  |  	adcli_entry_set_domain_ou (entry, ou); | ||||||
|  |   | ||||||
|  |  	adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT); | ||||||
|  |   | ||||||
|  |  	res = adcli_conn_connect (conn); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "couldn't connect to domain %s: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't connect to domain %s: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_entry_unref (entry);
 | ||||||
|  | +		adcli_attrs_free (attrs);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	res = adcli_entry_create (entry, attrs); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "creating group %s in domain %s failed: %s",
 | ||||||
|  | -		      adcli_entry_get_sam_name (entry),
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("creating group %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);
 | ||||||
|  | +		adcli_attrs_free (attrs);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	adcli_entry_unref (entry); | ||||||
|  | @@ -480,28 +513,36 @@ adcli_tool_group_delete (adcli_conn *conn,
 | ||||||
|  |  	argc -= optind; | ||||||
|  |  	argv += optind; | ||||||
|  |   | ||||||
|  | -	if (argc != 1)
 | ||||||
|  | -		errx (2, "specify one group name to delete");
 | ||||||
|  | +	if (argc != 1) {
 | ||||||
|  | +		warnx ("specify one group name to delete");
 | ||||||
|  | +		return 2;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	entry = adcli_entry_new_group (conn, argv[0]); | ||||||
|  | -	if (entry == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	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) { | ||||||
|  | -		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't connect to %s domain: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_entry_unref (entry);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	res = adcli_entry_delete (entry); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "deleting group %s in domain %s failed: %s",
 | ||||||
|  | -		      adcli_entry_get_sam_name (entry),
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("deleting group %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); | ||||||
|  | @@ -509,7 +550,7 @@ adcli_tool_group_delete (adcli_conn *conn,
 | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void
 | ||||||
|  | +static int
 | ||||||
|  |  expand_user_dn_as_member (adcli_conn *conn, | ||||||
|  |                            adcli_attrs *attrs, | ||||||
|  |                            const char *user, | ||||||
|  | @@ -523,16 +564,19 @@ expand_user_dn_as_member (adcli_conn *conn,
 | ||||||
|  |   | ||||||
|  |  	res = adcli_entry_load (entry); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "couldn't lookup user %s in domain %s: %s",
 | ||||||
|  | -		      user, adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't lookup user %s in domain %s: %s",
 | ||||||
|  | +		       user, adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_entry_unref (entry);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	dn = adcli_entry_get_dn (entry); | ||||||
|  |  	if (dn == NULL) { | ||||||
|  | -		errx (-ADCLI_ERR_CONFIG,
 | ||||||
|  | -		      "couldn't found user %s in domain %s",
 | ||||||
|  | -		      user, adcli_conn_get_domain_name (conn));
 | ||||||
|  | +		warnx ("couldn't found user %s in domain %s",
 | ||||||
|  | +		       user, adcli_conn_get_domain_name (conn));
 | ||||||
|  | +		adcli_entry_unref (entry);
 | ||||||
|  | +		return -ADCLI_ERR_CONFIG;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (adding) | ||||||
|  | @@ -541,6 +585,8 @@ expand_user_dn_as_member (adcli_conn *conn,
 | ||||||
|  |  		adcli_attrs_delete1 (attrs, "member", dn); | ||||||
|  |   | ||||||
|  |  	adcli_entry_unref (entry); | ||||||
|  | +
 | ||||||
|  | +	return ADCLI_SUCCESS;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int | ||||||
|  | @@ -590,33 +636,48 @@ adcli_tool_member_add (adcli_conn *conn,
 | ||||||
|  |  	argc -= optind; | ||||||
|  |  	argv += optind; | ||||||
|  |   | ||||||
|  | -	if (argc < 2)
 | ||||||
|  | -		errx (2, "specify a group name and a user to add");
 | ||||||
|  | +	if (argc < 2) {
 | ||||||
|  | +		warnx ("specify a group name and a user to add");
 | ||||||
|  | +		return 2;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	entry = adcli_entry_new_group (conn, argv[0]); | ||||||
|  | -	if (entry == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	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) { | ||||||
|  | -		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't connect to %s domain: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_entry_unref (entry);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	attrs = adcli_attrs_new (); | ||||||
|  |   | ||||||
|  | -	for (i = 1; i < argc; i++)
 | ||||||
|  | -		expand_user_dn_as_member (conn, attrs, argv[i], 1);
 | ||||||
|  | +	for (i = 1; i < argc; i++) {
 | ||||||
|  | +		res = expand_user_dn_as_member (conn, attrs, argv[i], 1);
 | ||||||
|  | +		if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +			adcli_attrs_free (attrs);
 | ||||||
|  | +			adcli_entry_unref (entry);
 | ||||||
|  | +			return res;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	res = adcli_entry_modify (entry, attrs); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "adding member(s) to group %s in domain %s failed: %s",
 | ||||||
|  | -		      adcli_entry_get_sam_name (entry),
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("adding member(s) to group %s in domain %s failed: %s",
 | ||||||
|  | +		       adcli_entry_get_sam_name (entry),
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_attrs_free (attrs);
 | ||||||
|  | +		adcli_entry_unref (entry);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	adcli_attrs_free (attrs); | ||||||
|  | @@ -672,33 +733,48 @@ adcli_tool_member_remove (adcli_conn *conn,
 | ||||||
|  |  	argc -= optind; | ||||||
|  |  	argv += optind; | ||||||
|  |   | ||||||
|  | -	if (argc < 2)
 | ||||||
|  | -		errx (2, "specify a group name and a user to remove");
 | ||||||
|  | +	if (argc < 2) {
 | ||||||
|  | +		warnx ("specify a group name and a user to remove");
 | ||||||
|  | +		return 2;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	entry = adcli_entry_new_group (conn, argv[0]); | ||||||
|  | -	if (entry == NULL)
 | ||||||
|  | -		errx (-1, "unexpected memory problems");
 | ||||||
|  | +	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) { | ||||||
|  | -		errx (-res, "couldn't connect to %s domain: %s",
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("couldn't connect to %s domain: %s",
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_entry_unref (entry);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	attrs = adcli_attrs_new (); | ||||||
|  |   | ||||||
|  | -	for (i = 1; i < argc; i++)
 | ||||||
|  | -		expand_user_dn_as_member (conn, attrs, argv[i], 0);
 | ||||||
|  | +	for (i = 1; i < argc; i++) {
 | ||||||
|  | +		res = expand_user_dn_as_member (conn, attrs, argv[i], 0);
 | ||||||
|  | +		if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +			adcli_attrs_free (attrs);
 | ||||||
|  | +			adcli_entry_unref (entry);
 | ||||||
|  | +			return res;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	res = adcli_entry_modify (entry, attrs); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -		errx (-res, "adding member(s) to group %s in domain %s failed: %s",
 | ||||||
|  | -		      adcli_entry_get_sam_name (entry),
 | ||||||
|  | -		      adcli_conn_get_domain_name (conn),
 | ||||||
|  | -		      adcli_get_last_error ());
 | ||||||
|  | +		warnx ("adding member(s) to group %s in domain %s failed: %s",
 | ||||||
|  | +		       adcli_entry_get_sam_name (entry),
 | ||||||
|  | +		       adcli_conn_get_domain_name (conn),
 | ||||||
|  | +		       adcli_get_last_error ());
 | ||||||
|  | +		adcli_attrs_free (attrs);
 | ||||||
|  | +		adcli_entry_unref (entry);
 | ||||||
|  | +		return -res;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	adcli_attrs_free (attrs); | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										57
									
								
								0003-Do-not-add-service-principals-twice.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								0003-Do-not-add-service-principals-twice.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | From f05adc23d5cc9f1dfa5638e31949dcd81d632df9 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 13 Aug 2018 17:32:24 +0200 | ||||||
|  | Subject: [PATCH 3/4] Do not add service principals twice | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 23 +++++++++++++++++++---- | ||||||
|  |  1 file changed, 19 insertions(+), 4 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index c4ba537..bb50365 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -313,6 +313,7 @@ add_service_names_to_service_principals (adcli_enroll *enroll)
 | ||||||
|  |  	char *name; | ||||||
|  |  	int length = 0; | ||||||
|  |  	int i; | ||||||
|  | +	size_t c;
 | ||||||
|  |   | ||||||
|  |  	if (enroll->service_principals != NULL) { | ||||||
|  |  		length = seq_count (enroll->service_principals); | ||||||
|  | @@ -321,14 +322,28 @@ add_service_names_to_service_principals (adcli_enroll *enroll)
 | ||||||
|  |  	for (i = 0; enroll->service_names[i] != NULL; i++) { | ||||||
|  |  		if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->computer_name) < 0) | ||||||
|  |  			return_unexpected_if_reached (); | ||||||
|  | -		enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | -			                                      name, &length);
 | ||||||
|  | +		for (c = 0; enroll->service_principals != NULL && enroll->service_principals[c] != NULL; c++) {
 | ||||||
|  | +			if (strcmp (name, enroll->service_principals[c]) == 0) {
 | ||||||
|  | +				break;
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  | +		if (enroll->service_principals == NULL || enroll->service_principals[c] == NULL) {
 | ||||||
|  | +			enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | +				                                      name, &length);
 | ||||||
|  | +		}
 | ||||||
|  |   | ||||||
|  |  		if (enroll->host_fqdn) { | ||||||
|  |  			if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->host_fqdn) < 0) | ||||||
|  |  				return_unexpected_if_reached (); | ||||||
|  | -			enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | -				                                      name, &length);
 | ||||||
|  | +			for (c = 0; enroll->service_principals != NULL && enroll->service_principals[c] != NULL; c++) {
 | ||||||
|  | +				if (strcmp (name, enroll->service_principals[c]) == 0) {
 | ||||||
|  | +					break;
 | ||||||
|  | +				}
 | ||||||
|  | +			}
 | ||||||
|  | +			if (enroll->service_principals == NULL || enroll->service_principals[c] == NULL) {
 | ||||||
|  | +				enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | +					                                      name, &length);
 | ||||||
|  | +			}
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.17.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										196
									
								
								0003-adenroll-add-adcli_enroll_get_permitted_keytab_encty.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								0003-adenroll-add-adcli_enroll_get_permitted_keytab_encty.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,196 @@ | |||||||
|  | From 0c09070e8beec734e3f0c70e14b0a04788077b73 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 13 Jun 2019 17:25:52 +0200 | ||||||
|  | Subject: [PATCH 3/4] adenroll: add adcli_enroll_get_permitted_keytab_enctypes | ||||||
|  |  with tests | ||||||
|  | 
 | ||||||
|  | The new call does not only return the current encryption types set in AD | ||||||
|  | or a default list but filters them with the list of permitted encryption | ||||||
|  | types on the client. This makes sure the client can create and use the | ||||||
|  | keys. | ||||||
|  | 
 | ||||||
|  | Related to https://gitlab.freedesktop.org/realmd/adcli/issues/3 | ||||||
|  | ---
 | ||||||
|  |  library/Makefile.am |   5 ++ | ||||||
|  |  library/adenroll.c  | 124 ++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  library/adenroll.h  |   2 + | ||||||
|  |  3 files changed, 131 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/Makefile.am b/library/Makefile.am
 | ||||||
|  | index 39e8fd1..4829555 100644
 | ||||||
|  | --- a/library/Makefile.am
 | ||||||
|  | +++ b/library/Makefile.am
 | ||||||
|  | @@ -40,6 +40,7 @@ check_PROGRAMS = \
 | ||||||
|  |  	test-util \ | ||||||
|  |  	test-ldap \ | ||||||
|  |  	test-attrs \ | ||||||
|  | +	test-adenroll \
 | ||||||
|  |  	$(NULL) | ||||||
|  |   | ||||||
|  |  test_seq_SOURCES = seq.c test.c test.h | ||||||
|  | @@ -56,6 +57,10 @@ test_attrs_SOURCES = adattrs.c $(test_ldap_SOURCES)
 | ||||||
|  |  test_attrs_CFLAGS = -DATTRS_TESTS | ||||||
|  |  test_attrs_LDADD = $(test_ldap_LDADD) | ||||||
|  |   | ||||||
|  | +test_adenroll_SOURCES = adenroll.c $(test_ldap_SOURCES)
 | ||||||
|  | +test_adenroll_CFLAGS = -DADENROLL_TESTS
 | ||||||
|  | +test_adenroll_LDADD = $(KRB5_LIBS)
 | ||||||
|  | +
 | ||||||
|  |  TESTS = $(check_PROGRAMS) | ||||||
|  |   | ||||||
|  |  MEMCHECK_ENV = $(TEST_RUNNER) valgrind --error-exitcode=80 --quiet --trace-children=yes | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index f617f28..95c07cd 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -2641,6 +2641,50 @@ adcli_enroll_get_keytab_enctypes (adcli_enroll *enroll)
 | ||||||
|  |  		return v51_earlier_enctypes; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +krb5_enctype *
 | ||||||
|  | +adcli_enroll_get_permitted_keytab_enctypes (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	krb5_enctype *cur_enctypes;
 | ||||||
|  | +	krb5_enctype *permitted_enctypes;
 | ||||||
|  | +	krb5_enctype *new_enctypes;
 | ||||||
|  | +	krb5_error_code code;
 | ||||||
|  | +	krb5_context k5;
 | ||||||
|  | +	size_t c;
 | ||||||
|  | +	size_t p;
 | ||||||
|  | +	size_t n;
 | ||||||
|  | +
 | ||||||
|  | +	return_val_if_fail (enroll != NULL, NULL);
 | ||||||
|  | +	cur_enctypes = adcli_enroll_get_keytab_enctypes (enroll);
 | ||||||
|  | +
 | ||||||
|  | +	k5 = adcli_conn_get_krb5_context (enroll->conn);
 | ||||||
|  | +	return_val_if_fail (k5 != NULL, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	code = krb5_get_permitted_enctypes (k5, &permitted_enctypes);
 | ||||||
|  | +	return_val_if_fail (code == 0, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	for (c = 0; cur_enctypes[c] != 0; c++);
 | ||||||
|  | +
 | ||||||
|  | +	new_enctypes = calloc (c + 1, sizeof (krb5_enctype));
 | ||||||
|  | +	return_val_if_fail (new_enctypes != NULL, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	n = 0;
 | ||||||
|  | +	for (c = 0; cur_enctypes[c] != 0; c++) {
 | ||||||
|  | +		for (p = 0; permitted_enctypes[p] != 0; p++) {
 | ||||||
|  | +			if (cur_enctypes[c] == permitted_enctypes[p]) {
 | ||||||
|  | +				new_enctypes[n++] = cur_enctypes[c];
 | ||||||
|  | +				break;
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  | +		if (permitted_enctypes[p] == 0) {
 | ||||||
|  | +			_adcli_info ("Encryption type [%d] not permitted.", cur_enctypes[c]);
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	krb5_free_enctypes (k5, permitted_enctypes);
 | ||||||
|  | +
 | ||||||
|  | +	return new_enctypes;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  void | ||||||
|  |  adcli_enroll_set_keytab_enctypes (adcli_enroll *enroll, | ||||||
|  |                                    krb5_enctype *value) | ||||||
|  | @@ -2833,3 +2877,83 @@ adcli_enroll_add_service_principal_to_remove (adcli_enroll *enroll,
 | ||||||
|  |  							    strdup (value), NULL); | ||||||
|  |  	return_if_fail (enroll->service_principals_to_remove != NULL); | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +#ifdef ADENROLL_TESTS
 | ||||||
|  | +
 | ||||||
|  | +#include "test.h"
 | ||||||
|  | +
 | ||||||
|  | +static void
 | ||||||
|  | +test_adcli_enroll_get_permitted_keytab_enctypes (void)
 | ||||||
|  | +{
 | ||||||
|  | +	krb5_enctype *enctypes;
 | ||||||
|  | +	krb5_error_code code;
 | ||||||
|  | +	krb5_enctype *permitted_enctypes;
 | ||||||
|  | +	krb5_enctype check_enctypes[3] = { 0 };
 | ||||||
|  | +	adcli_conn *conn;
 | ||||||
|  | +	adcli_enroll *enroll;
 | ||||||
|  | +	adcli_result res;
 | ||||||
|  | +	krb5_context k5;
 | ||||||
|  | +	size_t c;
 | ||||||
|  | +
 | ||||||
|  | +	conn = adcli_conn_new ("test.dom");
 | ||||||
|  | +	assert_ptr_not_null (conn);
 | ||||||
|  | +
 | ||||||
|  | +	enroll = adcli_enroll_new (conn);
 | ||||||
|  | +	assert_ptr_not_null (enroll);
 | ||||||
|  | +
 | ||||||
|  | +	enctypes = adcli_enroll_get_permitted_keytab_enctypes (NULL);
 | ||||||
|  | +	assert_ptr_eq (enctypes, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	/* krb5 context missing */
 | ||||||
|  | +	enctypes = adcli_enroll_get_permitted_keytab_enctypes (enroll);
 | ||||||
|  | +	assert_ptr_eq (enctypes, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	/* check that all permitted enctypes can pass */
 | ||||||
|  | +	res = _adcli_krb5_init_context (&k5);
 | ||||||
|  | +	assert_num_eq (res, ADCLI_SUCCESS);
 | ||||||
|  | +
 | ||||||
|  | +	adcli_conn_set_krb5_context (conn, k5);
 | ||||||
|  | +
 | ||||||
|  | +	code = krb5_get_permitted_enctypes (k5, &permitted_enctypes);
 | ||||||
|  | +	assert_num_eq (code, 0);
 | ||||||
|  | +	assert_ptr_not_null (permitted_enctypes);
 | ||||||
|  | +	assert_num_cmp (permitted_enctypes[0], !=, 0);
 | ||||||
|  | +
 | ||||||
|  | +	adcli_enroll_set_keytab_enctypes (enroll, permitted_enctypes);
 | ||||||
|  | +
 | ||||||
|  | +	enctypes = adcli_enroll_get_permitted_keytab_enctypes (enroll);
 | ||||||
|  | +	assert_ptr_not_null (enctypes);
 | ||||||
|  | +	for (c = 0; permitted_enctypes[c] != 0; c++) {
 | ||||||
|  | +		assert_num_eq (enctypes[c], permitted_enctypes[c]);
 | ||||||
|  | +	}
 | ||||||
|  | +	assert_num_eq (enctypes[c], 0);
 | ||||||
|  | +	krb5_free_enctypes (k5, enctypes);
 | ||||||
|  | +
 | ||||||
|  | +	/* check that ENCTYPE_UNKNOWN is filtered out */
 | ||||||
|  | +	check_enctypes[0] = permitted_enctypes[0];
 | ||||||
|  | +	check_enctypes[1] = ENCTYPE_UNKNOWN;
 | ||||||
|  | +	check_enctypes[2] = 0;
 | ||||||
|  | +	adcli_enroll_set_keytab_enctypes (enroll, check_enctypes);
 | ||||||
|  | +
 | ||||||
|  | +	enctypes = adcli_enroll_get_permitted_keytab_enctypes (enroll);
 | ||||||
|  | +	assert_ptr_not_null (enctypes);
 | ||||||
|  | +	assert_num_eq (enctypes[0], permitted_enctypes[0]);
 | ||||||
|  | +	assert_num_eq (enctypes[1], 0);
 | ||||||
|  | +	krb5_free_enctypes (k5, enctypes);
 | ||||||
|  | +
 | ||||||
|  | +	krb5_free_enctypes (k5, permitted_enctypes);
 | ||||||
|  | +
 | ||||||
|  | +	adcli_enroll_unref (enroll);
 | ||||||
|  | +	adcli_conn_unref (conn);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +int
 | ||||||
|  | +main (int argc,
 | ||||||
|  | +      char *argv[])
 | ||||||
|  | +{
 | ||||||
|  | +	test_func (test_adcli_enroll_get_permitted_keytab_enctypes,
 | ||||||
|  | +	           "/attrs/adcli_enroll_get_permitted_keytab_enctypes");
 | ||||||
|  | +	return test_run (argc, argv);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +#endif /* ADENROLL_TESTS */
 | ||||||
|  | diff --git a/library/adenroll.h b/library/adenroll.h
 | ||||||
|  | index abbbfd4..1d5d00d 100644
 | ||||||
|  | --- a/library/adenroll.h
 | ||||||
|  | +++ b/library/adenroll.h
 | ||||||
|  | @@ -138,6 +138,8 @@ krb5_enctype *     adcli_enroll_get_keytab_enctypes     (adcli_enroll *enroll);
 | ||||||
|  |  void               adcli_enroll_set_keytab_enctypes     (adcli_enroll *enroll, | ||||||
|  |                                                           krb5_enctype *enctypes); | ||||||
|  |   | ||||||
|  | +krb5_enctype *     adcli_enroll_get_permitted_keytab_enctypes (adcli_enroll *enroll);
 | ||||||
|  | +
 | ||||||
|  |  const char *       adcli_enroll_get_os_name             (adcli_enroll *enroll); | ||||||
|  |   | ||||||
|  |  void               adcli_enroll_set_os_name             (adcli_enroll *enroll, | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,26 @@ | |||||||
|  | From 85fa595baf689e85c0d897c5eef73fdf1ecc1581 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Striker Leggette <striker@redhat.com> | ||||||
|  | Date: Wed, 1 Nov 2017 11:16:39 +0100 | ||||||
|  | Subject: [PATCH 03/23] correct spelling of 'adcli_tool_computer_delete' | ||||||
|  |  description | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  tools/tools.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/tools.c b/tools/tools.c
 | ||||||
|  | index 4b243de..915130e 100644
 | ||||||
|  | --- a/tools/tools.c
 | ||||||
|  | +++ b/tools/tools.c
 | ||||||
|  | @@ -57,7 +57,7 @@ struct {
 | ||||||
|  |  	{ "update", adcli_tool_computer_update, "Update machine membership in a domain", }, | ||||||
|  |  	{ "preset-computer", adcli_tool_computer_preset, "Pre setup computers accounts", }, | ||||||
|  |  	{ "reset-computer", adcli_tool_computer_reset, "Reset a computer account", }, | ||||||
|  | -	{ "delete-computer", adcli_tool_computer_delete, "Delete a computer acocunt", },
 | ||||||
|  | +	{ "delete-computer", adcli_tool_computer_delete, "Delete a computer account", },
 | ||||||
|  |  	{ "create-user", adcli_tool_user_create, "Create a user account", }, | ||||||
|  |  	{ "delete-user", adcli_tool_user_delete, "Delete a user account", }, | ||||||
|  |  	{ "create-group", adcli_tool_group_create, "Create a group", }, | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										358
									
								
								0003-enroll-use-computer-or-service-in-debug-messages.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										358
									
								
								0003-enroll-use-computer-or-service-in-debug-messages.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,358 @@ | |||||||
|  | From eea6a8071b5e5df74808903bb15b30acf820ce3f Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 23 Oct 2020 16:55:11 +0200 | ||||||
|  | Subject: [PATCH 3/7] enroll: use 'computer' or 'service' in debug messages | ||||||
|  | 
 | ||||||
|  | Use proper account type in debug messages. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1854112 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 115 ++++++++++++++++++++++++++++----------------- | ||||||
|  |  1 file changed, 72 insertions(+), 43 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index dbfda36..9cdc79b 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -155,6 +155,12 @@ struct _adcli_enroll {
 | ||||||
|  |  	char *description; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +static const char *
 | ||||||
|  | +s_or_c (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	return enroll->is_service ? "service" : "computer";
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static void | ||||||
|  |  check_if_service (adcli_enroll *enroll, | ||||||
|  |                    LDAP *ldap, | ||||||
|  | @@ -203,13 +209,15 @@ ensure_computer_name (adcli_result res,
 | ||||||
|  |  		return res; | ||||||
|  |   | ||||||
|  |  	if (enroll->computer_name) { | ||||||
|  | -		_adcli_info ("Enrolling computer name: %s",
 | ||||||
|  | +		_adcli_info ("Enrolling %s name: %s",
 | ||||||
|  | +		             s_or_c (enroll),
 | ||||||
|  |  		             enroll->computer_name); | ||||||
|  |  		return ADCLI_SUCCESS; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (!enroll->host_fqdn) { | ||||||
|  | -		_adcli_err ("No host name from which to determine the computer name");
 | ||||||
|  | +		_adcli_err ("No host name from which to determine the %s name",
 | ||||||
|  | +		            s_or_c (enroll));
 | ||||||
|  |  		return ADCLI_ERR_CONFIG; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -603,7 +611,8 @@ lookup_computer_container (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  	} else if (ret != LDAP_SUCCESS) { | ||||||
|  |  		return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY, | ||||||
|  | -		                                   "Couldn't lookup computer container: %s", base);
 | ||||||
|  | +		                                   "Couldn't lookup %s container: %s",
 | ||||||
|  | +		                                   s_or_c (enroll), base);
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	values = _adcli_ldap_parse_values (ldap, results, attrs[0]); | ||||||
|  | @@ -614,8 +623,8 @@ lookup_computer_container (adcli_enroll *enroll,
 | ||||||
|  |  		if (strncmp (values[i], prefix, prefix_len) == 0) { | ||||||
|  |  			enroll->computer_container = strdup (values[i] + prefix_len); | ||||||
|  |  			return_unexpected_if_fail (enroll->computer_container != NULL); | ||||||
|  | -			_adcli_info ("Found well known computer container at: %s",
 | ||||||
|  | -			             enroll->computer_container);
 | ||||||
|  | +			_adcli_info ("Found well known %s container at: %s",
 | ||||||
|  | +			             s_or_c (enroll), enroll->computer_container);
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -629,8 +638,9 @@ lookup_computer_container (adcli_enroll *enroll,
 | ||||||
|  |  		if (ret == LDAP_SUCCESS) { | ||||||
|  |  			enroll->computer_container = _adcli_ldap_parse_dn (ldap, results); | ||||||
|  |  			if (enroll->computer_container) { | ||||||
|  | -				_adcli_info ("Well known computer container not "
 | ||||||
|  | +				_adcli_info ("Well known %s container not "
 | ||||||
|  |  				             "found, but found suitable one at: %s", | ||||||
|  | +				             s_or_c (enroll),
 | ||||||
|  |  				             enroll->computer_container); | ||||||
|  |  			} | ||||||
|  |  		} | ||||||
|  | @@ -646,7 +656,8 @@ lookup_computer_container (adcli_enroll *enroll,
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (!enroll->computer_container) { | ||||||
|  | -		_adcli_err ("Couldn't find location to create computer accounts");
 | ||||||
|  | +		_adcli_err ("Couldn't find location to create %s accounts",
 | ||||||
|  | +		            s_or_c (enroll));
 | ||||||
|  |  		return ADCLI_ERR_DIRECTORY; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -674,7 +685,8 @@ calculate_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	if (asprintf (&enroll->computer_dn, "CN=%s,%s", enroll->computer_name, enroll->computer_container) < 0) | ||||||
|  |  		return_unexpected_if_reached (); | ||||||
|  |   | ||||||
|  | -	_adcli_info ("Calculated computer account: %s", enroll->computer_dn);
 | ||||||
|  | +	_adcli_info ("Calculated %s account: %s",
 | ||||||
|  | +	             s_or_c (enroll), enroll->computer_dn);
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -861,7 +873,8 @@ create_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  		                                   enroll->computer_dn); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	_adcli_info ("Created computer account: %s", enroll->computer_dn);
 | ||||||
|  | +	_adcli_info ("Created %s account: %s", s_or_c (enroll),
 | ||||||
|  | +	                                       enroll->computer_dn);
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -908,17 +921,17 @@ validate_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	assert (enroll->computer_dn != NULL); | ||||||
|  |   | ||||||
|  |  	if (already_exists && !allow_overwrite) { | ||||||
|  | -		_adcli_err ("The computer account %s already exists",
 | ||||||
|  | -		            enroll->computer_name);
 | ||||||
|  | +		_adcli_err ("The %s account %s already exists",
 | ||||||
|  | +		            s_or_c (enroll), enroll->computer_name);
 | ||||||
|  |  		return ADCLI_ERR_CONFIG; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	/* Do we have an explicitly requested ou? */ | ||||||
|  |  	if (enroll->domain_ou && enroll->domain_ou_explicit && already_exists) { | ||||||
|  |  		if (!_adcli_ldap_dn_has_ancestor (enroll->computer_dn, enroll->domain_ou)) { | ||||||
|  | -			_adcli_err ("The computer account %s already exists, "
 | ||||||
|  | +			_adcli_err ("The %s account %s already exists, "
 | ||||||
|  |  			            "but is not in the desired organizational unit.", | ||||||
|  | -			            enroll->computer_name);
 | ||||||
|  | +			            s_or_c (enroll), enroll->computer_name);
 | ||||||
|  |  			return ADCLI_ERR_CONFIG; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -943,7 +956,8 @@ delete_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  		                                   "Couldn't delete computer account: %s", | ||||||
|  |  		                                   enroll->computer_dn); | ||||||
|  |  	} else { | ||||||
|  | -		_adcli_info ("Deleted computer account at: %s", enroll->computer_dn);
 | ||||||
|  | +		_adcli_info ("Deleted %s account at: %s", s_or_c (enroll),
 | ||||||
|  | +		                                          enroll->computer_dn);
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  | @@ -992,20 +1006,21 @@ locate_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  			free (enroll->computer_dn); | ||||||
|  |  			enroll->computer_dn = strdup (dn); | ||||||
|  |  			return_unexpected_if_fail (enroll->computer_dn != NULL); | ||||||
|  | -			_adcli_info ("Found computer account for %s at: %s",
 | ||||||
|  | -			             enroll->computer_sam, dn);
 | ||||||
|  | +			_adcli_info ("Found %s account for %s at: %s",
 | ||||||
|  | +			             s_or_c (enroll), enroll->computer_sam, dn);
 | ||||||
|  |  			ldap_memfree (dn); | ||||||
|  |   | ||||||
|  |  		} else { | ||||||
|  |  			ldap_msgfree (results); | ||||||
|  |  			results = NULL; | ||||||
|  | -			_adcli_info ("Computer account for %s does not exist",
 | ||||||
|  | -			             enroll->computer_sam);
 | ||||||
|  | +			_adcli_info ("A %s account for %s does not exist",
 | ||||||
|  | +			             s_or_c (enroll), enroll->computer_sam);
 | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  	} else { | ||||||
|  |  		return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY, | ||||||
|  | -		                                   "Couldn't lookup computer account: %s",
 | ||||||
|  | +		                                   "Couldn't lookup %s account: %s",
 | ||||||
|  | +		                                   s_or_c (enroll),
 | ||||||
|  |  		                                   enroll->computer_sam); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -1039,7 +1054,9 @@ load_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	if (ret == LDAP_SUCCESS) { | ||||||
|  |  		entry = ldap_first_entry (ldap, results); | ||||||
|  |  		if (entry) { | ||||||
|  | -			_adcli_info ("Found computer account for %s at: %s",
 | ||||||
|  | +			check_if_service (enroll, ldap, results);
 | ||||||
|  | +			_adcli_info ("Found %s account for %s at: %s",
 | ||||||
|  | +			             s_or_c (enroll),
 | ||||||
|  |  			             enroll->computer_sam, enroll->computer_dn); | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  | @@ -1146,7 +1163,8 @@ set_password_with_user_creds (adcli_enroll *enroll)
 | ||||||
|  |  	                                       &result_code_string, &result_string); | ||||||
|  |   | ||||||
|  |  	if (code != 0) { | ||||||
|  | -		_adcli_err ("Couldn't set password for computer account: %s: %s",
 | ||||||
|  | +		_adcli_err ("Couldn't set password for %s account: %s: %s",
 | ||||||
|  | +		            s_or_c (enroll),
 | ||||||
|  |  		            enroll->computer_sam, krb5_get_error_message (k5, code)); | ||||||
|  |  		/* TODO: Parse out these values */ | ||||||
|  |  		res = ADCLI_ERR_DIRECTORY; | ||||||
|  | @@ -1160,7 +1178,8 @@ set_password_with_user_creds (adcli_enroll *enroll)
 | ||||||
|  |  		if (result_string.length) | ||||||
|  |  			message = _adcli_str_dupn (result_string.data, result_string.length); | ||||||
|  |  #endif | ||||||
|  | -		_adcli_err ("Cannot set computer password: %.*s%s%s",
 | ||||||
|  | +		_adcli_err ("Cannot set %s password: %.*s%s%s",
 | ||||||
|  | +		            s_or_c (enroll),
 | ||||||
|  |  		            (int)result_code_string.length, result_code_string.data, | ||||||
|  |  		            message ? ": " : "", message ? message : ""); | ||||||
|  |  		res = ADCLI_ERR_CREDENTIALS; | ||||||
|  | @@ -1170,7 +1189,7 @@ set_password_with_user_creds (adcli_enroll *enroll)
 | ||||||
|  |  		free (message); | ||||||
|  |  #endif | ||||||
|  |  	} else { | ||||||
|  | -		_adcli_info ("Set computer password");
 | ||||||
|  | +		_adcli_info ("Set %s password", s_or_c (enroll));
 | ||||||
|  |  		if (enroll->kvno > 0) { | ||||||
|  |  			enroll->kvno++; | ||||||
|  |  			_adcli_info ("kvno incremented to %d", enroll->kvno); | ||||||
|  | @@ -1203,7 +1222,8 @@ set_password_with_computer_creds (adcli_enroll *enroll)
 | ||||||
|  |   | ||||||
|  |  	code = _adcli_kinit_computer_creds (enroll->conn, "kadmin/changepw", NULL, &creds); | ||||||
|  |  	if (code != 0) { | ||||||
|  | -		_adcli_err ("Couldn't get change password ticket for computer account: %s: %s",
 | ||||||
|  | +		_adcli_err ("Couldn't get change password ticket for %s account: %s: %s",
 | ||||||
|  | +		            s_or_c (enroll),
 | ||||||
|  |  		            enroll->computer_sam, krb5_get_error_message (k5, code)); | ||||||
|  |  		return ADCLI_ERR_DIRECTORY; | ||||||
|  |  	} | ||||||
|  | @@ -1214,7 +1234,8 @@ set_password_with_computer_creds (adcli_enroll *enroll)
 | ||||||
|  |  	krb5_free_cred_contents (k5, &creds); | ||||||
|  |   | ||||||
|  |  	if (code != 0) { | ||||||
|  | -		_adcli_err ("Couldn't change password for computer account: %s: %s",
 | ||||||
|  | +		_adcli_err ("Couldn't change password for %s account: %s: %s",
 | ||||||
|  | +		            s_or_c (enroll),
 | ||||||
|  |  		            enroll->computer_sam, krb5_get_error_message (k5, code)); | ||||||
|  |  		/* TODO: Parse out these values */ | ||||||
|  |  		res = ADCLI_ERR_DIRECTORY; | ||||||
|  | @@ -1284,7 +1305,8 @@ retrieve_computer_account (adcli_enroll *enroll)
 | ||||||
|  |   | ||||||
|  |  	if (ret != LDAP_SUCCESS) { | ||||||
|  |  		return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY, | ||||||
|  | -		                                   "Couldn't retrieve computer account info: %s",
 | ||||||
|  | +		                                   "Couldn't retrieve %s account info: %s",
 | ||||||
|  | +		                                   s_or_c (enroll),
 | ||||||
|  |  		                                   enroll->computer_dn); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -1294,15 +1316,15 @@ retrieve_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  		if (value != NULL) { | ||||||
|  |  			kvno = strtoul (value, &end, 10); | ||||||
|  |  			if (end == NULL || *end != '\0') { | ||||||
|  | -				_adcli_err ("Invalid kvno '%s' for computer account in directory: %s",
 | ||||||
|  | -				            value, enroll->computer_dn);
 | ||||||
|  | +				_adcli_err ("Invalid kvno '%s' for %s account in directory: %s",
 | ||||||
|  | +				            value, s_or_c (enroll), enroll->computer_dn);
 | ||||||
|  |  				res = ADCLI_ERR_DIRECTORY; | ||||||
|  |   | ||||||
|  |  			} else { | ||||||
|  |  				enroll->kvno = kvno; | ||||||
|  |   | ||||||
|  | -				_adcli_info ("Retrieved kvno '%s' for computer account in directory: %s",
 | ||||||
|  | -				             value, enroll->computer_dn);
 | ||||||
|  | +				_adcli_info ("Retrieved kvno '%s' for %s account in directory: %s",
 | ||||||
|  | +				             value, s_or_c (enroll), enroll->computer_dn);
 | ||||||
|  |  			} | ||||||
|  |   | ||||||
|  |  			free (value); | ||||||
|  | @@ -1311,8 +1333,8 @@ retrieve_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  			/* Apparently old AD didn't have this attribute, use zero */ | ||||||
|  |  			enroll->kvno = 0; | ||||||
|  |   | ||||||
|  | -			_adcli_info ("No kvno found for computer account in directory: %s",
 | ||||||
|  | -			             enroll->computer_dn);
 | ||||||
|  | +			_adcli_info ("No kvno found for %s account in directory: %s",
 | ||||||
|  | +			             s_or_c (enroll), enroll->computer_dn);
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -1353,12 +1375,14 @@ update_and_calculate_enctypes (adcli_enroll *enroll)
 | ||||||
|  |   | ||||||
|  |  	if (ret == LDAP_INSUFFICIENT_ACCESS) { | ||||||
|  |  		return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_CREDENTIALS, | ||||||
|  | -		                                   "Insufficient permissions to set encryption types on computer account: %s",
 | ||||||
|  | +		                                   "Insufficient permissions to set encryption types on %s account: %s",
 | ||||||
|  | +		                                   s_or_c (enroll),
 | ||||||
|  |  		                                   enroll->computer_dn); | ||||||
|  |   | ||||||
|  |  	} else if (ret != LDAP_SUCCESS) { | ||||||
|  |  		return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY, | ||||||
|  | -		                                   "Couldn't set encryption types on computer account: %s",
 | ||||||
|  | +		                                   "Couldn't set encryption types on %s account: %s",
 | ||||||
|  | +		                                   s_or_c (enroll),
 | ||||||
|  |  		                                   enroll->computer_dn); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -1381,13 +1405,14 @@ update_computer_attribute (adcli_enroll *enroll,
 | ||||||
|  |  	string = _adcli_ldap_mods_to_string (mods); | ||||||
|  |  	return_unexpected_if_fail (string != NULL); | ||||||
|  |   | ||||||
|  | -	_adcli_info ("Modifying computer account: %s", string);
 | ||||||
|  | +	_adcli_info ("Modifying %s account: %s", s_or_c (enroll), string);
 | ||||||
|  |   | ||||||
|  |  	ret = ldap_modify_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL); | ||||||
|  |   | ||||||
|  |  	if (ret != LDAP_SUCCESS) { | ||||||
|  | -		_adcli_warn ("Couldn't set %s on computer account: %s: %s",
 | ||||||
|  | -		             string, enroll->computer_dn, ldap_err2string (ret));
 | ||||||
|  | +		_adcli_warn ("Couldn't set %s on %s account: %s: %s",
 | ||||||
|  | +		             string, s_or_c (enroll), enroll->computer_dn,
 | ||||||
|  | +		             ldap_err2string (ret));
 | ||||||
|  |  		res = ADCLI_ERR_DIRECTORY; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -1411,8 +1436,8 @@ static char *get_user_account_control (adcli_enroll *enroll)
 | ||||||
|  |   | ||||||
|  |  		attr_val = strtoul (uac_str, &end, 10); | ||||||
|  |  		if (*end != '\0' || attr_val > UINT32_MAX) { | ||||||
|  | -			_adcli_warn ("Invalid userAccountControl '%s' for computer account in directory: %s, assuming 0",
 | ||||||
|  | -			            uac_str, enroll->computer_dn);
 | ||||||
|  | +			_adcli_warn ("Invalid userAccountControl '%s' for %s account in directory: %s, assuming 0",
 | ||||||
|  | +			            uac_str, s_or_c (enroll), enroll->computer_dn);
 | ||||||
|  |  		} else { | ||||||
|  |  			uac = attr_val; | ||||||
|  |  		} | ||||||
|  | @@ -1653,7 +1678,8 @@ load_keytab_entry (krb5_context k5,
 | ||||||
|  |  		    _adcli_str_has_suffix (name, "$") && !strchr (name, '/')) { | ||||||
|  |  			enroll->computer_name = name; | ||||||
|  |  			name[len - 1] = '\0'; | ||||||
|  | -			_adcli_info ("Found computer name in keytab: %s", name);
 | ||||||
|  | +			_adcli_info ("Found %s name in keytab: %s",
 | ||||||
|  | +			             s_or_c (enroll), name);
 | ||||||
|  |  			adcli_conn_set_computer_name (enroll->conn, | ||||||
|  |  			                              enroll->computer_name); | ||||||
|  |  			name = NULL; | ||||||
|  | @@ -2348,7 +2374,8 @@ adcli_enroll_read_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  		if (res != ADCLI_SUCCESS) | ||||||
|  |  			return res; | ||||||
|  |  		if (!enroll->computer_dn) { | ||||||
|  | -			_adcli_err ("No computer account for %s exists", enroll->computer_sam);
 | ||||||
|  | +			_adcli_err ("No %s account for %s exists",
 | ||||||
|  | +			            s_or_c (enroll), enroll->computer_sam);
 | ||||||
|  |  			return ADCLI_ERR_CONFIG; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -2460,7 +2487,8 @@ adcli_enroll_delete (adcli_enroll *enroll,
 | ||||||
|  |  		if (res != ADCLI_SUCCESS) | ||||||
|  |  			return res; | ||||||
|  |  		if (!enroll->computer_dn) { | ||||||
|  | -			_adcli_err ("No computer account for %s exists",
 | ||||||
|  | +			_adcli_err ("No %s account for %s exists",
 | ||||||
|  | +			            s_or_c (enroll),
 | ||||||
|  |  			            enroll->computer_sam); | ||||||
|  |  			return ADCLI_ERR_CONFIG; | ||||||
|  |  		} | ||||||
|  | @@ -2503,7 +2531,8 @@ adcli_enroll_password (adcli_enroll *enroll,
 | ||||||
|  |  		if (res != ADCLI_SUCCESS) | ||||||
|  |  			return res; | ||||||
|  |  		if (!enroll->computer_dn) { | ||||||
|  | -			_adcli_err ("No computer account for %s exists",
 | ||||||
|  | +			_adcli_err ("No %s account for %s exists",
 | ||||||
|  | +			            s_or_c (enroll),
 | ||||||
|  |  			            enroll->computer_sam); | ||||||
|  |  			return ADCLI_ERR_CONFIG; | ||||||
|  |  		} | ||||||
|  | -- 
 | ||||||
|  | 2.28.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										366
									
								
								0003-entry-add-passwd-user-sub-command.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										366
									
								
								0003-entry-add-passwd-user-sub-command.patch
									
									
									
									
									
										Normal file
									
								
							| @ -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/3] 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 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | From 10a4dbb5978b6f05cf75f820d97da908e735ace8 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 22 Mar 2019 10:37:11 +0100 | ||||||
|  | Subject: [PATCH 3/4] library: _adcli_krb5_build_principal allow principals as | ||||||
|  |  names | ||||||
|  | 
 | ||||||
|  | Make _adcli_krb5_build_principal a bit more robust by checking if the | ||||||
|  | given name already contains a realm suffix. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1630187 | ||||||
|  | ---
 | ||||||
|  |  library/adkrb5.c | 12 ++++++++---- | ||||||
|  |  1 file changed, 8 insertions(+), 4 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adkrb5.c b/library/adkrb5.c
 | ||||||
|  | index 7f77373..da835d7 100644
 | ||||||
|  | --- a/library/adkrb5.c
 | ||||||
|  | +++ b/library/adkrb5.c
 | ||||||
|  | @@ -41,12 +41,16 @@ _adcli_krb5_build_principal (krb5_context k5,
 | ||||||
|  |                               krb5_principal *principal) | ||||||
|  |  { | ||||||
|  |  	krb5_error_code code; | ||||||
|  | -	char *name;
 | ||||||
|  | +	char *name = NULL;
 | ||||||
|  |   | ||||||
|  | -	if (asprintf (&name, "%s@%s", user, realm) < 0)
 | ||||||
|  | -		return_val_if_reached (ENOMEM);
 | ||||||
|  | +	/* Use user if user contains a @-character and add @realm otherwise */
 | ||||||
|  | +	if (strchr (user, '@') == NULL) {
 | ||||||
|  | +		if (asprintf (&name, "%s@%s", user, realm) < 0) {
 | ||||||
|  | +			return_val_if_reached (ENOMEM);
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  | -	code = krb5_parse_name (k5, name, principal);
 | ||||||
|  | +	code = krb5_parse_name (k5, name != NULL ? name : user, principal);
 | ||||||
|  |  	return_val_if_fail (code == 0, code); | ||||||
|  |   | ||||||
|  |  	free (name); | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										53
									
								
								0003-tools-remove-errx-from-info-commands.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								0003-tools-remove-errx-from-info-commands.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | |||||||
|  | From 4794812cc98c8783921f534d20dae8b44f3826d2 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 15 Apr 2019 17:57:37 +0200 | ||||||
|  | Subject: [PATCH 3/7] tools: remove errx from info commands | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596 | ||||||
|  | ---
 | ||||||
|  |  tools/info.c | 21 ++++++++++++++------- | ||||||
|  |  1 file changed, 14 insertions(+), 7 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/info.c b/tools/info.c
 | ||||||
|  | index e7e20ad..c63e0ff 100644
 | ||||||
|  | --- a/tools/info.c
 | ||||||
|  | +++ b/tools/info.c
 | ||||||
|  | @@ -162,21 +162,28 @@ adcli_tool_info (adcli_conn *unused,
 | ||||||
|  |   | ||||||
|  |  	if (argc == 1) | ||||||
|  |  		domain = argv[0]; | ||||||
|  | -	else if (argc != 0)
 | ||||||
|  | -		errx (2, "specify one user name to create");
 | ||||||
|  | +	else if (argc != 0) {
 | ||||||
|  | +		warnx ("specify one user name to create");
 | ||||||
|  | +		return 2;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	if (server) { | ||||||
|  |  		adcli_disco_host (server, &disco); | ||||||
|  | -		if (disco == NULL)
 | ||||||
|  | -			errx (1, "couldn't discover domain controller: %s", server);
 | ||||||
|  | +		if (disco == NULL) {
 | ||||||
|  | +			warnx ("couldn't discover domain controller: %s", server);
 | ||||||
|  | +			return 1;
 | ||||||
|  | +		}
 | ||||||
|  |  		for_host = 1; | ||||||
|  |  	} else if (domain) { | ||||||
|  |  		adcli_disco_domain (domain, &disco); | ||||||
|  | -		if (disco == NULL)
 | ||||||
|  | -			errx (1, "couldn't discover domain: %s", domain);
 | ||||||
|  | +		if (disco == NULL) {
 | ||||||
|  | +			warnx ("couldn't discover domain: %s", domain);
 | ||||||
|  | +			return 1;
 | ||||||
|  | +		}
 | ||||||
|  |  		for_host = 0; | ||||||
|  |  	} else { | ||||||
|  | -		errx (2, "specify a domain to discover");
 | ||||||
|  | +		warnx ("specify a domain to discover");
 | ||||||
|  | +		return 2;
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	print_info (disco, for_host); | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										27
									
								
								0004-Do-not-depend-on-default_realm-in-krb5.conf.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								0004-Do-not-depend-on-default_realm-in-krb5.conf.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | From 8f726817b9ff643a382fa12ea9ff489cd5ab9068 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 13 Aug 2018 18:24:58 +0200 | ||||||
|  | Subject: [PATCH 4/4] Do not depend on default_realm in krb5.conf | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 4 +++- | ||||||
|  |  1 file changed, 3 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index bb50365..02bd9e3 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -1661,7 +1661,9 @@ remove_principal_from_keytab (adcli_enroll *enroll,
 | ||||||
|  |  	krb5_principal principal; | ||||||
|  |  	match_principal_kvno closure; | ||||||
|  |   | ||||||
|  | -	code = krb5_parse_name (k5, principal_name, &principal);
 | ||||||
|  | +	code = _adcli_krb5_build_principal (k5, principal_name,
 | ||||||
|  | +	                                    adcli_conn_get_domain_realm (enroll->conn),
 | ||||||
|  | +	                                    &principal);
 | ||||||
|  |  	if (code != 0) { | ||||||
|  |  		_adcli_err ("Couldn't parse principal: %s: %s", | ||||||
|  |  		            principal_name, krb5_get_error_message (k5, code)); | ||||||
|  | -- 
 | ||||||
|  | 2.17.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										103
									
								
								0004-adenroll-use-only-enctypes-permitted-by-Kerberos-con.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								0004-adenroll-use-only-enctypes-permitted-by-Kerberos-con.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | From cc3ef52884a48863a81acbfc741735fe09cd85f7 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 13 Jun 2019 18:27:49 +0200 | ||||||
|  | Subject: [PATCH 4/4] adenroll: use only enctypes permitted by Kerberos config | ||||||
|  | 
 | ||||||
|  | Realted to https://gitlab.freedesktop.org/realmd/adcli/issues/3 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml      | 10 ++++++++++ | ||||||
|  |  library/adenroll.c | 22 +++++++++++++++++++--- | ||||||
|  |  2 files changed, 29 insertions(+), 3 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index 9605b4a..094f577 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -342,6 +342,11 @@ Password for Administrator:
 | ||||||
|  |  		</varlistentry> | ||||||
|  |  	</variablelist> | ||||||
|  |   | ||||||
|  | +	<para>If supported on the AD side the
 | ||||||
|  | +	<option>msDS-supportedEncryptionTypes</option> attribute will be set as
 | ||||||
|  | +	well. Either the current value or the default list of AD's supported
 | ||||||
|  | +	encryption types filtered by the permitted encryption types of the
 | ||||||
|  | +	client's Kerberos configuration are written.</para>
 | ||||||
|  |  </refsect1> | ||||||
|  |   | ||||||
|  |  <refsect1 id='updating'> | ||||||
|  | @@ -475,6 +480,11 @@ $ adcli update --login-ccache=/tmp/krbcc_123
 | ||||||
|  |  		</varlistentry> | ||||||
|  |  	</variablelist> | ||||||
|  |   | ||||||
|  | +	<para>If supported on the AD side the
 | ||||||
|  | +	<option>msDS-supportedEncryptionTypes</option> attribute will be set as
 | ||||||
|  | +	well. Either the current value or the default list of AD's supported
 | ||||||
|  | +	encryption types filtered by the permitted encryption types of the
 | ||||||
|  | +	client's Kerberos configuration are written.</para>
 | ||||||
|  |  </refsect1> | ||||||
|  |   | ||||||
|  |  <refsect1 id='testjoin'> | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 95c07cd..53cd812 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -639,6 +639,7 @@ calculate_enctypes (adcli_enroll *enroll, char **enctype)
 | ||||||
|  |  { | ||||||
|  |  	char *value = NULL; | ||||||
|  |  	krb5_enctype *read_enctypes; | ||||||
|  | +	krb5_enctype *new_enctypes;
 | ||||||
|  |  	char *new_value = NULL; | ||||||
|  |  	int is_2008_or_later; | ||||||
|  |  	LDAP *ldap; | ||||||
|  | @@ -685,7 +686,14 @@ calculate_enctypes (adcli_enroll *enroll, char **enctype)
 | ||||||
|  |  		value = _adcli_krb5_format_enctypes (v51_earlier_enctypes); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	new_value = _adcli_krb5_format_enctypes (adcli_enroll_get_keytab_enctypes (enroll));
 | ||||||
|  | +	new_enctypes = adcli_enroll_get_permitted_keytab_enctypes (enroll);
 | ||||||
|  | +	if (new_enctypes == NULL) {
 | ||||||
|  | +		_adcli_warn ("No permitted encryption type found.");
 | ||||||
|  | +		return ADCLI_ERR_UNEXPECTED;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	new_value = _adcli_krb5_format_enctypes (new_enctypes);
 | ||||||
|  | +	krb5_free_enctypes (adcli_conn_get_krb5_context (enroll->conn), new_enctypes);
 | ||||||
|  |  	if (new_value == NULL) { | ||||||
|  |  		free (value); | ||||||
|  |  		_adcli_warn ("The encryption types desired are not available in active directory"); | ||||||
|  | @@ -1758,7 +1766,11 @@ add_principal_to_keytab (adcli_enroll *enroll,
 | ||||||
|  |  		             enroll->keytab_name); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	enctypes = adcli_enroll_get_keytab_enctypes (enroll);
 | ||||||
|  | +	enctypes = adcli_enroll_get_permitted_keytab_enctypes (enroll);
 | ||||||
|  | +	if (enctypes == NULL) {
 | ||||||
|  | +		_adcli_warn ("No permitted encryption type found.");
 | ||||||
|  | +		return ADCLI_ERR_UNEXPECTED;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	if (flags & ADCLI_ENROLL_PASSWORD_VALID) { | ||||||
|  |  		code = _adcli_krb5_keytab_copy_entries (k5, enroll->keytab, principal, | ||||||
|  | @@ -1774,7 +1786,10 @@ add_principal_to_keytab (adcli_enroll *enroll,
 | ||||||
|  |  		 */ | ||||||
|  |   | ||||||
|  |  		salts = build_principal_salts (enroll, k5, principal); | ||||||
|  | -		return_unexpected_if_fail (salts != NULL);
 | ||||||
|  | +		if (salts == NULL) {
 | ||||||
|  | +			krb5_free_enctypes (k5, enctypes);
 | ||||||
|  | +			return ADCLI_ERR_UNEXPECTED;
 | ||||||
|  | +		}
 | ||||||
|  |   | ||||||
|  |  		if (*which_salt < 0) { | ||||||
|  |  			code = _adcli_krb5_keytab_discover_salt (k5, principal, enroll->kvno, &password, | ||||||
|  | @@ -1794,6 +1809,7 @@ add_principal_to_keytab (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  		free_principal_salts (k5, salts); | ||||||
|  |  	} | ||||||
|  | +	krb5_free_enctypes (k5, enctypes);
 | ||||||
|  |   | ||||||
|  |  	if (code != 0) { | ||||||
|  |  		_adcli_err ("Couldn't add keytab entries: %s: %s", | ||||||
|  | -- 
 | ||||||
|  | 2.21.0 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,37 @@ | |||||||
|  | From c3ec5121c1e79344ce615612ab3b576bc4745acb Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 1 Nov 2017 12:01:18 +0100 | ||||||
|  | Subject: [PATCH 04/23] doc: explain that all credential cache types are | ||||||
|  |  supported | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml | 12 ++++++++---- | ||||||
|  |  1 file changed, 8 insertions(+), 4 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index e18ba5d..c54cc1b 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -118,11 +118,15 @@
 | ||||||
|  |  			is automatically discovered.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  | -			<term><option>-C, --login-ccache=<parameter>/path/to/file</parameter></option></term>
 | ||||||
|  | +			<term><option>-C, --login-ccache=<parameter>ccache_name</parameter></option></term>
 | ||||||
|  |  			<listitem><para>Use the specified kerberos credential | ||||||
|  | -			cache to authenticate with the domain. If no file is specified or
 | ||||||
|  | -			<option>-C</option> is used, then the default kerberos credential cache will
 | ||||||
|  | -			be used.</para></listitem>
 | ||||||
|  | +                        cache to authenticate with the domain. If no credential
 | ||||||
|  | +                        cache is specified, the default kerberos credential
 | ||||||
|  | +                        cache will be used. Credential caches of type FILE can
 | ||||||
|  | +                        be given with the path to the file. For other
 | ||||||
|  | +                        credential cache types, e.g. DIR, KEYRING or KCM, the
 | ||||||
|  | +                        type must be specified explicitly together with a
 | ||||||
|  | +                        suitable identifier.</para></listitem>
 | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-U, --login-user=<parameter>User</parameter></option></term> | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										77
									
								
								0004-enroll-more-filters-for-random-characters.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								0004-enroll-more-filters-for-random-characters.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | |||||||
|  | From 2750f536ac6746756335eec8332060d2365a4126 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 27 Oct 2020 14:44:07 +0100 | ||||||
|  | Subject: [PATCH 4/7] enroll: more filters for random characters | ||||||
|  | 
 | ||||||
|  | Make handling of random strings more flexible. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1854112 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 30 +++++++++++++++++++++++++++--- | ||||||
|  |  1 file changed, 27 insertions(+), 3 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 9cdc79b..44383cc 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -259,6 +259,29 @@ ensure_computer_sam (adcli_result res,
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +typedef int (rand_filter) (char *password, int length);
 | ||||||
|  | +
 | ||||||
|  | +static int
 | ||||||
|  | +filter_sam_chars (char *password,
 | ||||||
|  | +                       int length)
 | ||||||
|  | +{
 | ||||||
|  | +	int i, j;
 | ||||||
|  | +
 | ||||||
|  | +	/*
 | ||||||
|  | +	 * There are a couple of restrictions for characters in the
 | ||||||
|  | +	 * sAMAccountName attribute value, for our purpose (random suffix)
 | ||||||
|  | +	 * letters and numbers are sufficient.
 | ||||||
|  | +	 */
 | ||||||
|  | +	for (i = 0, j = 0; i < length; i++) {
 | ||||||
|  | +		if (password[i] >= 48 && password[i] <= 122 &&
 | ||||||
|  | +		    isalnum (password[i]))
 | ||||||
|  | +			password[j++] = password[i];
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	/* return the number of valid characters remaining */
 | ||||||
|  | +	return j;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static int | ||||||
|  |  filter_password_chars (char *password, | ||||||
|  |                         int length) | ||||||
|  | @@ -283,7 +306,8 @@ filter_password_chars (char *password,
 | ||||||
|  |   | ||||||
|  |  static char * | ||||||
|  |  generate_host_password  (adcli_enroll *enroll, | ||||||
|  | -                         size_t length)
 | ||||||
|  | +                         size_t length,
 | ||||||
|  | +                         rand_filter *filter)
 | ||||||
|  |  { | ||||||
|  |  	char *password; | ||||||
|  |  	krb5_context k5; | ||||||
|  | @@ -305,7 +329,7 @@ generate_host_password  (adcli_enroll *enroll,
 | ||||||
|  |  		code = krb5_c_random_make_octets (k5, &buffer); | ||||||
|  |  		return_val_if_fail (code == 0, NULL); | ||||||
|  |   | ||||||
|  | -		at += filter_password_chars (buffer.data, buffer.length);
 | ||||||
|  | +		at += filter (buffer.data, buffer.length);
 | ||||||
|  |  		assert (at <= length); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -333,7 +357,7 @@ ensure_computer_password (adcli_result res,
 | ||||||
|  |  		_adcli_info ("Using default reset computer password"); | ||||||
|  |   | ||||||
|  |  	} else { | ||||||
|  | -		enroll->computer_password = generate_host_password (enroll, length);
 | ||||||
|  | +		enroll->computer_password = generate_host_password (enroll, length, filter_password_chars);
 | ||||||
|  |  		return_unexpected_if_fail (enroll->computer_password != NULL); | ||||||
|  |  		_adcli_info ("Generated %d character computer password", length); | ||||||
|  |  	} | ||||||
|  | -- 
 | ||||||
|  | 2.28.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										82
									
								
								0004-library-make-sure-server-side-SPNs-are-preserved.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								0004-library-make-sure-server-side-SPNs-are-preserved.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | |||||||
|  | From 972f1a2f35829ed89f5353bd204683aa9ad6a2d2 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 22 Mar 2019 10:37:57 +0100 | ||||||
|  | Subject: [PATCH 4/4] library: make sure server side SPNs are preserved | ||||||
|  | 
 | ||||||
|  | adcli should not delete service principal names (SPNs) unexpectedly. If | ||||||
|  | a SPN was added on the server while presetting a host or updating an | ||||||
|  | existing entry and upcoming adcli join or update should preserver this | ||||||
|  | change. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1630187 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  1 file changed, 46 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 48cb4cf..1cce86a 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -1961,6 +1961,47 @@ adcli_enroll_prepare (adcli_enroll *enroll,
 | ||||||
|  |  	return res; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static adcli_result
 | ||||||
|  | +add_server_side_service_principals (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	char **spn_list;
 | ||||||
|  | +	LDAP *ldap;
 | ||||||
|  | +	size_t c;
 | ||||||
|  | +	int length = 0;
 | ||||||
|  | +	adcli_result res;
 | ||||||
|  | +
 | ||||||
|  | +	ldap = adcli_conn_get_ldap_connection (enroll->conn);
 | ||||||
|  | +	assert (ldap != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	spn_list = _adcli_ldap_parse_values (ldap, enroll->computer_attributes,
 | ||||||
|  | +	                                     "servicePrincipalName");
 | ||||||
|  | +	if (spn_list == NULL) {
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (enroll->service_principals != NULL) {
 | ||||||
|  | +		length = seq_count (enroll->service_principals);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	for (c = 0; spn_list[c] != NULL; c++) {
 | ||||||
|  | +		_adcli_info ("Checking %s", spn_list[c]);
 | ||||||
|  | +		if (!_adcli_strv_has_ex (enroll->service_principals_to_remove, spn_list[c], strcasecmp)) {
 | ||||||
|  | +			enroll->service_principals = _adcli_strv_add_unique (enroll->service_principals,
 | ||||||
|  | +		                                                             spn_list[c], &length, false);
 | ||||||
|  | +			assert (enroll->service_principals != NULL);
 | ||||||
|  | +			_adcli_info ("   Added %s", spn_list[c]);
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +	_adcli_strv_free (spn_list);
 | ||||||
|  | +
 | ||||||
|  | +	res = ensure_keytab_principals (ADCLI_SUCCESS, enroll);
 | ||||||
|  | +	if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +		return res;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return ADCLI_SUCCESS;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static adcli_result | ||||||
|  |  enroll_join_or_update_tasks (adcli_enroll *enroll, | ||||||
|  |  		             adcli_enroll_flags flags) | ||||||
|  | @@ -2019,6 +2060,11 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
 | ||||||
|  |  	update_and_calculate_enctypes (enroll); | ||||||
|  |  	update_computer_account (enroll); | ||||||
|  |   | ||||||
|  | +	res = add_server_side_service_principals (enroll);
 | ||||||
|  | +	if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +		return res;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	/* service_names is only set from input on the command line, so no | ||||||
|  |  	 * additional check for explicit is needed here */ | ||||||
|  |  	if (enroll->service_names != NULL) { | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										42
									
								
								0004-tools-remove-errx-from-adcli_read_password_func.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								0004-tools-remove-errx-from-adcli_read_password_func.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | From 251d7d0c71226afb8e51f7bc5794a7a3164f5a20 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 15 Apr 2019 17:59:17 +0200 | ||||||
|  | Subject: [PATCH 4/7] tools: remove errx from adcli_read_password_func | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596 | ||||||
|  | ---
 | ||||||
|  |  tools/tools.c | 11 ++++++++--- | ||||||
|  |  1 file changed, 8 insertions(+), 3 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/tools.c b/tools/tools.c
 | ||||||
|  | index c4e2851..bdf6d38 100644
 | ||||||
|  | --- a/tools/tools.c
 | ||||||
|  | +++ b/tools/tools.c
 | ||||||
|  | @@ -247,7 +247,9 @@ adcli_read_password_func (adcli_login_type login_type,
 | ||||||
|  |  		if (res < 0) { | ||||||
|  |  			if (errno == EAGAIN || errno == EINTR) | ||||||
|  |  				continue; | ||||||
|  | -			err (EFAIL, "couldn't read password from stdin");
 | ||||||
|  | +			warn ("couldn't read password from stdin");
 | ||||||
|  | +			free (buffer);
 | ||||||
|  | +			return NULL;
 | ||||||
|  |   | ||||||
|  |  		} else if (res == 0) { | ||||||
|  |  			buffer[offset] = '\0'; | ||||||
|  | @@ -261,8 +263,11 @@ adcli_read_password_func (adcli_login_type login_type,
 | ||||||
|  |  			return buffer; | ||||||
|  |   | ||||||
|  |  		} else { | ||||||
|  | -			if (memchr (buffer + offset, 0, res))
 | ||||||
|  | -				errx (EUSAGE, "unsupported null character present in password");
 | ||||||
|  | +			if (memchr (buffer + offset, 0, res)) {
 | ||||||
|  | +				warnx ("unsupported null character present in password");
 | ||||||
|  | +				free (buffer);
 | ||||||
|  | +				return NULL;
 | ||||||
|  | +			}
 | ||||||
|  |  			offset += res; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,91 @@ | |||||||
|  | From 81c98e367ba4bc8d77668acd31e462ad31cf12be Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 27 Oct 2020 14:47:31 +0100 | ||||||
|  | Subject: [PATCH 5/7] enroll: make adcli_enroll_add_keytab_for_service_account | ||||||
|  |  public | ||||||
|  | 
 | ||||||
|  | Determine keytab name more early to catch errors more early. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1854112 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 13 +++++++------ | ||||||
|  |  library/adenroll.h |  2 ++ | ||||||
|  |  tools/computer.c   |  6 ++++++ | ||||||
|  |  3 files changed, 15 insertions(+), 6 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 44383cc..05bb085 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -2276,9 +2276,10 @@ adcli_enroll_add_description_for_service_account (adcli_enroll *enroll)
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static adcli_result
 | ||||||
|  | +adcli_result
 | ||||||
|  |  adcli_enroll_add_keytab_for_service_account (adcli_enroll *enroll) | ||||||
|  |  { | ||||||
|  | +	adcli_result res;
 | ||||||
|  |  	krb5_context k5; | ||||||
|  |  	krb5_error_code code; | ||||||
|  |  	char def_keytab_name[MAX_KEYTAB_NAME_LEN]; | ||||||
|  | @@ -2286,11 +2287,14 @@ adcli_enroll_add_keytab_for_service_account (adcli_enroll *enroll)
 | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  |  	if (adcli_enroll_get_keytab_name (enroll) == NULL) { | ||||||
|  | -		k5 = adcli_conn_get_krb5_context (enroll->conn);
 | ||||||
|  | -		return_unexpected_if_fail (k5 != NULL);
 | ||||||
|  | +		res = _adcli_krb5_init_context (&k5);
 | ||||||
|  | +		if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +			return res;
 | ||||||
|  | +		}
 | ||||||
|  |   | ||||||
|  |  		code = krb5_kt_default_name (k5, def_keytab_name, | ||||||
|  |  		                             sizeof (def_keytab_name)); | ||||||
|  | +		krb5_free_context (k5);
 | ||||||
|  |  		return_unexpected_if_fail (code == 0); | ||||||
|  |   | ||||||
|  |  		lc_dom_name = strdup (adcli_conn_get_domain_name (enroll->conn)); | ||||||
|  | @@ -2326,9 +2330,6 @@ adcli_enroll_join (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  	if (enroll->is_service) { | ||||||
|  |  		res = adcli_enroll_add_description_for_service_account (enroll); | ||||||
|  | -		if (res == ADCLI_SUCCESS) {
 | ||||||
|  | -			res = adcli_enroll_add_keytab_for_service_account (enroll);
 | ||||||
|  | -		}
 | ||||||
|  |  	} else { | ||||||
|  |  		res = ensure_default_service_names (enroll); | ||||||
|  |  	} | ||||||
|  | diff --git a/library/adenroll.h b/library/adenroll.h
 | ||||||
|  | index 7765ed4..11a30c8 100644
 | ||||||
|  | --- a/library/adenroll.h
 | ||||||
|  | +++ b/library/adenroll.h
 | ||||||
|  | @@ -146,6 +146,8 @@ const char *       adcli_enroll_get_keytab_name         (adcli_enroll *enroll);
 | ||||||
|  |  void               adcli_enroll_set_keytab_name         (adcli_enroll *enroll, | ||||||
|  |                                                           const char *value); | ||||||
|  |   | ||||||
|  | +adcli_result       adcli_enroll_add_keytab_for_service_account (adcli_enroll *enroll);
 | ||||||
|  | +
 | ||||||
|  |  krb5_enctype *     adcli_enroll_get_keytab_enctypes     (adcli_enroll *enroll); | ||||||
|  |   | ||||||
|  |  void               adcli_enroll_set_keytab_enctypes     (adcli_enroll *enroll, | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index 63fd374..98a0472 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -1166,6 +1166,12 @@ adcli_tool_computer_managed_service_account (adcli_conn *conn,
 | ||||||
|  |   | ||||||
|  |  	adcli_enroll_set_is_service (enroll, true); | ||||||
|  |  	adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT); | ||||||
|  | +	res = adcli_enroll_add_keytab_for_service_account (enroll);
 | ||||||
|  | +	if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +		warnx ("Failed to set domain specific keytab name");
 | ||||||
|  | +		adcli_enroll_unref (enroll);
 | ||||||
|  | +		return 2;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	res = adcli_enroll_load (enroll); | ||||||
|  |  	if (res != ADCLI_SUCCESS) { | ||||||
|  | -- 
 | ||||||
|  | 2.28.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										38
									
								
								0005-library-add-adcli_conn_is_writeable.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								0005-library-add-adcli_conn_is_writeable.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | From d2cdc54b0e51436c30ffaf19b0530aa446440367 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 1 Nov 2017 16:29:19 +0100 | ||||||
|  | Subject: [PATCH 05/23] library: add adcli_conn_is_writeable() | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  library/adconn.c | 6 ++++++ | ||||||
|  |  library/adconn.h | 2 ++ | ||||||
|  |  2 files changed, 8 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adconn.c b/library/adconn.c
 | ||||||
|  | index a294dfd..67bdfd9 100644
 | ||||||
|  | --- a/library/adconn.c
 | ||||||
|  | +++ b/library/adconn.c
 | ||||||
|  | @@ -1528,3 +1528,9 @@ adcli_conn_server_has_capability (adcli_conn *conn,
 | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +bool adcli_conn_is_writeable (adcli_conn *conn)
 | ||||||
|  | +{
 | ||||||
|  | +    disco_dance_if_necessary (conn);
 | ||||||
|  | +    return ( (conn->domain_disco->flags & ADCLI_DISCO_WRITABLE) != 0);
 | ||||||
|  | +}
 | ||||||
|  | diff --git a/library/adconn.h b/library/adconn.h
 | ||||||
|  | index a0cb1f8..ed1cc58 100644
 | ||||||
|  | --- a/library/adconn.h
 | ||||||
|  | +++ b/library/adconn.h
 | ||||||
|  | @@ -144,4 +144,6 @@ void                adcli_conn_set_krb5_conf_dir     (adcli_conn *conn,
 | ||||||
|  |  int                 adcli_conn_server_has_capability (adcli_conn *conn, | ||||||
|  |                                                        const char *capability); | ||||||
|  |   | ||||||
|  | +bool                adcli_conn_is_writeable          (adcli_conn *conn);
 | ||||||
|  | +
 | ||||||
|  |  #endif /* ADCONN_H_ */ | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										63
									
								
								0005-tools-remove-errx-from-setup_krb5_conf_directory.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								0005-tools-remove-errx-from-setup_krb5_conf_directory.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | |||||||
|  | From b8f5d995d30c17eb8bec3ac5e0777ea94f5b76c3 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 15 Apr 2019 18:00:52 +0200 | ||||||
|  | Subject: [PATCH 5/7] tools: remove errx from setup_krb5_conf_directory | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596 | ||||||
|  | ---
 | ||||||
|  |  tools/tools.c | 38 ++++++++++++++++++++++++-------------- | ||||||
|  |  1 file changed, 24 insertions(+), 14 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/tools.c b/tools/tools.c
 | ||||||
|  | index bdf6d38..fc9fa9a 100644
 | ||||||
|  | --- a/tools/tools.c
 | ||||||
|  | +++ b/tools/tools.c
 | ||||||
|  | @@ -327,21 +327,31 @@ setup_krb5_conf_directory (adcli_conn *conn)
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (asprintf (&directory, "%s%sadcli-krb5-XXXXXX", parent, | ||||||
|  | -	              (parent[0] && parent[strlen(parent) - 1] == '/') ? "" : "/") < 0)
 | ||||||
|  | -		errx (1, "unexpected: out of memory");
 | ||||||
|  | -
 | ||||||
|  | -	if (mkdtemp (directory) == NULL) {
 | ||||||
|  | -		errn = errno;
 | ||||||
|  | +	              (parent[0] && parent[strlen(parent) - 1] == '/') ? "" : "/") < 0) {
 | ||||||
|  | +		warnx ("unexpected: out of memory");
 | ||||||
|  | +		directory = NULL; /* content is undefined */
 | ||||||
|  |  		failed = 1; | ||||||
|  | -		warnx ("couldn't create temporary directory in: %s: %s",
 | ||||||
|  | -		       parent, strerror (errn));
 | ||||||
|  | -	} else {
 | ||||||
|  | -		if (asprintf (&filename, "%s/krb5.conf", directory) < 0 ||
 | ||||||
|  | -		    asprintf (&snippets, "%s/krb5.d", directory) < 0 ||
 | ||||||
|  | -		    asprintf (&contents, "includedir %s\n%s%s\n", snippets,
 | ||||||
|  | -		              krb5_conf ? "include " : "",
 | ||||||
|  | -		              krb5_conf ? krb5_conf : "") < 0)
 | ||||||
|  | -			errx (1, "unexpected: out of memory");
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (!failed) {
 | ||||||
|  | +		if (mkdtemp (directory) == NULL) {
 | ||||||
|  | +			errn = errno;
 | ||||||
|  | +			failed = 1;
 | ||||||
|  | +			warnx ("couldn't create temporary directory in: %s: %s",
 | ||||||
|  | +			       parent, strerror (errn));
 | ||||||
|  | +		} else {
 | ||||||
|  | +			if (asprintf (&filename, "%s/krb5.conf", directory) < 0 ||
 | ||||||
|  | +			    asprintf (&snippets, "%s/krb5.d", directory) < 0 ||
 | ||||||
|  | +			    asprintf (&contents, "includedir %s\n%s%s\n", snippets,
 | ||||||
|  | +			              krb5_conf ? "include " : "",
 | ||||||
|  | +			              krb5_conf ? krb5_conf : "") < 0) {
 | ||||||
|  | +				warnx ("unexpected: out of memory");
 | ||||||
|  | +				filename = NULL; /* content is undefined */
 | ||||||
|  | +				snippets = NULL; /* content is undefined */
 | ||||||
|  | +				contents = NULL; /* content is undefined */
 | ||||||
|  | +				failed = 1;
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (!failed) { | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										67
									
								
								0006-Handle-kvno-increment-for-RODCs.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								0006-Handle-kvno-increment-for-RODCs.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | |||||||
|  | From 6b60f4c08d811e4bc3a68d1a4770c2ce5619c890 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 1 Nov 2017 17:14:05 +0100 | ||||||
|  | Subject: [PATCH 06/23] Handle kvno increment for RODCs | ||||||
|  | 
 | ||||||
|  | Since the actual password change does not happen on the read-only domain | ||||||
|  | controller (RODC) the kvno change has to be replicated back which might | ||||||
|  | take some time. So we check the kvno before and after the change if we | ||||||
|  | are connected to a RODC and increment the kvno if needed. | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 31 +++++++++++++++++++++++++++++++ | ||||||
|  |  1 file changed, 31 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 05885d0..bb970d1 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -1633,8 +1633,30 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
 | ||||||
|  |  		             adcli_enroll_flags flags) | ||||||
|  |  { | ||||||
|  |  	adcli_result res; | ||||||
|  | +	krb5_kvno old_kvno = -1;
 | ||||||
|  |   | ||||||
|  |  	if (!(flags & ADCLI_ENROLL_PASSWORD_VALID)) { | ||||||
|  | +
 | ||||||
|  | +		/* Handle kvno changes for read-only domain controllers
 | ||||||
|  | +		 * (RODC). Since the actual password change does not happen on
 | ||||||
|  | +		 * the RODC the kvno change has to be replicated back which
 | ||||||
|  | +		 * might take some time. So we check the kvno before and after
 | ||||||
|  | +		 * the change if we are connected to a RODC and increment the
 | ||||||
|  | +		 * kvno if needed. */
 | ||||||
|  | +		if (!adcli_conn_is_writeable (enroll->conn)) {
 | ||||||
|  | +			if (enroll->computer_attributes == NULL) {
 | ||||||
|  | +				res = retrieve_computer_account (enroll);
 | ||||||
|  | +				if (res != ADCLI_SUCCESS)
 | ||||||
|  | +					return res;
 | ||||||
|  | +			}
 | ||||||
|  | +			old_kvno = adcli_enroll_get_kvno (enroll);
 | ||||||
|  | +			_adcli_info ("Found old kvno '%d'", old_kvno);
 | ||||||
|  | +
 | ||||||
|  | +			ldap_msgfree (enroll->computer_attributes);
 | ||||||
|  | +			enroll->computer_attributes = NULL;
 | ||||||
|  | +			adcli_enroll_set_kvno (enroll, 0);
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  |  		res = set_computer_password (enroll); | ||||||
|  |  		if (res != ADCLI_SUCCESS) | ||||||
|  |  			return res; | ||||||
|  | @@ -1651,6 +1673,15 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
 | ||||||
|  |  			return res; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	/* Handle kvno changes for read-only domain controllers (RODC) */
 | ||||||
|  | +	if (!adcli_conn_is_writeable (enroll->conn) && old_kvno != -1 &&
 | ||||||
|  | +	    adcli_enroll_get_kvno (enroll) != 0 &&
 | ||||||
|  | +	    adcli_enroll_get_kvno (enroll) == old_kvno) {
 | ||||||
|  | +		enroll->kvno++;
 | ||||||
|  | +		_adcli_info ("No kvno change detected on read-only DC,  kvno "
 | ||||||
|  | +		             "will be incremented by 1 to '%d'", enroll->kvno);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	/* We ignore failures of setting these fields */ | ||||||
|  |  	update_and_calculate_enctypes (enroll); | ||||||
|  |  	update_computer_account (enroll); | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										129
									
								
								0006-enroll-allow-fqdn-for-locate_computer_account.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								0006-enroll-allow-fqdn-for-locate_computer_account.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | |||||||
|  | From 2a695dfe09cafeee3a648d3b969c364f8d3f494f Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 27 Oct 2020 14:49:55 +0100 | ||||||
|  | Subject: [PATCH 6/7] enroll: allow fqdn for locate_computer_account | ||||||
|  | 
 | ||||||
|  | Make it possible to find existing manages service account by the | ||||||
|  | fully-qualified name. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1854112 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 45 +++++++++++++++++++++++++++++++-------------- | ||||||
|  |  1 file changed, 31 insertions(+), 14 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 05bb085..98cd5fa 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -990,10 +990,11 @@ delete_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  static adcli_result | ||||||
|  |  locate_computer_account (adcli_enroll *enroll, | ||||||
|  |                           LDAP *ldap, | ||||||
|  | +                         bool use_fqdn,
 | ||||||
|  |                           LDAPMessage **rresults, | ||||||
|  |                           LDAPMessage **rentry) | ||||||
|  |  { | ||||||
|  | -	char *attrs[] = { "objectClass", NULL };
 | ||||||
|  | +	char *attrs[] = { "objectClass", "CN", NULL };
 | ||||||
|  |  	LDAPMessage *results = NULL; | ||||||
|  |  	LDAPMessage *entry = NULL; | ||||||
|  |  	const char *base; | ||||||
|  | @@ -1003,12 +1004,22 @@ locate_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	int ret = 0; | ||||||
|  |   | ||||||
|  |  	/* If we don't yet know our computer dn, then try and find it */ | ||||||
|  | -	value = _adcli_ldap_escape_filter (enroll->computer_sam);
 | ||||||
|  | -	return_unexpected_if_fail (value != NULL);
 | ||||||
|  | -	if (asprintf (&filter, "(&(objectClass=%s)(sAMAccountName=%s))",
 | ||||||
|  | -	              enroll->is_service ? "msDS-ManagedServiceAccount" : "computer",
 | ||||||
|  | -	              value) < 0)
 | ||||||
|  | -		return_unexpected_if_reached ();
 | ||||||
|  | +	if (use_fqdn) {
 | ||||||
|  | +		return_unexpected_if_fail (enroll->host_fqdn != NULL);
 | ||||||
|  | +		value = _adcli_ldap_escape_filter (enroll->host_fqdn);
 | ||||||
|  | +		return_unexpected_if_fail (value != NULL);
 | ||||||
|  | +		if (asprintf (&filter, "(&(objectClass=%s)(dNSHostName=%s))",
 | ||||||
|  | +		              enroll->is_service ? "msDS-ManagedServiceAccount" : "computer",
 | ||||||
|  | +		              value) < 0)
 | ||||||
|  | +			return_unexpected_if_reached ();
 | ||||||
|  | +	} else {
 | ||||||
|  | +		value = _adcli_ldap_escape_filter (enroll->computer_sam);
 | ||||||
|  | +		return_unexpected_if_fail (value != NULL);
 | ||||||
|  | +		if (asprintf (&filter, "(&(objectClass=%s)(sAMAccountName=%s))",
 | ||||||
|  | +		              enroll->is_service ? "msDS-ManagedServiceAccount" : "computer",
 | ||||||
|  | +		              value) < 0)
 | ||||||
|  | +			return_unexpected_if_reached ();
 | ||||||
|  | +	}
 | ||||||
|  |  	free (value); | ||||||
|  |   | ||||||
|  |  	base = adcli_conn_get_default_naming_context (enroll->conn); | ||||||
|  | @@ -1031,21 +1042,26 @@ locate_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  			enroll->computer_dn = strdup (dn); | ||||||
|  |  			return_unexpected_if_fail (enroll->computer_dn != NULL); | ||||||
|  |  			_adcli_info ("Found %s account for %s at: %s", | ||||||
|  | -			             s_or_c (enroll), enroll->computer_sam, dn);
 | ||||||
|  | +			             s_or_c (enroll),
 | ||||||
|  | +			             use_fqdn ? enroll->host_fqdn
 | ||||||
|  | +			                      : enroll->computer_sam, dn);
 | ||||||
|  |  			ldap_memfree (dn); | ||||||
|  |   | ||||||
|  |  		} else { | ||||||
|  |  			ldap_msgfree (results); | ||||||
|  |  			results = NULL; | ||||||
|  |  			_adcli_info ("A %s account for %s does not exist", | ||||||
|  | -			             s_or_c (enroll), enroll->computer_sam);
 | ||||||
|  | +			             s_or_c (enroll),
 | ||||||
|  | +			             use_fqdn ? enroll->host_fqdn
 | ||||||
|  | +			                      : enroll->computer_sam);
 | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  	} else { | ||||||
|  |  		return _adcli_ldap_handle_failure (ldap, ADCLI_ERR_DIRECTORY, | ||||||
|  |  		                                   "Couldn't lookup %s account: %s", | ||||||
|  |  		                                   s_or_c (enroll), | ||||||
|  | -		                                   enroll->computer_sam);
 | ||||||
|  | +		                                   use_fqdn ? enroll->host_fqdn
 | ||||||
|  | +		                                            :enroll->computer_sam);
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (rresults) | ||||||
|  | @@ -1120,7 +1136,8 @@ locate_or_create_computer_account (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  	/* Try to find the computer account */ | ||||||
|  |  	if (!enroll->computer_dn) { | ||||||
|  | -		res = locate_computer_account (enroll, ldap, &results, &entry);
 | ||||||
|  | +		res = locate_computer_account (enroll, ldap, false,
 | ||||||
|  | +		                               &results, &entry);
 | ||||||
|  |  		if (res != ADCLI_SUCCESS) | ||||||
|  |  			return res; | ||||||
|  |  		searched = 1; | ||||||
|  | @@ -2395,7 +2412,7 @@ adcli_enroll_read_computer_account (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  	/* Find the computer dn */ | ||||||
|  |  	if (!enroll->computer_dn) { | ||||||
|  | -		res = locate_computer_account (enroll, ldap, NULL, NULL);
 | ||||||
|  | +		res = locate_computer_account (enroll, ldap, false, NULL, NULL);
 | ||||||
|  |  		if (res != ADCLI_SUCCESS) | ||||||
|  |  			return res; | ||||||
|  |  		if (!enroll->computer_dn) { | ||||||
|  | @@ -2508,7 +2525,7 @@ adcli_enroll_delete (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  	/* Find the computer dn */ | ||||||
|  |  	if (!enroll->computer_dn) { | ||||||
|  | -		res = locate_computer_account (enroll, ldap, NULL, NULL);
 | ||||||
|  | +		res = locate_computer_account (enroll, ldap, false, NULL, NULL);
 | ||||||
|  |  		if (res != ADCLI_SUCCESS) | ||||||
|  |  			return res; | ||||||
|  |  		if (!enroll->computer_dn) { | ||||||
|  | @@ -2552,7 +2569,7 @@ adcli_enroll_password (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  	/* Find the computer dn */ | ||||||
|  |  	if (!enroll->computer_dn) { | ||||||
|  | -		res = locate_computer_account (enroll, ldap, NULL, NULL);
 | ||||||
|  | +		res = locate_computer_account (enroll, ldap, false, NULL, NULL);
 | ||||||
|  |  		if (res != ADCLI_SUCCESS) | ||||||
|  |  			return res; | ||||||
|  |  		if (!enroll->computer_dn) { | ||||||
|  | -- 
 | ||||||
|  | 2.28.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										175
									
								
								0006-tools-entry-remove-errx-from-parse_option.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								0006-tools-entry-remove-errx-from-parse_option.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,175 @@ | |||||||
|  | From d9912e19e48ec482351b9c384140ad71922ec5c0 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 8 Apr 2019 17:22:00 +0200 | ||||||
|  | Subject: [PATCH 6/7] tools: entry - remove errx from parse_option | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596 | ||||||
|  | ---
 | ||||||
|  |  tools/entry.c | 70 ++++++++++++++++++++++++++++++++++----------------- | ||||||
|  |  1 file changed, 47 insertions(+), 23 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/entry.c b/tools/entry.c
 | ||||||
|  | index 97ec6e7..f361845 100644
 | ||||||
|  | --- a/tools/entry.c
 | ||||||
|  | +++ b/tools/entry.c
 | ||||||
|  | @@ -81,7 +81,7 @@ static adcli_tool_desc common_usages[] = {
 | ||||||
|  |  	{ 0 }, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | -static void
 | ||||||
|  | +static int
 | ||||||
|  |  parse_option (Option opt, | ||||||
|  |                const char *optarg, | ||||||
|  |                adcli_conn *conn) | ||||||
|  | @@ -93,54 +93,58 @@ parse_option (Option opt,
 | ||||||
|  |  	switch (opt) { | ||||||
|  |  	case opt_login_ccache: | ||||||
|  |  		adcli_conn_set_login_ccache_name (conn, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_login_user: | ||||||
|  |  		adcli_conn_set_login_user (conn, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_domain: | ||||||
|  |  		adcli_conn_set_domain_name (conn, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_domain_realm: | ||||||
|  |  		adcli_conn_set_domain_realm (conn, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_domain_controller: | ||||||
|  |  		adcli_conn_set_domain_controller (conn, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_no_password: | ||||||
|  |  		if (stdin_password || prompt_password) { | ||||||
|  | -			errx (EUSAGE, "cannot use --no-password argument with %s",
 | ||||||
|  | -			      stdin_password ? "--stdin-password" : "--prompt-password");
 | ||||||
|  | +			warnx ("cannot use --no-password argument with %s",
 | ||||||
|  | +			       stdin_password ? "--stdin-password" : "--prompt-password");
 | ||||||
|  | +			return EUSAGE;
 | ||||||
|  |  		} else { | ||||||
|  |  			adcli_conn_set_password_func (conn, NULL, NULL, NULL); | ||||||
|  |  			no_password = 1; | ||||||
|  |  		} | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_prompt_password: | ||||||
|  |  		if (stdin_password || no_password) { | ||||||
|  | -			errx (EUSAGE, "cannot use --prompt-password argument with %s",
 | ||||||
|  | -			      stdin_password ? "--stdin-password" : "--no-password");
 | ||||||
|  | +			warnx ("cannot use --prompt-password argument with %s",
 | ||||||
|  | +			       stdin_password ? "--stdin-password" : "--no-password");
 | ||||||
|  | +			return EUSAGE;
 | ||||||
|  |  		} else { | ||||||
|  |  			adcli_conn_set_password_func (conn, adcli_prompt_password_func, NULL, NULL); | ||||||
|  |  			prompt_password = 1; | ||||||
|  |  		} | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_stdin_password: | ||||||
|  |  		if (prompt_password || no_password) { | ||||||
|  | -			errx (EUSAGE, "cannot use --stdin-password argument with %s",
 | ||||||
|  | -			      prompt_password ? "--prompt-password" : "--no-password");
 | ||||||
|  | +			warnx ("cannot use --stdin-password argument with %s",
 | ||||||
|  | +			       prompt_password ? "--prompt-password" : "--no-password");
 | ||||||
|  | +			return EUSAGE;
 | ||||||
|  |  		} else { | ||||||
|  |  			adcli_conn_set_password_func (conn, adcli_read_password_func, NULL, NULL); | ||||||
|  |  			stdin_password = 1; | ||||||
|  |  		} | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_verbose: | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	default: | ||||||
|  |  		assert (0 && "not reached"); | ||||||
|  |  		break; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	errx (EUSAGE, "failure to parse option '%c'", opt);
 | ||||||
|  | +	warnx ("failure to parse option '%c'", opt);
 | ||||||
|  | +	return EUSAGE;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int | ||||||
|  | @@ -224,7 +228,11 @@ adcli_tool_user_create (adcli_conn *conn,
 | ||||||
|  |  			adcli_attrs_free (attrs); | ||||||
|  |  			return opt == 'h' ? 0 : 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				adcli_attrs_free (attrs);
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -322,7 +330,10 @@ adcli_tool_user_delete (adcli_conn *conn,
 | ||||||
|  |  			adcli_tool_usage (options, common_usages); | ||||||
|  |  			return opt == 'h' ? 0 : 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -417,7 +428,11 @@ adcli_tool_group_create (adcli_conn *conn,
 | ||||||
|  |  			adcli_attrs_free (attrs); | ||||||
|  |  			return opt == 'h' ? 0 : 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				adcli_attrs_free (attrs);
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -505,7 +520,10 @@ adcli_tool_group_delete (adcli_conn *conn,
 | ||||||
|  |  			adcli_tool_usage (options, common_usages); | ||||||
|  |  			return opt == 'h' ? 0 : 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -628,7 +646,10 @@ adcli_tool_member_add (adcli_conn *conn,
 | ||||||
|  |  			adcli_tool_usage (options, common_usages); | ||||||
|  |  			return opt == 'h' ? 0 : 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -725,7 +746,10 @@ adcli_tool_member_remove (adcli_conn *conn,
 | ||||||
|  |  			adcli_tool_usage (options, common_usages); | ||||||
|  |  			return opt == 'h' ? 0 : 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | From 3d312a6c89a88be444fb5ed768fbaa6155bf1cc9 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 30 Jan 2018 14:39:46 +0100 | ||||||
|  | Subject: [PATCH 07/23] Fix memory leak in test_check_nt_time_string_lifetime | ||||||
|  | 
 | ||||||
|  | The test added with 650e5d33ef31437a049fb454ad3dc5457c56abe7 introduced | ||||||
|  | a small memory leak. | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  library/adutil.c | 1 + | ||||||
|  |  1 file changed, 1 insertion(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adutil.c b/library/adutil.c
 | ||||||
|  | index 21ccd27..cd40f45 100644
 | ||||||
|  | --- a/library/adutil.c
 | ||||||
|  | +++ b/library/adutil.c
 | ||||||
|  | @@ -501,6 +501,7 @@ test_check_nt_time_string_lifetime (void)
 | ||||||
|  |  			  (time (NULL) + 10 + AD_TO_UNIX_TIME_CONST) * 1000 * 1000 *10) | ||||||
|  |  		!= -1); | ||||||
|  |  	assert (!_adcli_check_nt_time_string_lifetime (time_str, 0)); | ||||||
|  | +	free (time_str);
 | ||||||
|  |   | ||||||
|  |  	/* This test will fail some time after 2200AD as a reminder to reflect | ||||||
|  |  	 * why adcli is still needed. */ | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										122
									
								
								0007-service-account-add-random-suffix-to-account-name.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								0007-service-account-add-random-suffix-to-account-name.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,122 @@ | |||||||
|  | From 6b94f9712378b8f1fa1bc530c64cb987abb0c43b Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 27 Oct 2020 15:23:04 +0100 | ||||||
|  | Subject: [PATCH 7/7] service-account: add random suffix to account name | ||||||
|  | 
 | ||||||
|  | Add a random component to the default managed service account name to | ||||||
|  | avoid name collisions. | ||||||
|  | 
 | ||||||
|  | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1854112 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  1 file changed, 79 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 98cd5fa..f693e58 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -1121,6 +1121,59 @@ load_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static adcli_result
 | ||||||
|  | +refresh_service_account_name_sam_and_princ (adcli_enroll *enroll,
 | ||||||
|  | +                                            const char *name)
 | ||||||
|  | +{
 | ||||||
|  | +	adcli_result res;
 | ||||||
|  | +
 | ||||||
|  | +	adcli_enroll_set_computer_name (enroll, name);
 | ||||||
|  | +	res = ensure_computer_sam (ADCLI_SUCCESS, enroll);
 | ||||||
|  | +	res = ensure_keytab_principals (res, enroll);
 | ||||||
|  | +
 | ||||||
|  | +	return res;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static adcli_result
 | ||||||
|  | +calculate_random_service_account_name (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	char *suffix;
 | ||||||
|  | +	char *new_name;
 | ||||||
|  | +	int ret;
 | ||||||
|  | +	adcli_result res;
 | ||||||
|  | +
 | ||||||
|  | +	suffix = generate_host_password (enroll, 3, filter_sam_chars);
 | ||||||
|  | +	return_unexpected_if_fail (suffix != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	ret = asprintf (&new_name, "%s!%s", enroll->computer_name, suffix);
 | ||||||
|  | +	free (suffix);
 | ||||||
|  | +	return_unexpected_if_fail (ret > 0);
 | ||||||
|  | +
 | ||||||
|  | +	res = refresh_service_account_name_sam_and_princ (enroll, new_name);
 | ||||||
|  | +	free (new_name);
 | ||||||
|  | +
 | ||||||
|  | +	return res;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static adcli_result
 | ||||||
|  | +get_service_account_name_from_ldap (adcli_enroll *enroll, LDAPMessage *results)
 | ||||||
|  | +{
 | ||||||
|  | +	LDAP *ldap;
 | ||||||
|  | +	char *cn;
 | ||||||
|  | +	adcli_result res;
 | ||||||
|  | +
 | ||||||
|  | +	ldap = adcli_conn_get_ldap_connection (enroll->conn);
 | ||||||
|  | +	assert (ldap != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	cn = _adcli_ldap_parse_value (ldap, results, "CN");
 | ||||||
|  | +	return_unexpected_if_fail (cn != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	res = refresh_service_account_name_sam_and_princ (enroll, cn);
 | ||||||
|  | +	free (cn);
 | ||||||
|  | +
 | ||||||
|  | +	return res;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static adcli_result | ||||||
|  |  locate_or_create_computer_account (adcli_enroll *enroll, | ||||||
|  |                                     int allow_overwrite) | ||||||
|  | @@ -1143,8 +1196,32 @@ locate_or_create_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  		searched = 1; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	/* Try with fqdn for service accounts */
 | ||||||
|  | +	if (!enroll->computer_dn && enroll->is_service
 | ||||||
|  | +	                && enroll->host_fqdn != NULL) {
 | ||||||
|  | +		res = locate_computer_account (enroll, ldap, true,
 | ||||||
|  | +		                               &results, &entry);
 | ||||||
|  | +		if (res != ADCLI_SUCCESS)
 | ||||||
|  | +			return res;
 | ||||||
|  | +		searched = 1;
 | ||||||
|  | +
 | ||||||
|  | +		if (results != NULL) {
 | ||||||
|  | +			res = get_service_account_name_from_ldap (enroll,
 | ||||||
|  | +			                                          results);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	/* Next try and come up with where we think it should be */ | ||||||
|  |  	if (enroll->computer_dn == NULL) { | ||||||
|  | +		if (enroll->is_service && !enroll->computer_name_explicit) {
 | ||||||
|  | +			res = calculate_random_service_account_name (enroll);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  |  		res = calculate_computer_account (enroll, ldap); | ||||||
|  |  		if (res != ADCLI_SUCCESS) | ||||||
|  |  			return res; | ||||||
|  | @@ -2113,6 +2190,8 @@ adcli_enroll_prepare (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  	if (enroll->is_service) { | ||||||
|  |  		/* Ensure basic params for service accounts */ | ||||||
|  | +		res = ensure_host_fqdn (res, enroll);
 | ||||||
|  | +		res = ensure_computer_name (res, enroll);
 | ||||||
|  |  		res = ensure_computer_sam (res, enroll); | ||||||
|  |  		res = ensure_computer_password (res, enroll); | ||||||
|  |  		res = ensure_host_keytab (res, enroll); | ||||||
|  | -- 
 | ||||||
|  | 2.28.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										294
									
								
								0007-tools-computer-remove-errx-from-parse_option.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										294
									
								
								0007-tools-computer-remove-errx-from-parse_option.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,294 @@ | |||||||
|  | From f127ddef23a532cd9763190527bf79b4e47fa2ab Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 8 Apr 2019 17:33:17 +0200 | ||||||
|  | Subject: [PATCH 7/7] tools: computer - remove errx from parse_option | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1588596 | ||||||
|  | ---
 | ||||||
|  |  tools/computer.c | 128 +++++++++++++++++++++++++++++------------------ | ||||||
|  |  1 file changed, 80 insertions(+), 48 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index 9cbbb28..ac8a203 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -159,7 +159,7 @@ static adcli_tool_desc common_usages[] = {
 | ||||||
|  |  	{ 0 }, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | -static void
 | ||||||
|  | +static int
 | ||||||
|  |  parse_option (Option opt, | ||||||
|  |                const char *optarg, | ||||||
|  |                adcli_conn *conn, | ||||||
|  | @@ -175,132 +175,139 @@ parse_option (Option opt,
 | ||||||
|  |  	switch (opt) { | ||||||
|  |  	case opt_login_ccache: | ||||||
|  |  		adcli_conn_set_login_ccache_name (conn, optarg ? optarg : ""); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_login_user: | ||||||
|  |  		if (adcli_conn_get_allowed_login_types (conn) & ADCLI_LOGIN_USER_ACCOUNT) { | ||||||
|  |  			adcli_conn_set_login_user (conn, optarg); | ||||||
|  |  			adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT); | ||||||
|  |  		} else { | ||||||
|  | -			errx (EUSAGE, "cannot set --user if --login-type not set to 'user'");
 | ||||||
|  | +			warnx ("cannot set --user if --login-type not set to 'user'");
 | ||||||
|  | +			return EUSAGE;
 | ||||||
|  |  		} | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_login_type: | ||||||
|  |  		if (optarg && strcmp (optarg, "computer") == 0) { | ||||||
|  | -			if (adcli_conn_get_login_user (conn) != NULL)
 | ||||||
|  | -				errx (EUSAGE, "cannot set --login-type to 'computer' if --user is set");
 | ||||||
|  | -			else
 | ||||||
|  | +			if (adcli_conn_get_login_user (conn) != NULL) {
 | ||||||
|  | +				warnx ("cannot set --login-type to 'computer' if --user is set");
 | ||||||
|  | +				return EUSAGE;
 | ||||||
|  | +			} else
 | ||||||
|  |  				adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_COMPUTER_ACCOUNT); | ||||||
|  |  		} else if (optarg && strcmp (optarg, "user") == 0) { | ||||||
|  |  			adcli_conn_set_allowed_login_types (conn, ADCLI_LOGIN_USER_ACCOUNT); | ||||||
|  |   | ||||||
|  |  		} else { | ||||||
|  | -			errx (EUSAGE, "unknown login type '%s'", optarg);
 | ||||||
|  | +			warnx ("unknown login type '%s'", optarg);
 | ||||||
|  | +			return EUSAGE;
 | ||||||
|  |  		} | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_host_fqdn: | ||||||
|  |  		adcli_conn_set_host_fqdn (conn, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_host_keytab: | ||||||
|  |  		adcli_enroll_set_keytab_name (enroll, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_computer_name: | ||||||
|  |  		adcli_conn_set_computer_name (conn, optarg); | ||||||
|  |  		adcli_enroll_set_computer_name (enroll, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_domain: | ||||||
|  |  		adcli_conn_set_domain_name (conn, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_domain_realm: | ||||||
|  |  		adcli_conn_set_domain_realm (conn, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_domain_controller: | ||||||
|  |  		adcli_conn_set_domain_controller (conn, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_domain_ou: | ||||||
|  |  		adcli_enroll_set_domain_ou (enroll, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_service_name: | ||||||
|  |  		adcli_enroll_add_service_name (enroll, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_no_password: | ||||||
|  |  		if (stdin_password || prompt_password) { | ||||||
|  | -			errx (EUSAGE, "cannot use --no-password argument with %s",
 | ||||||
|  | -			      stdin_password ? "--stdin-password" : "--prompt-password");
 | ||||||
|  | +			warnx ("cannot use --no-password argument with %s",
 | ||||||
|  | +			       stdin_password ? "--stdin-password" : "--prompt-password");
 | ||||||
|  | +			return EUSAGE;
 | ||||||
|  |  		} else { | ||||||
|  |  			adcli_conn_set_password_func (conn, NULL, NULL, NULL); | ||||||
|  |  			no_password = 1; | ||||||
|  |  		} | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_prompt_password: | ||||||
|  |  		if (stdin_password || no_password) { | ||||||
|  | -			errx (EUSAGE, "cannot use --prompt-password argument with %s",
 | ||||||
|  | -			      stdin_password ? "--stdin-password" : "--no-password");
 | ||||||
|  | +			warnx ("cannot use --prompt-password argument with %s",
 | ||||||
|  | +			       stdin_password ? "--stdin-password" : "--no-password");
 | ||||||
|  | +			return EUSAGE;
 | ||||||
|  |  		} else { | ||||||
|  |  			adcli_conn_set_password_func (conn, adcli_prompt_password_func, NULL, NULL); | ||||||
|  |  			prompt_password = 1; | ||||||
|  |  		} | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_stdin_password: | ||||||
|  |  		if (prompt_password || no_password) { | ||||||
|  | -			errx (EUSAGE, "cannot use --stdin-password argument with %s",
 | ||||||
|  | -			      prompt_password ? "--prompt-password" : "--no-password");
 | ||||||
|  | +			warnx ("cannot use --stdin-password argument with %s",
 | ||||||
|  | +			       prompt_password ? "--prompt-password" : "--no-password");
 | ||||||
|  | +			return EUSAGE;
 | ||||||
|  |  		} else { | ||||||
|  |  			adcli_conn_set_password_func (conn, adcli_read_password_func, NULL, NULL); | ||||||
|  |  			stdin_password = 1; | ||||||
|  |  		} | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_os_name: | ||||||
|  |  		adcli_enroll_set_os_name (enroll, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_os_version: | ||||||
|  |  		adcli_enroll_set_os_version (enroll, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_os_service_pack: | ||||||
|  |  		adcli_enroll_set_os_service_pack (enroll, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_user_principal: | ||||||
|  |  		if (optarg && optarg[0]) | ||||||
|  |  			adcli_enroll_set_user_principal (enroll, optarg); | ||||||
|  |  		else | ||||||
|  |  			adcli_enroll_auto_user_principal (enroll); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_computer_password_lifetime: | ||||||
|  |  		errno = 0; | ||||||
|  |  		lifetime = strtoul (optarg, &endptr, 10); | ||||||
|  |  		if (errno != 0 || *endptr != '\0' || endptr == optarg) { | ||||||
|  | -			errx (EUSAGE,
 | ||||||
|  | -			      "failure to parse value '%s' of option 'computer-password-lifetime'; "
 | ||||||
|  | -			      "expecting non-negative integer indicating the lifetime in days",
 | ||||||
|  | -			      optarg);
 | ||||||
|  | +			warnx ("failure to parse value '%s' of option 'computer-password-lifetime'; "
 | ||||||
|  | +			       "expecting non-negative integer indicating the lifetime in days",
 | ||||||
|  | +			       optarg);
 | ||||||
|  | +			return EUSAGE;
 | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  		adcli_enroll_set_computer_password_lifetime (enroll, lifetime); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_samba_data_tool: | ||||||
|  |  		errno = 0; | ||||||
|  |  		ret = access (optarg, X_OK); | ||||||
|  |  		if (ret != 0) { | ||||||
|  |  			ret = errno; | ||||||
|  | -			errx (EUSAGE, "Failed to access tool to add Samba data: %s", strerror (ret));
 | ||||||
|  | +			warnx ("Failed to access tool to add Samba data: %s", strerror (ret));
 | ||||||
|  | +			return EUSAGE;
 | ||||||
|  |  		} else { | ||||||
|  |  			adcli_enroll_set_samba_data_tool (enroll, optarg); | ||||||
|  |  		} | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_trusted_for_delegation: | ||||||
|  |  		if (strcasecmp (optarg, "true") == 0 || strcasecmp (optarg, "yes") == 0) { | ||||||
|  |  			adcli_enroll_set_trusted_for_delegation (enroll, true); | ||||||
|  |  		} else { | ||||||
|  |  			adcli_enroll_set_trusted_for_delegation (enroll, false); | ||||||
|  |  		} | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_add_service_principal: | ||||||
|  |  		adcli_enroll_add_service_principal_to_add (enroll, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_remove_service_principal: | ||||||
|  |  		adcli_enroll_add_service_principal_to_remove (enroll, optarg); | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |  	case opt_verbose: | ||||||
|  | -		return;
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  |   | ||||||
|  |  	/* Should be handled by caller */ | ||||||
|  |  	case opt_show_details: | ||||||
|  | @@ -311,7 +318,8 @@ parse_option (Option opt,
 | ||||||
|  |  		break; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	errx (EUSAGE, "failure to parse option '%c'", opt);
 | ||||||
|  | +	warnx ("failure to parse option '%c'", opt);
 | ||||||
|  | +	return EUSAGE;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  | @@ -407,7 +415,11 @@ adcli_tool_computer_join (adcli_conn *conn,
 | ||||||
|  |  			adcli_enroll_unref (enroll); | ||||||
|  |  			return opt == 'h' ? 0 : 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				adcli_enroll_unref (enroll);
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -519,7 +531,11 @@ adcli_tool_computer_update (adcli_conn *conn,
 | ||||||
|  |  			adcli_enroll_unref (enroll); | ||||||
|  |  			return opt == 'h' ? 0 : 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				adcli_enroll_unref (enroll);
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -610,7 +626,11 @@ adcli_tool_computer_testjoin (adcli_conn *conn,
 | ||||||
|  |  			adcli_enroll_unref (enroll); | ||||||
|  |  			return opt == 'h' ? 0 : 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				adcli_enroll_unref (enroll);
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -707,7 +727,11 @@ adcli_tool_computer_preset (adcli_conn *conn,
 | ||||||
|  |  			adcli_enroll_unref (enroll); | ||||||
|  |  			return 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				adcli_enroll_unref (enroll);
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -801,7 +825,11 @@ adcli_tool_computer_reset (adcli_conn *conn,
 | ||||||
|  |  			adcli_enroll_unref (enroll); | ||||||
|  |  			return opt == 'h' ? 0 : 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				adcli_enroll_unref (enroll);
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | @@ -884,7 +912,11 @@ adcli_tool_computer_delete (adcli_conn *conn,
 | ||||||
|  |  			adcli_enroll_unref (enroll); | ||||||
|  |  			return opt == 'h' ? 0 : 2; | ||||||
|  |  		default: | ||||||
|  | -			parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			res = parse_option ((Option)opt, optarg, conn, enroll);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				adcli_enroll_unref (enroll);
 | ||||||
|  | +				return res;
 | ||||||
|  | +			}
 | ||||||
|  |  			break; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | -- 
 | ||||||
|  | 2.20.1 | ||||||
|  | 
 | ||||||
							
								
								
									
										178
									
								
								0008-library-add-_adcli_bin_sid_to_str.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								0008-library-add-_adcli_bin_sid_to_str.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,178 @@ | |||||||
|  | From f28edf4e887cf8616fa21dacc2b0f0d31f5f92fb Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 30 Jan 2018 14:37:05 +0100 | ||||||
|  | Subject: [PATCH 08/23] library: add _adcli_bin_sid_to_str() | ||||||
|  | 
 | ||||||
|  | Convert a binary SID to the string representation. | ||||||
|  | 
 | ||||||
|  | https://bugs.freedesktop.org/show_bug.cgi?id=100118 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  library/adprivate.h |   4 ++ | ||||||
|  |  library/adutil.c    | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  2 files changed, 117 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adprivate.h b/library/adprivate.h
 | ||||||
|  | index fc146af..e99f9fc 100644
 | ||||||
|  | --- a/library/adprivate.h
 | ||||||
|  | +++ b/library/adprivate.h
 | ||||||
|  | @@ -31,6 +31,7 @@
 | ||||||
|  |  #include <limits.h> | ||||||
|  |  #include <stdlib.h> | ||||||
|  |  #include <stdio.h> | ||||||
|  | +#include <stdint.h>
 | ||||||
|  |   | ||||||
|  |  #include <ldap.h> | ||||||
|  |   | ||||||
|  | @@ -132,6 +133,9 @@ int            _adcli_str_has_prefix         (const char *str,
 | ||||||
|  |  int            _adcli_str_has_suffix         (const char *str, | ||||||
|  |  		                              const char *suffix); | ||||||
|  |   | ||||||
|  | +char *          _adcli_bin_sid_to_str        (const uint8_t *data,
 | ||||||
|  | +                                              size_t len);
 | ||||||
|  | +
 | ||||||
|  |  char *         _adcli_str_dupn               (void *data, | ||||||
|  |                                                size_t len); | ||||||
|  |   | ||||||
|  | diff --git a/library/adutil.c b/library/adutil.c
 | ||||||
|  | index cd40f45..829cdd9 100644
 | ||||||
|  | --- a/library/adutil.c
 | ||||||
|  | +++ b/library/adutil.c
 | ||||||
|  | @@ -293,6 +293,83 @@ _adcli_strv_set (char ***field,
 | ||||||
|  |  	*field = newval; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +char *
 | ||||||
|  | +_adcli_bin_sid_to_str (const uint8_t *data,
 | ||||||
|  | +                       size_t len)
 | ||||||
|  | +{
 | ||||||
|  | +	uint8_t sid_rev_num;
 | ||||||
|  | +	int8_t num_auths;
 | ||||||
|  | +	uint8_t id_auth[6];
 | ||||||
|  | +	uint32_t id_auth_val;
 | ||||||
|  | +	uint32_t sub_auths[15];
 | ||||||
|  | +	uint32_t val;
 | ||||||
|  | +	size_t p = 0;
 | ||||||
|  | +	size_t c;
 | ||||||
|  | +	int nc;
 | ||||||
|  | +	char *sid_buf;
 | ||||||
|  | +	size_t sid_buf_len;
 | ||||||
|  | +
 | ||||||
|  | +	if (data == NULL || len < 8) {
 | ||||||
|  | +		return NULL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	sid_rev_num = (uint8_t) data [p];
 | ||||||
|  | +	p++;
 | ||||||
|  | +
 | ||||||
|  | +	num_auths = (int8_t) data[p];
 | ||||||
|  | +	p++;
 | ||||||
|  | +
 | ||||||
|  | +	if (num_auths > 15 || len < 8 + (num_auths * sizeof (uint32_t))) {
 | ||||||
|  | +		return NULL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	for (c = 0; c < 6; c++) {
 | ||||||
|  | +		id_auth[c] = (uint8_t) data[p];
 | ||||||
|  | +		p++;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	/* Only 32bits are used for the string representation */
 | ||||||
|  | +	id_auth_val = (id_auth[2] << 24) +
 | ||||||
|  | +	              (id_auth[3] << 16) +
 | ||||||
|  | +	              (id_auth[4] << 8) +
 | ||||||
|  | +	              (id_auth[5]);
 | ||||||
|  | +
 | ||||||
|  | +	for (c = 0; c < num_auths; c++) {
 | ||||||
|  | +		memcpy (&val, data + p, sizeof (uint32_t));
 | ||||||
|  | +		sub_auths[c] = le32toh (val);
 | ||||||
|  | +
 | ||||||
|  | +		p += sizeof (uint32_t);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	sid_buf_len = 17 + (num_auths * 11);
 | ||||||
|  | +	sid_buf = calloc (1, sid_buf_len);
 | ||||||
|  | +	if (sid_buf == NULL) {
 | ||||||
|  | +		return NULL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	nc = snprintf (sid_buf, sid_buf_len, "S-%u-%lu", sid_rev_num,
 | ||||||
|  | +	              (unsigned long) id_auth_val);
 | ||||||
|  | +	if (nc < 0 || nc >= sid_buf_len) {
 | ||||||
|  | +		free (sid_buf);
 | ||||||
|  | +		return NULL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	p = 0;
 | ||||||
|  | +	for (c = 0; c < num_auths; c++) {
 | ||||||
|  | +		p += nc;
 | ||||||
|  | +		sid_buf_len -= nc;
 | ||||||
|  | +
 | ||||||
|  | +		nc = snprintf (sid_buf + p, sid_buf_len, "-%lu",
 | ||||||
|  | +		               (unsigned long) sub_auths[c]);
 | ||||||
|  | +		if (nc < 0 || nc >= sid_buf_len) {
 | ||||||
|  | +			free (sid_buf);
 | ||||||
|  | +			return NULL;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return sid_buf;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  char * | ||||||
|  |  _adcli_str_dupn (void *data, | ||||||
|  |                   size_t len) | ||||||
|  | @@ -508,6 +585,41 @@ test_check_nt_time_string_lifetime (void)
 | ||||||
|  |  	assert (_adcli_check_nt_time_string_lifetime ("130645404000000000", 100000)); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static void
 | ||||||
|  | +test_bin_sid_to_str (void)
 | ||||||
|  | +{
 | ||||||
|  | +	uint8_t sid1[] = { 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
 | ||||||
|  | +	                   0x15, 0x00, 0x00, 0x00, 0xF8, 0x12, 0x13, 0xDC,
 | ||||||
|  | +	                   0x47, 0xF3, 0x1C, 0x76, 0x47, 0x2F, 0x2E, 0xD7,
 | ||||||
|  | +	                   0x51, 0x04, 0x00, 0x00 };
 | ||||||
|  | +
 | ||||||
|  | +	uint8_t sid2[] = { 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
 | ||||||
|  | +	                   0x15, 0x00, 0x00, 0x00, 0xF8, 0x12, 0x13, 0xDC,
 | ||||||
|  | +	                   0x47, 0xF3, 0x1C, 0x76, 0x47, 0x2F, 0x2E, 0xD7};
 | ||||||
|  | +
 | ||||||
|  | +	uint8_t sid3[] = { 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
 | ||||||
|  | +	                   0x15, 0x00, 0x00, 0x00, 0x29, 0xC9, 0x4F, 0xD9,
 | ||||||
|  | +	                   0xC2, 0x3C, 0xC3, 0x78, 0x36, 0x55, 0x87, 0xF8};
 | ||||||
|  | +
 | ||||||
|  | +
 | ||||||
|  | +	char *str;
 | ||||||
|  | +
 | ||||||
|  | +	str = _adcli_bin_sid_to_str (sid1, sizeof (sid1));
 | ||||||
|  | +	assert (str != NULL);
 | ||||||
|  | +	assert (strcmp (str, "S-1-5-21-3692237560-1981608775-3610128199-1105") == 0);
 | ||||||
|  | +	free (str);
 | ||||||
|  | +
 | ||||||
|  | +	str = _adcli_bin_sid_to_str (sid2, sizeof (sid2));
 | ||||||
|  | +	assert (str != NULL);
 | ||||||
|  | +	assert (strcmp (str, "S-1-5-21-3692237560-1981608775-3610128199") == 0);
 | ||||||
|  | +	free (str);
 | ||||||
|  | +
 | ||||||
|  | +	str = _adcli_bin_sid_to_str (sid3, sizeof (sid2));
 | ||||||
|  | +	assert (str != NULL);
 | ||||||
|  | +	assert (strcmp (str, "S-1-5-21-3645884713-2026060994-4169618742") == 0);
 | ||||||
|  | +	free (str);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  int | ||||||
|  |  main (int argc, | ||||||
|  |        char *argv[]) | ||||||
|  | @@ -516,6 +628,7 @@ main (int argc,
 | ||||||
|  |  	test_func (test_strv_dup, "/util/strv_dup"); | ||||||
|  |  	test_func (test_strv_count, "/util/strv_count"); | ||||||
|  |  	test_func (test_check_nt_time_string_lifetime, "/util/check_nt_time_string_lifetime"); | ||||||
|  | +	test_func (test_bin_sid_to_str, "/util/bin_sid_to_str");
 | ||||||
|  |  	return test_run (argc, argv); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										317
									
								
								0009-library-add-_adcli_call_external_program.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										317
									
								
								0009-library-add-_adcli_call_external_program.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,317 @@ | |||||||
|  | From 63576f12524f521c0cf08d42b279654885135a90 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 30 Jan 2018 14:39:17 +0100 | ||||||
|  | Subject: [PATCH 09/23] library: add _adcli_call_external_program() | ||||||
|  | 
 | ||||||
|  | Allow adcli to call an external program given by an absolute path name | ||||||
|  | and an array of options. stdin and stdout can be used if needed. | ||||||
|  | 
 | ||||||
|  | https://bugs.freedesktop.org/show_bug.cgi?id=100118 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  configure.ac        |  28 +++++++ | ||||||
|  |  library/adprivate.h |   6 ++ | ||||||
|  |  library/adutil.c    | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  3 files changed, 245 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/configure.ac b/configure.ac
 | ||||||
|  | index 221d8ae..fe86638 100644
 | ||||||
|  | --- a/configure.ac
 | ||||||
|  | +++ b/configure.ac
 | ||||||
|  | @@ -263,6 +263,34 @@ AC_SUBST(LCOV)
 | ||||||
|  |  AC_SUBST(GCOV) | ||||||
|  |  AC_SUBST(GENHTML) | ||||||
|  |   | ||||||
|  | +AC_PATH_PROG(BIN_CAT, cat, no)
 | ||||||
|  | +if test "$BIN_CAT" = "no" ; then
 | ||||||
|  | +	AC_MSG_ERROR([cat is not available])
 | ||||||
|  | +else
 | ||||||
|  | +	AC_DEFINE_UNQUOTED(BIN_CAT, "$BIN_CAT", [path to cat, used in unit test])
 | ||||||
|  | +fi
 | ||||||
|  | +
 | ||||||
|  | +AC_PATH_PROG(BIN_TAC, tac, no)
 | ||||||
|  | +if test "$BIN_TAC" = "no" ; then
 | ||||||
|  | +	AC_MSG_ERROR([tac is not available])
 | ||||||
|  | +else
 | ||||||
|  | +	AC_DEFINE_UNQUOTED(BIN_TAC, "$BIN_TAC", [path to tac, used in unit test])
 | ||||||
|  | +fi
 | ||||||
|  | +
 | ||||||
|  | +AC_PATH_PROG(BIN_REV, rev, no)
 | ||||||
|  | +if test "$BIN_REV" = "no" ; then
 | ||||||
|  | +	AC_MSG_ERROR([rev is not available])
 | ||||||
|  | +else
 | ||||||
|  | +	AC_DEFINE_UNQUOTED(BIN_REV, "$BIN_REV", [path to rev, used in unit test])
 | ||||||
|  | +fi
 | ||||||
|  | +
 | ||||||
|  | +AC_PATH_PROG(BIN_ECHO, echo, no)
 | ||||||
|  | +if test "$BIN_ECHO" = "no" ; then
 | ||||||
|  | +	AC_MSG_ERROR([echo is not available])
 | ||||||
|  | +else
 | ||||||
|  | +	AC_DEFINE_UNQUOTED(BIN_ECHO, "$BIN_ECHO", [path to echo, used in unit test])
 | ||||||
|  | +fi
 | ||||||
|  | +
 | ||||||
|  |  # --------------------------------------------------------------------- | ||||||
|  |   | ||||||
|  |  ADCLI_LT_RELEASE=$ADCLI_CURRENT:$ADCLI_REVISION:$ADCLI_AGE | ||||||
|  | diff --git a/library/adprivate.h b/library/adprivate.h
 | ||||||
|  | index e99f9fc..7257c93 100644
 | ||||||
|  | --- a/library/adprivate.h
 | ||||||
|  | +++ b/library/adprivate.h
 | ||||||
|  | @@ -285,4 +285,10 @@ struct _adcli_attrs {
 | ||||||
|  |   | ||||||
|  |  bool             _adcli_check_nt_time_string_lifetime (const char *nt_time_string, unsigned int lifetime); | ||||||
|  |   | ||||||
|  | +adcli_result     _adcli_call_external_program     (const char *binary,
 | ||||||
|  | +                                                   char * const *argv,
 | ||||||
|  | +                                                   const char *stdin_data,
 | ||||||
|  | +                                                   uint8_t **stdout_data,
 | ||||||
|  | +                                                   size_t *stdout_data_len);
 | ||||||
|  | +
 | ||||||
|  |  #endif /* ADPRIVATE_H_ */ | ||||||
|  | diff --git a/library/adutil.c b/library/adutil.c
 | ||||||
|  | index 829cdd9..a27bd68 100644
 | ||||||
|  | --- a/library/adutil.c
 | ||||||
|  | +++ b/library/adutil.c
 | ||||||
|  | @@ -36,6 +36,7 @@
 | ||||||
|  |  #include <unistd.h> | ||||||
|  |  #include <stdint.h> | ||||||
|  |  #include <time.h> | ||||||
|  | +#include <sys/wait.h>
 | ||||||
|  |   | ||||||
|  |  static adcli_message_func message_func = NULL; | ||||||
|  |  static char last_error[2048] = { 0, }; | ||||||
|  | @@ -506,6 +507,161 @@ _adcli_check_nt_time_string_lifetime (const char *nt_time_string,
 | ||||||
|  |  	return false; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +adcli_result
 | ||||||
|  | +_adcli_call_external_program (const char *binary, char * const *argv,
 | ||||||
|  | +                              const char *stdin_data,
 | ||||||
|  | +                              uint8_t **stdout_data, size_t *stdout_data_len)
 | ||||||
|  | +{
 | ||||||
|  | +	int ret;
 | ||||||
|  | +	int pipefd_to_child[2] = { -1, -1};
 | ||||||
|  | +	int pipefd_from_child[2] = { -1, -1};
 | ||||||
|  | +	pid_t child_pid = 0;
 | ||||||
|  | +	int err;
 | ||||||
|  | +	size_t len;
 | ||||||
|  | +	ssize_t rlen;
 | ||||||
|  | +	pid_t wret;
 | ||||||
|  | +	int status;
 | ||||||
|  | +	uint8_t read_buf[4096];
 | ||||||
|  | +	uint8_t *out;
 | ||||||
|  | +
 | ||||||
|  | +	errno = 0;
 | ||||||
|  | +	ret = access (binary, X_OK);
 | ||||||
|  | +	if (ret != 0) {
 | ||||||
|  | +		err = errno;
 | ||||||
|  | +		_adcli_err ("Cannot run [%s]: [%d][%s].", binary, err,
 | ||||||
|  | +		                                          strerror (err));
 | ||||||
|  | +		ret = ADCLI_ERR_FAIL;
 | ||||||
|  | +		goto done;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	ret = pipe (pipefd_from_child);
 | ||||||
|  | +	if (ret == -1) {
 | ||||||
|  | +		err = errno;
 | ||||||
|  | +		_adcli_err ("pipe failed [%d][%s].", err, strerror (err));
 | ||||||
|  | +		ret = ADCLI_ERR_FAIL;
 | ||||||
|  | +		goto done;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	ret = pipe (pipefd_to_child);
 | ||||||
|  | +	if (ret == -1) {
 | ||||||
|  | +		err = errno;
 | ||||||
|  | +		_adcli_err ("pipe failed [%d][%s].", err, strerror (err));
 | ||||||
|  | +		ret = ADCLI_ERR_FAIL;
 | ||||||
|  | +		goto done;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	child_pid = fork ();
 | ||||||
|  | +
 | ||||||
|  | +	if (child_pid == 0) { /* child */
 | ||||||
|  | +		close (pipefd_to_child[1]);
 | ||||||
|  | +		ret = dup2 (pipefd_to_child[0], STDIN_FILENO);
 | ||||||
|  | +		if (ret == -1) {
 | ||||||
|  | +			err = errno;
 | ||||||
|  | +			_adcli_err ("dup2 failed [%d][%s].", err,
 | ||||||
|  | +			                                     strerror (err));
 | ||||||
|  | +			exit (EXIT_FAILURE);
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +		close (pipefd_from_child[0]);
 | ||||||
|  | +		ret = dup2 (pipefd_from_child[1], STDOUT_FILENO);
 | ||||||
|  | +		if (ret == -1) {
 | ||||||
|  | +			err = errno;
 | ||||||
|  | +			_adcli_err ("dup2 failed [%d][%s].", err,
 | ||||||
|  | +			                                     strerror (err));
 | ||||||
|  | +			exit (EXIT_FAILURE);
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +		execv (binary, argv);
 | ||||||
|  | +		_adcli_err ("Failed to run %s.", binary);
 | ||||||
|  | +		ret = ADCLI_ERR_FAIL;
 | ||||||
|  | +		goto done;
 | ||||||
|  | +	} else if (child_pid > 0) { /* parent */
 | ||||||
|  | +
 | ||||||
|  | +		if (stdin_data != NULL) {
 | ||||||
|  | +			len = strlen (stdin_data);
 | ||||||
|  | +			ret = write (pipefd_to_child[1], stdin_data, len);
 | ||||||
|  | +			if (ret != len) {
 | ||||||
|  | +				_adcli_err ("Failed to send computer account password "
 | ||||||
|  | +				            "to net command.");
 | ||||||
|  | +				ret = ADCLI_ERR_FAIL;
 | ||||||
|  | +				goto done;
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +		close (pipefd_to_child[0]);
 | ||||||
|  | +		pipefd_to_child[0] = -1;
 | ||||||
|  | +		close (pipefd_to_child[1]);
 | ||||||
|  | +		pipefd_to_child[0] = -1;
 | ||||||
|  | +
 | ||||||
|  | +		if (stdout_data != NULL || stdout_data_len != NULL) {
 | ||||||
|  | +			rlen = read (pipefd_from_child[0], read_buf, sizeof (read_buf));
 | ||||||
|  | +			if (rlen < 0) {
 | ||||||
|  | +				ret = errno;
 | ||||||
|  | +				_adcli_err ("Failed to read from child [%d][%s].\n",
 | ||||||
|  | +				            ret, strerror (ret));
 | ||||||
|  | +				ret = ADCLI_ERR_FAIL;
 | ||||||
|  | +				goto done;
 | ||||||
|  | +			}
 | ||||||
|  | +
 | ||||||
|  | +			out = malloc (sizeof(uint8_t) * rlen);
 | ||||||
|  | +			if (out == NULL) {
 | ||||||
|  | +				_adcli_err ("Failed to allocate memory "
 | ||||||
|  | +				            "for child output.");
 | ||||||
|  | +				ret = ADCLI_ERR_FAIL;
 | ||||||
|  | +				goto done;
 | ||||||
|  | +			} else {
 | ||||||
|  | +				memcpy (out, read_buf, rlen);
 | ||||||
|  | +			}
 | ||||||
|  | +
 | ||||||
|  | +			if (stdout_data != NULL) {
 | ||||||
|  | +				*stdout_data = out;
 | ||||||
|  | +			} else {
 | ||||||
|  | +				free (out);
 | ||||||
|  | +			}
 | ||||||
|  | +
 | ||||||
|  | +			if (stdout_data_len != NULL) {
 | ||||||
|  | +				*stdout_data_len = rlen;
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +	} else {
 | ||||||
|  | +		_adcli_err ("Cannot run net command.");
 | ||||||
|  | +		ret = ADCLI_ERR_FAIL;
 | ||||||
|  | +		goto done;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	ret = ADCLI_SUCCESS;
 | ||||||
|  | +
 | ||||||
|  | +done:
 | ||||||
|  | +	if (pipefd_from_child[0] != -1) {
 | ||||||
|  | +		close (pipefd_from_child[0]);
 | ||||||
|  | +	}
 | ||||||
|  | +	if (pipefd_from_child[1] != -1) {
 | ||||||
|  | +		close (pipefd_from_child[1]);
 | ||||||
|  | +	}
 | ||||||
|  | +	if (pipefd_to_child[0] != -1) {
 | ||||||
|  | +		close (pipefd_to_child[0]);
 | ||||||
|  | +	}
 | ||||||
|  | +	if (pipefd_to_child[1] != -1) {
 | ||||||
|  | +		close (pipefd_to_child[1]);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (child_pid > 0) {
 | ||||||
|  | +		wret = waitpid (child_pid, &status, 0);
 | ||||||
|  | +		if (wret == -1) {
 | ||||||
|  | +			_adcli_err ("No sure what happend to net command.");
 | ||||||
|  | +		} else {
 | ||||||
|  | +			if (WIFEXITED (status)) {
 | ||||||
|  | +				_adcli_err ("net command failed with %d.",
 | ||||||
|  | +				            WEXITSTATUS (status));
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return ret;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +
 | ||||||
|  |  #ifdef UTIL_TESTS | ||||||
|  |   | ||||||
|  |  #include "test.h" | ||||||
|  | @@ -620,6 +776,60 @@ test_bin_sid_to_str (void)
 | ||||||
|  |  	free (str); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static void
 | ||||||
|  | +test_call_external_program (void)
 | ||||||
|  | +{
 | ||||||
|  | +	adcli_result res;
 | ||||||
|  | +	char *argv[] = { NULL, NULL, NULL };
 | ||||||
|  | +	uint8_t *stdout_data;
 | ||||||
|  | +	size_t stdout_data_len;
 | ||||||
|  | +
 | ||||||
|  | +	argv[0] = "/does/not/exists";
 | ||||||
|  | +	res = _adcli_call_external_program (argv[0], argv, NULL, NULL, NULL);
 | ||||||
|  | +	assert (res == ADCLI_ERR_FAIL);
 | ||||||
|  | +
 | ||||||
|  | +#ifdef BIN_CAT
 | ||||||
|  | +	argv[0] = BIN_CAT;
 | ||||||
|  | +	res = _adcli_call_external_program (argv[0], argv, "Hello",
 | ||||||
|  | +	                                    &stdout_data, &stdout_data_len);
 | ||||||
|  | +	assert (res == ADCLI_SUCCESS);
 | ||||||
|  | +	assert (strncmp ("Hello", (char *) stdout_data, stdout_data_len) == 0);
 | ||||||
|  | +	free (stdout_data);
 | ||||||
|  | +
 | ||||||
|  | +	res = _adcli_call_external_program (argv[0], argv, "Hello",
 | ||||||
|  | +	                                    NULL, NULL);
 | ||||||
|  | +	assert (res == ADCLI_SUCCESS);
 | ||||||
|  | +#endif
 | ||||||
|  | +
 | ||||||
|  | +#ifdef BIN_REV
 | ||||||
|  | +	argv[0] = BIN_REV;
 | ||||||
|  | +	res = _adcli_call_external_program (argv[0], argv, "Hello\n",
 | ||||||
|  | +	                                    &stdout_data, &stdout_data_len);
 | ||||||
|  | +	assert (res == ADCLI_SUCCESS);
 | ||||||
|  | +	assert (strncmp ("olleH\n", (char *) stdout_data, stdout_data_len) == 0);
 | ||||||
|  | +	free (stdout_data);
 | ||||||
|  | +#endif
 | ||||||
|  | +
 | ||||||
|  | +#ifdef BIN_TAC
 | ||||||
|  | +	argv[0] = BIN_TAC;
 | ||||||
|  | +	res = _adcli_call_external_program (argv[0], argv, "Hello\nWorld\n",
 | ||||||
|  | +	                                    &stdout_data, &stdout_data_len);
 | ||||||
|  | +	assert (res == ADCLI_SUCCESS);
 | ||||||
|  | +	assert (strncmp ("World\nHello\n", (char *) stdout_data, stdout_data_len) == 0);
 | ||||||
|  | +	free (stdout_data);
 | ||||||
|  | +#endif
 | ||||||
|  | +
 | ||||||
|  | +#ifdef BIN_ECHO
 | ||||||
|  | +	argv[0] = BIN_ECHO;
 | ||||||
|  | +	argv[1] = "Hello";
 | ||||||
|  | +	res = _adcli_call_external_program (argv[0], argv, NULL,
 | ||||||
|  | +	                                    &stdout_data, &stdout_data_len);
 | ||||||
|  | +	assert (res == ADCLI_SUCCESS);
 | ||||||
|  | +	assert (strncmp ("Hello\n", (char *) stdout_data, stdout_data_len) == 0);
 | ||||||
|  | +	free (stdout_data);
 | ||||||
|  | +#endif
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  int | ||||||
|  |  main (int argc, | ||||||
|  |        char *argv[]) | ||||||
|  | @@ -629,6 +839,7 @@ main (int argc,
 | ||||||
|  |  	test_func (test_strv_count, "/util/strv_count"); | ||||||
|  |  	test_func (test_check_nt_time_string_lifetime, "/util/check_nt_time_string_lifetime"); | ||||||
|  |  	test_func (test_bin_sid_to_str, "/util/bin_sid_to_str"); | ||||||
|  | +	test_func (test_call_external_program, "/util/call_external_program");
 | ||||||
|  |  	return test_run (argc, argv); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										69
									
								
								0010-library-add-_adcli_ldap_parse_sid.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								0010-library-add-_adcli_ldap_parse_sid.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | |||||||
|  | From bab08d90162c9146c1b4e8373f4b08209b84768c Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 30 Jan 2018 14:44:45 +0100 | ||||||
|  | Subject: [PATCH 10/23] library: add _adcli_ldap_parse_sid() | ||||||
|  | 
 | ||||||
|  | Get a binary SID from a LDAP message and return it in the string | ||||||
|  | representation. | ||||||
|  | 
 | ||||||
|  | https://bugs.freedesktop.org/show_bug.cgi?id=100118 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  library/adldap.c    | 24 ++++++++++++++++++++++++ | ||||||
|  |  library/adprivate.h |  4 ++++ | ||||||
|  |  2 files changed, 28 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adldap.c b/library/adldap.c
 | ||||||
|  | index 7c7a01b..07dc373 100644
 | ||||||
|  | --- a/library/adldap.c
 | ||||||
|  | +++ b/library/adldap.c
 | ||||||
|  | @@ -67,6 +67,30 @@ _adcli_ldap_handle_failure (LDAP *ldap,
 | ||||||
|  |  	return defres; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +char *
 | ||||||
|  | +_adcli_ldap_parse_sid (LDAP *ldap,
 | ||||||
|  | +                         LDAPMessage *results,
 | ||||||
|  | +                         const char *attr_name)
 | ||||||
|  | +{
 | ||||||
|  | +	LDAPMessage *entry;
 | ||||||
|  | +	struct berval **bvs;
 | ||||||
|  | +	char *val = NULL;
 | ||||||
|  | +
 | ||||||
|  | +	entry = ldap_first_entry (ldap, results);
 | ||||||
|  | +	if (entry != NULL) {
 | ||||||
|  | +		bvs = ldap_get_values_len (ldap, entry, attr_name);
 | ||||||
|  | +		if (bvs != NULL) {
 | ||||||
|  | +			if (bvs[0]) {
 | ||||||
|  | +				val = _adcli_bin_sid_to_str ( (uint8_t *) bvs[0]->bv_val,
 | ||||||
|  | +				                              bvs[0]->bv_len);
 | ||||||
|  | +				return_val_if_fail (val != NULL, NULL);
 | ||||||
|  | +			}
 | ||||||
|  | +			ldap_value_free_len (bvs);
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return val;
 | ||||||
|  | +}
 | ||||||
|  |   | ||||||
|  |  char * | ||||||
|  |  _adcli_ldap_parse_value (LDAP *ldap, | ||||||
|  | diff --git a/library/adprivate.h b/library/adprivate.h
 | ||||||
|  | index 7257c93..83a88f6 100644
 | ||||||
|  | --- a/library/adprivate.h
 | ||||||
|  | +++ b/library/adprivate.h
 | ||||||
|  | @@ -174,6 +174,10 @@ adcli_result  _adcli_ldap_handle_failure     (LDAP *ldap,
 | ||||||
|  |                                                const char *desc, | ||||||
|  |                                                ...) GNUC_PRINTF(3, 4); | ||||||
|  |   | ||||||
|  | +char *         _adcli_ldap_parse_sid         (LDAP *ldap,
 | ||||||
|  | +                                              LDAPMessage *results,
 | ||||||
|  | +                                              const char *attr_name);
 | ||||||
|  | +
 | ||||||
|  |  char *        _adcli_ldap_parse_value        (LDAP *ldap, | ||||||
|  |                                                LDAPMessage *results, | ||||||
|  |                                                const char *attr_name); | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										71
									
								
								0011-library-add-lookup_domain_sid.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								0011-library-add-lookup_domain_sid.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | |||||||
|  | From 3fa854b1439c039a2250cb24efadae6a66b0e9da Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 30 Jan 2018 14:40:46 +0100 | ||||||
|  | Subject: [PATCH 11/23] library: add lookup_domain_sid() | ||||||
|  | 
 | ||||||
|  | Read the domain SID from the default naming context AD object and store | ||||||
|  | it in adcli_conn. | ||||||
|  | 
 | ||||||
|  | https://bugs.freedesktop.org/show_bug.cgi?id=100118 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  library/adconn.c | 28 ++++++++++++++++++++++++++++ | ||||||
|  |  1 file changed, 28 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adconn.c b/library/adconn.c
 | ||||||
|  | index 67bdfd9..6b84b88 100644
 | ||||||
|  | --- a/library/adconn.c
 | ||||||
|  | +++ b/library/adconn.c
 | ||||||
|  | @@ -72,6 +72,7 @@ struct _adcli_conn_ctx {
 | ||||||
|  |  	char *domain_controller; | ||||||
|  |  	char *canonical_host; | ||||||
|  |  	char *domain_short; | ||||||
|  | +	char *domain_sid;
 | ||||||
|  |  	adcli_disco *domain_disco; | ||||||
|  |  	char *default_naming_context; | ||||||
|  |  	char *configuration_naming_context; | ||||||
|  | @@ -1068,6 +1069,32 @@ lookup_short_name (adcli_conn *conn)
 | ||||||
|  |  	} | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static void
 | ||||||
|  | +lookup_domain_sid (adcli_conn *conn)
 | ||||||
|  | +{
 | ||||||
|  | +	char *attrs[] = { "objectSid", NULL, };
 | ||||||
|  | +	LDAPMessage *results;
 | ||||||
|  | +	int ret;
 | ||||||
|  | +
 | ||||||
|  | +	free (conn->domain_sid);
 | ||||||
|  | +	conn->domain_sid = NULL;
 | ||||||
|  | +
 | ||||||
|  | +	ret = ldap_search_ext_s (conn->ldap, conn->default_naming_context, LDAP_SCOPE_BASE,
 | ||||||
|  | +	                         NULL, attrs, 0, NULL, NULL, NULL, -1, &results);
 | ||||||
|  | +	if (ret == LDAP_SUCCESS) {
 | ||||||
|  | +		conn->domain_sid = _adcli_ldap_parse_sid (conn->ldap, results, "objectSid");
 | ||||||
|  | +		ldap_msgfree (results);
 | ||||||
|  | +
 | ||||||
|  | +		if (conn->domain_sid)
 | ||||||
|  | +			_adcli_info ("Looked up domain SID: %s", conn->domain_sid);
 | ||||||
|  | +		else
 | ||||||
|  | +			_adcli_err ("No domain SID found");
 | ||||||
|  | +	} else {
 | ||||||
|  | +		_adcli_ldap_handle_failure (conn->ldap, ADCLI_ERR_DIRECTORY,
 | ||||||
|  | +		                            "Couldn't lookup domain SID");
 | ||||||
|  | +	}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static void | ||||||
|  |  conn_clear_state (adcli_conn *conn) | ||||||
|  |  { | ||||||
|  | @@ -1148,6 +1175,7 @@ adcli_conn_connect (adcli_conn *conn)
 | ||||||
|  |  		return res; | ||||||
|  |   | ||||||
|  |  	lookup_short_name (conn); | ||||||
|  | +	lookup_domain_sid (conn);
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										61
									
								
								0012-library-add-adcli_conn_get_domain_sid.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								0012-library-add-adcli_conn_get_domain_sid.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | From f98c4f92091f6a68f390078f73be3bb6ca6e6550 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 30 Jan 2018 18:23:03 +0100 | ||||||
|  | Subject: [PATCH 12/23] library: add adcli_conn_get_domain_sid() | ||||||
|  | 
 | ||||||
|  | https://bugs.freedesktop.org/show_bug.cgi?id=100118 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  library/adconn.c | 8 ++++++++ | ||||||
|  |  library/adconn.h | 2 ++ | ||||||
|  |  tools/computer.c | 1 + | ||||||
|  |  3 files changed, 11 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adconn.c b/library/adconn.c
 | ||||||
|  | index 6b84b88..d2fb1d5 100644
 | ||||||
|  | --- a/library/adconn.c
 | ||||||
|  | +++ b/library/adconn.c
 | ||||||
|  | @@ -1355,6 +1355,14 @@ adcli_conn_get_domain_short (adcli_conn *conn)
 | ||||||
|  |  	return conn->domain_short; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +const char *
 | ||||||
|  | +adcli_conn_get_domain_sid (adcli_conn *conn)
 | ||||||
|  | +{
 | ||||||
|  | +	return_val_if_fail (conn != NULL, NULL);
 | ||||||
|  | +	return conn->domain_sid;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +
 | ||||||
|  |  LDAP * | ||||||
|  |  adcli_conn_get_ldap_connection (adcli_conn *conn) | ||||||
|  |  { | ||||||
|  | diff --git a/library/adconn.h b/library/adconn.h
 | ||||||
|  | index ed1cc58..13cfd32 100644
 | ||||||
|  | --- a/library/adconn.h
 | ||||||
|  | +++ b/library/adconn.h
 | ||||||
|  | @@ -91,6 +91,8 @@ void                adcli_conn_set_domain_controller (adcli_conn *conn,
 | ||||||
|  |   | ||||||
|  |  const char *        adcli_conn_get_domain_short      (adcli_conn *conn); | ||||||
|  |   | ||||||
|  | +const char *        adcli_conn_get_domain_sid        (adcli_conn *conn);
 | ||||||
|  | +
 | ||||||
|  |  LDAP *              adcli_conn_get_ldap_connection   (adcli_conn *conn); | ||||||
|  |   | ||||||
|  |  krb5_context        adcli_conn_get_krb5_context      (adcli_conn *conn); | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index d8a58c9..a3d0f03 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -43,6 +43,7 @@ dump_details (adcli_conn *conn,
 | ||||||
|  |  	printf ("domain-realm = %s\n", adcli_conn_get_domain_realm (conn)); | ||||||
|  |  	printf ("domain-controller = %s\n", adcli_conn_get_domain_controller (conn)); | ||||||
|  |  	printf ("domain-short = %s\n", adcli_conn_get_domain_short (conn)); | ||||||
|  | +	printf ("domain-SID = %s\n", adcli_conn_get_domain_sid (conn));
 | ||||||
|  |  	printf ("naming-context = %s\n", adcli_conn_get_default_naming_context (conn)); | ||||||
|  |  	printf ("domain-ou = %s\n", adcli_enroll_get_domain_ou (enroll)); | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										142
									
								
								0013-tools-add-option-add-samba-data.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								0013-tools-add-option-add-samba-data.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,142 @@ | |||||||
|  | From d362a0799618b576918f5c5d0625565484670ba2 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 30 Jan 2018 14:46:00 +0100 | ||||||
|  | Subject: [PATCH 13/23] tools: add option --add-samba-data | ||||||
|  | 
 | ||||||
|  | https://bugs.freedesktop.org/show_bug.cgi?id=100118 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml      | 30 ++++++++++++++++++++++++++++++ | ||||||
|  |  library/adenroll.h |  1 + | ||||||
|  |  tools/computer.c   | 12 ++++++++++++ | ||||||
|  |  3 files changed, 43 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index c54cc1b..fbc6c63 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -292,6 +292,21 @@ Password for Administrator:
 | ||||||
|  |  			machine account password. This is output in a format that should | ||||||
|  |  			be both human and machine readable.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--add-samba-data</option></term>
 | ||||||
|  | +			<listitem><para>After a successful join add the domain
 | ||||||
|  | +			SID and the machine account password to the Samba
 | ||||||
|  | +			specific databases by calling Samba's
 | ||||||
|  | +			<command>net</command> utility.</para>
 | ||||||
|  | +
 | ||||||
|  | +			<para>Please note that Samba's <command>net</command>
 | ||||||
|  | +			requires some settings in <filename>smb.conf</filename>
 | ||||||
|  | +			to create the database entries correctly. Most
 | ||||||
|  | +			important here is currently the
 | ||||||
|  | +			<option>workgroup</option> option, see
 | ||||||
|  | +			<citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
 | ||||||
|  | +			for details.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  |  	</variablelist> | ||||||
|  |   | ||||||
|  |  </refsect1> | ||||||
|  | @@ -382,6 +397,21 @@ $ adcli update --login-ccache=/tmp/krbcc_123
 | ||||||
|  |  			about join operation. This is output in a format that should | ||||||
|  |  			be both human and machine readable.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--add-samba-data</option></term>
 | ||||||
|  | +			<listitem><para>After a successful join add the domain
 | ||||||
|  | +			SID and the machine account password to the Samba
 | ||||||
|  | +			specific databases by calling Samba's
 | ||||||
|  | +			<command>net</command> utility.</para>
 | ||||||
|  | +
 | ||||||
|  | +			<para>Please note that Samba's <command>net</command>
 | ||||||
|  | +			requires some settings in <filename>smb.conf</filename>
 | ||||||
|  | +			to create the database entries correctly. Most
 | ||||||
|  | +			important here is currently the
 | ||||||
|  | +			<option>workgroup</option> option, see
 | ||||||
|  | +			<citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
 | ||||||
|  | +			for details.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  |  	</variablelist> | ||||||
|  |   | ||||||
|  |  </refsect1> | ||||||
|  | diff --git a/library/adenroll.h b/library/adenroll.h
 | ||||||
|  | index 9a107ab..32c9764 100644
 | ||||||
|  | --- a/library/adenroll.h
 | ||||||
|  | +++ b/library/adenroll.h
 | ||||||
|  | @@ -30,6 +30,7 @@ typedef enum {
 | ||||||
|  |  	ADCLI_ENROLL_NO_KEYTAB = 1 << 1, | ||||||
|  |  	ADCLI_ENROLL_ALLOW_OVERWRITE = 1 << 2, | ||||||
|  |  	ADCLI_ENROLL_PASSWORD_VALID = 1 << 3, | ||||||
|  | +	ADCLI_ENROLL_ADD_SAMBA_DATA = 1 << 3,
 | ||||||
|  |  } adcli_enroll_flags; | ||||||
|  |   | ||||||
|  |  typedef struct _adcli_enroll adcli_enroll; | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index a3d0f03..fc646f2 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -106,6 +106,7 @@ typedef enum {
 | ||||||
|  |  	opt_os_service_pack, | ||||||
|  |  	opt_user_principal, | ||||||
|  |  	opt_computer_password_lifetime, | ||||||
|  | +	opt_add_samba_data,
 | ||||||
|  |  } Option; | ||||||
|  |   | ||||||
|  |  static adcli_tool_desc common_usages[] = { | ||||||
|  | @@ -142,6 +143,8 @@ static adcli_tool_desc common_usages[] = {
 | ||||||
|  |  	                     "a successful join" }, | ||||||
|  |  	{ opt_show_password, "show computer account password after after a\n" | ||||||
|  |  	                     "successful join" }, | ||||||
|  | +	{ opt_add_samba_data, "add domain SID and computer account password\n"
 | ||||||
|  | +	                      "to the Samba specific configuration database" },
 | ||||||
|  |  	{ opt_verbose, "show verbose progress and failure messages", }, | ||||||
|  |  	{ 0 }, | ||||||
|  |  }; | ||||||
|  | @@ -269,6 +272,7 @@ parse_option (Option opt,
 | ||||||
|  |  	case opt_show_details: | ||||||
|  |  	case opt_show_password: | ||||||
|  |  	case opt_one_time_password: | ||||||
|  | +	case opt_add_samba_data:
 | ||||||
|  |  		assert (0 && "not reached"); | ||||||
|  |  		break; | ||||||
|  |  	} | ||||||
|  | @@ -326,6 +330,7 @@ adcli_tool_computer_join (adcli_conn *conn,
 | ||||||
|  |  		{ "user-principal", optional_argument, NULL, opt_user_principal }, | ||||||
|  |  		{ "show-details", no_argument, NULL, opt_show_details }, | ||||||
|  |  		{ "show-password", no_argument, NULL, opt_show_password }, | ||||||
|  | +		{ "add-samba-data", no_argument, NULL, opt_add_samba_data },
 | ||||||
|  |  		{ "verbose", no_argument, NULL, opt_verbose }, | ||||||
|  |  		{ "help", no_argument, NULL, 'h' }, | ||||||
|  |  		{ 0 }, | ||||||
|  | @@ -352,6 +357,9 @@ adcli_tool_computer_join (adcli_conn *conn,
 | ||||||
|  |  		case opt_show_password: | ||||||
|  |  			show_password = 1; | ||||||
|  |  			break; | ||||||
|  | +		case opt_add_samba_data:
 | ||||||
|  | +			flags |= ADCLI_ENROLL_ADD_SAMBA_DATA;
 | ||||||
|  | +			break;
 | ||||||
|  |  		case 'h': | ||||||
|  |  		case '?': | ||||||
|  |  		case ':': | ||||||
|  | @@ -425,6 +433,7 @@ adcli_tool_computer_update (adcli_conn *conn,
 | ||||||
|  |  		{ "computer-password-lifetime", optional_argument, NULL, opt_computer_password_lifetime }, | ||||||
|  |  		{ "show-details", no_argument, NULL, opt_show_details }, | ||||||
|  |  		{ "show-password", no_argument, NULL, opt_show_password }, | ||||||
|  | +		{ "add-samba-data", no_argument, NULL, opt_add_samba_data },
 | ||||||
|  |  		{ "verbose", no_argument, NULL, opt_verbose }, | ||||||
|  |  		{ "help", no_argument, NULL, 'h' }, | ||||||
|  |  		{ 0 }, | ||||||
|  | @@ -447,6 +456,9 @@ adcli_tool_computer_update (adcli_conn *conn,
 | ||||||
|  |  		case opt_show_password: | ||||||
|  |  			show_password = 1; | ||||||
|  |  			break; | ||||||
|  | +		case opt_add_samba_data:
 | ||||||
|  | +			flags |= ADCLI_ENROLL_ADD_SAMBA_DATA;
 | ||||||
|  | +			break;
 | ||||||
|  |  		case 'h': | ||||||
|  |  		case '?': | ||||||
|  |  		case ':': | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										75
									
								
								0014-tools-store-Samba-data-if-requested.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								0014-tools-store-Samba-data-if-requested.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,75 @@ | |||||||
|  | From c090131e4f912f6f6c4f79eb40fbe500eb31c171 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Tue, 30 Jan 2018 18:24:15 +0100 | ||||||
|  | Subject: [PATCH 14/23] tools: store Samba data if requested | ||||||
|  | 
 | ||||||
|  | Use Samba's net utility to add the machine account password and the | ||||||
|  | domain SID to the Samba configuration. | ||||||
|  | 
 | ||||||
|  | https://bugs.freedesktop.org/show_bug.cgi?id=100118 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 39 +++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  1 file changed, 39 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index bb970d1..20731cd 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -1533,6 +1533,36 @@ update_keytab_for_principals (adcli_enroll *enroll)
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static adcli_result
 | ||||||
|  | +update_samba_data (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	int ret;
 | ||||||
|  | +	char *argv_pw[] = { "/usr/bin/net", "changesecretpw", "-i", "-f", NULL };
 | ||||||
|  | +	char *argv_sid[] = { "/usr/bin/net", "setdomainsid", NULL, NULL };
 | ||||||
|  | +
 | ||||||
|  | +	_adcli_info ("Trying to set Samba secret.\n");
 | ||||||
|  | +	ret = _adcli_call_external_program (argv_pw[0], argv_pw,
 | ||||||
|  | +	                                    enroll->computer_password, NULL, NULL);
 | ||||||
|  | +	if (ret != ADCLI_SUCCESS) {
 | ||||||
|  | +		_adcli_err ("Failed to set Samba computer account password.\n");
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	argv_sid[2] = (char *) adcli_conn_get_domain_sid (enroll->conn);
 | ||||||
|  | +	if (argv_sid[2] == NULL) {
 | ||||||
|  | +		_adcli_err ("Domain SID not available.\n");
 | ||||||
|  | +	} else {
 | ||||||
|  | +		_adcli_info ("Trying to set domain SID %s for Samba.\n",
 | ||||||
|  | +		             argv_sid[2]);
 | ||||||
|  | +		ret = _adcli_call_external_program (argv_sid[0], argv_sid,
 | ||||||
|  | +		                                    NULL, NULL, NULL);
 | ||||||
|  | +		if (ret != ADCLI_SUCCESS) {
 | ||||||
|  | +			_adcli_err ("Failed to set Samba domain SID.\n");
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return ret;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static void | ||||||
|  |  enroll_clear_state (adcli_enroll *enroll) | ||||||
|  |  { | ||||||
|  | @@ -1687,6 +1717,15 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
 | ||||||
|  |  	update_computer_account (enroll); | ||||||
|  |  	update_service_principals (enroll); | ||||||
|  |   | ||||||
|  | +	if ( (flags & ADCLI_ENROLL_ADD_SAMBA_DATA) && ! (flags & ADCLI_ENROLL_PASSWORD_VALID)) {
 | ||||||
|  | +		res = update_samba_data (enroll);
 | ||||||
|  | +		if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +			_adcli_info ("Failed to add Samba specific data, smbd "
 | ||||||
|  | +			             "or winbindd might not work as "
 | ||||||
|  | +			             "expected.\n");
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	if (flags & ADCLI_ENROLL_NO_KEYTAB) | ||||||
|  |  		return ADCLI_SUCCESS; | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										292
									
								
								0015-make-Samba-data-tool-configurable.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										292
									
								
								0015-make-Samba-data-tool-configurable.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,292 @@ | |||||||
|  | From 9b73f79a2436760b8278377014bf78a144a427ae Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 1 Feb 2018 14:26:22 +0100 | ||||||
|  | Subject: [PATCH 15/23] make Samba data tool configurable | ||||||
|  | 
 | ||||||
|  | Allow to specify an alternative path to Samba's net utility at configure | ||||||
|  | time and at run time. | ||||||
|  | 
 | ||||||
|  | https://bugs.freedesktop.org/show_bug.cgi?id=100118 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  configure.ac                    | 13 ++++++++++++ | ||||||
|  |  doc/adcli.xml                   | 21 ++++++++++++++++++- | ||||||
|  |  doc/samba_data_tool_path.xml.in |  1 + | ||||||
|  |  library/adenroll.c              | 46 ++++++++++++++++++++++++++++++++++------- | ||||||
|  |  library/adenroll.h              |  5 +++++ | ||||||
|  |  tools/computer.c                | 16 ++++++++++++++ | ||||||
|  |  7 files changed, 95 insertions(+), 8 deletions(-) | ||||||
|  |  create mode 100644 doc/samba_data_tool_path.xml.in | ||||||
|  | 
 | ||||||
|  | diff --git a/configure.ac b/configure.ac
 | ||||||
|  | index fe86638..68877c7 100644
 | ||||||
|  | --- a/configure.ac
 | ||||||
|  | +++ b/configure.ac
 | ||||||
|  | @@ -291,6 +291,18 @@ else
 | ||||||
|  |  	AC_DEFINE_UNQUOTED(BIN_ECHO, "$BIN_ECHO", [path to echo, used in unit test]) | ||||||
|  |  fi | ||||||
|  |   | ||||||
|  | +AC_MSG_CHECKING([where is Samba's net utility])
 | ||||||
|  | +AC_ARG_WITH([samba_data_tool],
 | ||||||
|  | +              AC_HELP_STRING([--with-samba-data-tool=/path],
 | ||||||
|  | +              [Path to Samba's net utility]),
 | ||||||
|  | +              [],
 | ||||||
|  | +              [with_samba_data_tool=/usr/bin/net])
 | ||||||
|  | +AC_MSG_RESULT([$with_samba_data_tool])
 | ||||||
|  | +
 | ||||||
|  | +AC_DEFINE_UNQUOTED(SAMBA_DATA_TOOL, "$with_samba_data_tool",
 | ||||||
|  | +                   [Path to Samba's net utility])
 | ||||||
|  | +
 | ||||||
|  | +AC_SUBST(SAMBA_DATA_TOOL, [$with_samba_data_tool])
 | ||||||
|  |  # --------------------------------------------------------------------- | ||||||
|  |   | ||||||
|  |  ADCLI_LT_RELEASE=$ADCLI_CURRENT:$ADCLI_REVISION:$ADCLI_AGE | ||||||
|  | @@ -300,6 +312,7 @@ AC_CONFIG_FILES([Makefile
 | ||||||
|  |  	build/Makefile | ||||||
|  |  	doc/Makefile | ||||||
|  |  	doc/version.xml | ||||||
|  | +	doc/samba_data_tool_path.xml
 | ||||||
|  |  	library/Makefile | ||||||
|  |  	tools/Makefile | ||||||
|  |  ]) | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index fbc6c63..c2b7760 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -1,6 +1,9 @@
 | ||||||
|  |  <?xml version='1.0'?> | ||||||
|  |  <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" | ||||||
|  | -	"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
 | ||||||
|  | +	"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
 | ||||||
|  | +[
 | ||||||
|  | +	<!ENTITY samba_data_tool SYSTEM "samba_data_tool_path.xml">
 | ||||||
|  | +]>
 | ||||||
|  |   | ||||||
|  |  <refentry id="adcli"> | ||||||
|  |   | ||||||
|  | @@ -307,6 +310,14 @@ Password for Administrator:
 | ||||||
|  |  			<citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> | ||||||
|  |  			for details.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term>
 | ||||||
|  | +			<listitem><para>If Samba's <command>net</command>
 | ||||||
|  | +			cannot be found at
 | ||||||
|  | +			<filename>&samba_data_tool;</filename> this option can
 | ||||||
|  | +			be used to specific an alternative location with the
 | ||||||
|  | +			help of an absolute path.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  |  	</variablelist> | ||||||
|  |   | ||||||
|  |  </refsect1> | ||||||
|  | @@ -412,6 +423,14 @@ $ adcli update --login-ccache=/tmp/krbcc_123
 | ||||||
|  |  			<citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> | ||||||
|  |  			for details.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term>
 | ||||||
|  | +			<listitem><para>If Samba's <command>net</command>
 | ||||||
|  | +			cannot be found at
 | ||||||
|  | +			<filename>&samba_data_tool;</filename> this option can
 | ||||||
|  | +			be used to specific an alternative location with the
 | ||||||
|  | +			help of an absolute path.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  |  	</variablelist> | ||||||
|  |   | ||||||
|  |  </refsect1> | ||||||
|  | diff --git a/doc/samba_data_tool_path.xml.in b/doc/samba_data_tool_path.xml.in
 | ||||||
|  | new file mode 100644 | ||||||
|  | index 0000000..a667c57
 | ||||||
|  | --- /dev/null
 | ||||||
|  | +++ b/doc/samba_data_tool_path.xml.in
 | ||||||
|  | @@ -0,0 +1 @@
 | ||||||
|  | +@SAMBA_DATA_TOOL@
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 20731cd..a693049 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -42,6 +42,10 @@
 | ||||||
|  |  #include <stdio.h> | ||||||
|  |  #include <unistd.h> | ||||||
|  |   | ||||||
|  | +#ifndef SAMBA_DATA_TOOL
 | ||||||
|  | +#define SAMBA_DATA_TOOL "/usr/bin/net"
 | ||||||
|  | +#endif
 | ||||||
|  | +
 | ||||||
|  |  static krb5_enctype v60_later_enctypes[] = { | ||||||
|  |  	ENCTYPE_AES256_CTS_HMAC_SHA1_96, | ||||||
|  |  	ENCTYPE_AES128_CTS_HMAC_SHA1_96, | ||||||
|  | @@ -100,6 +104,7 @@ struct _adcli_enroll {
 | ||||||
|  |  	int keytab_enctypes_explicit; | ||||||
|  |  	unsigned int computer_password_lifetime; | ||||||
|  |  	int computer_password_lifetime_explicit; | ||||||
|  | +	char *samba_data_tool;
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static adcli_result | ||||||
|  | @@ -1537,26 +1542,33 @@ static adcli_result
 | ||||||
|  |  update_samba_data (adcli_enroll *enroll) | ||||||
|  |  { | ||||||
|  |  	int ret; | ||||||
|  | -	char *argv_pw[] = { "/usr/bin/net", "changesecretpw", "-i", "-f", NULL };
 | ||||||
|  | -	char *argv_sid[] = { "/usr/bin/net", "setdomainsid", NULL, NULL };
 | ||||||
|  | +	char *argv_pw[] = { NULL, "changesecretpw", "-i", "-f", NULL };
 | ||||||
|  | +	char *argv_sid[] = { NULL, "setdomainsid", NULL, NULL };
 | ||||||
|  | +
 | ||||||
|  | +	argv_pw[0] = (char *) adcli_enroll_get_samba_data_tool (enroll);
 | ||||||
|  | +	if (argv_pw[0] ==NULL) {
 | ||||||
|  | +		_adcli_err ("Samba data tool not available.");
 | ||||||
|  | +		return ADCLI_ERR_FAIL;
 | ||||||
|  | +	}
 | ||||||
|  | +	argv_sid[0] = argv_pw[0];
 | ||||||
|  |   | ||||||
|  | -	_adcli_info ("Trying to set Samba secret.\n");
 | ||||||
|  | +	_adcli_info ("Trying to set Samba secret.");
 | ||||||
|  |  	ret = _adcli_call_external_program (argv_pw[0], argv_pw, | ||||||
|  |  	                                    enroll->computer_password, NULL, NULL); | ||||||
|  |  	if (ret != ADCLI_SUCCESS) { | ||||||
|  | -		_adcli_err ("Failed to set Samba computer account password.\n");
 | ||||||
|  | +		_adcli_err ("Failed to set Samba computer account password.");
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	argv_sid[2] = (char *) adcli_conn_get_domain_sid (enroll->conn); | ||||||
|  |  	if (argv_sid[2] == NULL) { | ||||||
|  | -		_adcli_err ("Domain SID not available.\n");
 | ||||||
|  | +		_adcli_err ("Domain SID not available.");
 | ||||||
|  |  	} else { | ||||||
|  | -		_adcli_info ("Trying to set domain SID %s for Samba.\n",
 | ||||||
|  | +		_adcli_info ("Trying to set domain SID %s for Samba.",
 | ||||||
|  |  		             argv_sid[2]); | ||||||
|  |  		ret = _adcli_call_external_program (argv_sid[0], argv_sid, | ||||||
|  |  		                                    NULL, NULL, NULL); | ||||||
|  |  		if (ret != ADCLI_SUCCESS) { | ||||||
|  | -			_adcli_err ("Failed to set Samba domain SID.\n");
 | ||||||
|  | +			_adcli_err ("Failed to set Samba domain SID.");
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -1951,6 +1963,9 @@ adcli_enroll_new (adcli_conn *conn)
 | ||||||
|  |  	enroll->os_name = strdup (value); | ||||||
|  |  	return_val_if_fail (enroll->os_name != NULL, NULL); | ||||||
|  |   | ||||||
|  | +	enroll->samba_data_tool = strdup (SAMBA_DATA_TOOL);
 | ||||||
|  | +	return_val_if_fail (enroll->samba_data_tool != NULL, NULL);
 | ||||||
|  | +
 | ||||||
|  |  	return enroll; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -1978,6 +1993,7 @@ enroll_free (adcli_enroll *enroll)
 | ||||||
|  |  	free (enroll->os_name); | ||||||
|  |  	free (enroll->os_version); | ||||||
|  |  	free (enroll->os_service_pack); | ||||||
|  | +	free (enroll->samba_data_tool);
 | ||||||
|  |   | ||||||
|  |  	free (enroll->user_principal); | ||||||
|  |  	_adcli_strv_free (enroll->service_names); | ||||||
|  | @@ -2343,3 +2359,19 @@ adcli_enroll_set_computer_password_lifetime (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  	enroll->computer_password_lifetime_explicit = 1; | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +adcli_enroll_set_samba_data_tool (adcli_enroll *enroll, const char *value)
 | ||||||
|  | +{
 | ||||||
|  | +	return_if_fail (enroll != NULL);
 | ||||||
|  | +	if (value != NULL && value[0] != '\0') {
 | ||||||
|  | +		_adcli_str_set (&enroll->samba_data_tool, value);
 | ||||||
|  | +	}
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +const char *
 | ||||||
|  | +adcli_enroll_get_samba_data_tool (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	return_val_if_fail (enroll != NULL, NULL);
 | ||||||
|  | +	return enroll->samba_data_tool;
 | ||||||
|  | +}
 | ||||||
|  | diff --git a/library/adenroll.h b/library/adenroll.h
 | ||||||
|  | index 32c9764..31ca0bc 100644
 | ||||||
|  | --- a/library/adenroll.h
 | ||||||
|  | +++ b/library/adenroll.h
 | ||||||
|  | @@ -141,4 +141,9 @@ const char *       adcli_enroll_get_os_service_pack     (adcli_enroll *enroll);
 | ||||||
|  |  void               adcli_enroll_set_os_service_pack     (adcli_enroll *enroll, | ||||||
|  |                                                           const char *value); | ||||||
|  |   | ||||||
|  | +void               adcli_enroll_set_samba_data_tool     (adcli_enroll *enroll,
 | ||||||
|  | +                                                         const char *value);
 | ||||||
|  | +
 | ||||||
|  | +const char *       adcli_enroll_get_samba_data_tool     (adcli_enroll *enroll);
 | ||||||
|  | +
 | ||||||
|  |  #endif /* ADENROLL_H_ */ | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index fc646f2..f86548b 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -30,6 +30,7 @@
 | ||||||
|  |  #include <err.h> | ||||||
|  |  #include <stdio.h> | ||||||
|  |  #include <errno.h> | ||||||
|  | +#include <unistd.h>
 | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  |  dump_details (adcli_conn *conn, | ||||||
|  | @@ -107,6 +108,7 @@ typedef enum {
 | ||||||
|  |  	opt_user_principal, | ||||||
|  |  	opt_computer_password_lifetime, | ||||||
|  |  	opt_add_samba_data, | ||||||
|  | +	opt_samba_data_tool,
 | ||||||
|  |  } Option; | ||||||
|  |   | ||||||
|  |  static adcli_tool_desc common_usages[] = { | ||||||
|  | @@ -145,6 +147,7 @@ static adcli_tool_desc common_usages[] = {
 | ||||||
|  |  	                     "successful join" }, | ||||||
|  |  	{ opt_add_samba_data, "add domain SID and computer account password\n" | ||||||
|  |  	                      "to the Samba specific configuration database" }, | ||||||
|  | +	{ opt_samba_data_tool, "Absolute path to the tool used for add-samba-data" },
 | ||||||
|  |  	{ opt_verbose, "show verbose progress and failure messages", }, | ||||||
|  |  	{ 0 }, | ||||||
|  |  }; | ||||||
|  | @@ -160,6 +163,7 @@ parse_option (Option opt,
 | ||||||
|  |  	static int stdin_password = 0; | ||||||
|  |  	char *endptr; | ||||||
|  |  	unsigned int lifetime; | ||||||
|  | +	int ret;
 | ||||||
|  |   | ||||||
|  |  	switch (opt) { | ||||||
|  |  	case opt_login_ccache: | ||||||
|  | @@ -265,6 +269,16 @@ parse_option (Option opt,
 | ||||||
|  |   | ||||||
|  |  		adcli_enroll_set_computer_password_lifetime (enroll, lifetime); | ||||||
|  |  		return; | ||||||
|  | +	case opt_samba_data_tool:
 | ||||||
|  | +		errno = 0;
 | ||||||
|  | +		ret = access (optarg, X_OK);
 | ||||||
|  | +		if (ret != 0) {
 | ||||||
|  | +			ret = errno;
 | ||||||
|  | +			errx (EUSAGE, "Failed to access tool to add Samba data: %s", strerror (ret));
 | ||||||
|  | +		} else {
 | ||||||
|  | +			adcli_enroll_set_samba_data_tool (enroll, optarg);
 | ||||||
|  | +		}
 | ||||||
|  | +		return;
 | ||||||
|  |  	case opt_verbose: | ||||||
|  |  		return; | ||||||
|  |   | ||||||
|  | @@ -331,6 +345,7 @@ adcli_tool_computer_join (adcli_conn *conn,
 | ||||||
|  |  		{ "show-details", no_argument, NULL, opt_show_details }, | ||||||
|  |  		{ "show-password", no_argument, NULL, opt_show_password }, | ||||||
|  |  		{ "add-samba-data", no_argument, NULL, opt_add_samba_data }, | ||||||
|  | +		{ "samba-data-tool", no_argument, NULL, opt_samba_data_tool },
 | ||||||
|  |  		{ "verbose", no_argument, NULL, opt_verbose }, | ||||||
|  |  		{ "help", no_argument, NULL, 'h' }, | ||||||
|  |  		{ 0 }, | ||||||
|  | @@ -434,6 +449,7 @@ adcli_tool_computer_update (adcli_conn *conn,
 | ||||||
|  |  		{ "show-details", no_argument, NULL, opt_show_details }, | ||||||
|  |  		{ "show-password", no_argument, NULL, opt_show_password }, | ||||||
|  |  		{ "add-samba-data", no_argument, NULL, opt_add_samba_data }, | ||||||
|  | +		{ "samba-data-tool", no_argument, NULL, opt_samba_data_tool },
 | ||||||
|  |  		{ "verbose", no_argument, NULL, opt_verbose }, | ||||||
|  |  		{ "help", no_argument, NULL, 'h' }, | ||||||
|  |  		{ 0 }, | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										247
									
								
								0016-Add-trusted-for-delegation-option.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										247
									
								
								0016-Add-trusted-for-delegation-option.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,247 @@ | |||||||
|  | From f306f2f20c1d35fac63d27147824f039f7ef2d67 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 31 May 2018 18:27:37 +0200 | ||||||
|  | Subject: [PATCH 16/23] Add trusted-for-delegation option | ||||||
|  | 
 | ||||||
|  | Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1538730 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml      | 14 ++++++++++ | ||||||
|  |  library/adenroll.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- | ||||||
|  |  library/adenroll.h |  4 +++ | ||||||
|  |  tools/computer.c   | 12 ++++++++ | ||||||
|  |  4 files changed, 108 insertions(+), 2 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index c2b7760..b246190 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -283,6 +283,13 @@ Password for Administrator:
 | ||||||
|  |  			<option>--login-type=computer</option> and providing a | ||||||
|  |  			password as input.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--trusted-for-delegation=<parameter>yes|no|true|false</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Set or unset the TRUSTED_FOR_DELEGATION
 | ||||||
|  | +			flag in the userAccountControl attribute to allow or
 | ||||||
|  | +			not allow that Kerberos tickets can be forwarded to the
 | ||||||
|  | +			host.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>--show-details</option></term> | ||||||
|  |  			<listitem><para>After a successful join print out information | ||||||
|  | @@ -402,6 +409,13 @@ $ adcli update --login-ccache=/tmp/krbcc_123
 | ||||||
|  |  			in days. By default the password is updated if it is | ||||||
|  |  			older than 30 days.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--trusted-for-delegation=<parameter>yes|no|true|false</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Set or unset the TRUSTED_FOR_DELEGATION
 | ||||||
|  | +			flag in the userAccountControl attribute to allow or
 | ||||||
|  | +			not allow that Kerberos tickets can be forwarded to the
 | ||||||
|  | +			host.</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 a693049..eca3c37 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -63,6 +63,13 @@ static krb5_enctype v51_earlier_enctypes[] = {
 | ||||||
|  |  	0 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +/* 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_WORKSTATION_TRUST_ACCOUNT  0x1000
 | ||||||
|  | +#define UAC_DONT_EXPIRE_PASSWORD      0x10000
 | ||||||
|  | +#define UAC_TRUSTED_FOR_DELEGATION    0x80000
 | ||||||
|  | +
 | ||||||
|  |  struct _adcli_enroll { | ||||||
|  |  	int refs; | ||||||
|  |  	adcli_conn *conn; | ||||||
|  | @@ -105,6 +112,7 @@ struct _adcli_enroll {
 | ||||||
|  |  	unsigned int computer_password_lifetime; | ||||||
|  |  	int computer_password_lifetime_explicit; | ||||||
|  |  	char *samba_data_tool; | ||||||
|  | +	bool trusted_for_delegation;
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static adcli_result | ||||||
|  | @@ -538,6 +546,10 @@ create_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  		NULL, | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  | +	if (adcli_enroll_get_trusted_for_delegation (enroll)) {
 | ||||||
|  | +		vals_userAccountControl[0] = "593920"; /* WORKSTATION_TRUST_ACCOUNT | DONT_EXPIRE_PASSWD | TRUSTED_FOR_DELEGATION */
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	ret = ldap_add_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL); | ||||||
|  |   | ||||||
|  |  	/* | ||||||
|  | @@ -971,6 +983,7 @@ retrieve_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  		"operatingSystemVersion", | ||||||
|  |  		"operatingSystemServicePack", | ||||||
|  |  		"pwdLastSet", | ||||||
|  | +		"userAccountControl",
 | ||||||
|  |  		NULL, | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  | @@ -1149,6 +1162,47 @@ update_computer_attribute (adcli_enroll *enroll,
 | ||||||
|  |  	return res; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static char *get_user_account_control (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	uint32_t uac = 0;
 | ||||||
|  | +	unsigned long attr_val;
 | ||||||
|  | +	char *uac_str;
 | ||||||
|  | +	LDAP *ldap;
 | ||||||
|  | +	char *end;
 | ||||||
|  | +
 | ||||||
|  | +	ldap = adcli_conn_get_ldap_connection (enroll->conn);
 | ||||||
|  | +	return_val_if_fail (ldap != NULL, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	uac_str = _adcli_ldap_parse_value (ldap, enroll->computer_attributes, "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 computer account in directory: %s, assuming 0",
 | ||||||
|  | +			            uac_str, enroll->computer_dn);
 | ||||||
|  | +		} else {
 | ||||||
|  | +			uac = attr_val;
 | ||||||
|  | +		}
 | ||||||
|  | +		free (uac_str);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (uac == 0) {
 | ||||||
|  | +		uac = UAC_WORKSTATION_TRUST_ACCOUNT | UAC_DONT_EXPIRE_PASSWORD;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (adcli_enroll_get_trusted_for_delegation (enroll)) {
 | ||||||
|  | +		uac |= UAC_TRUSTED_FOR_DELEGATION;
 | ||||||
|  | +	} else {
 | ||||||
|  | +		uac &= ~(UAC_TRUSTED_FOR_DELEGATION);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (asprintf (&uac_str, "%d", uac) < 0) {
 | ||||||
|  | +		return_val_if_reached (NULL);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return uac_str;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static void | ||||||
|  |  update_computer_account (adcli_enroll *enroll) | ||||||
|  |  { | ||||||
|  | @@ -1167,11 +1221,16 @@ update_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (res == ADCLI_SUCCESS) { | ||||||
|  | -		char *vals_userAccountControl[] = { "69632", NULL }; /* WORKSTATION_TRUST_ACCOUNT | DONT_EXPIRE_PASSWD */
 | ||||||
|  | +		char *vals_userAccountControl[] = { NULL , NULL };
 | ||||||
|  |  		LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } }; | ||||||
|  |  		LDAPMod *mods[] = { &userAccountControl, NULL }; | ||||||
|  |   | ||||||
|  | -		res |= update_computer_attribute (enroll, ldap, mods);
 | ||||||
|  | +		vals_userAccountControl[0] = get_user_account_control (enroll);
 | ||||||
|  | +		if (vals_userAccountControl[0] != NULL) {
 | ||||||
|  | +			res |= update_computer_attribute (enroll, ldap, mods);
 | ||||||
|  | +		} else {
 | ||||||
|  | +			_adcli_warn ("Cannot update userAccountControl");
 | ||||||
|  | +		}
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (res == ADCLI_SUCCESS) { | ||||||
|  | @@ -2375,3 +2434,20 @@ adcli_enroll_get_samba_data_tool (adcli_enroll *enroll)
 | ||||||
|  |  	return_val_if_fail (enroll != NULL, NULL); | ||||||
|  |  	return enroll->samba_data_tool; | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +bool
 | ||||||
|  | +adcli_enroll_get_trusted_for_delegation (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	return_val_if_fail (enroll != NULL, false);
 | ||||||
|  | +
 | ||||||
|  | +	return enroll->trusted_for_delegation;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
 | ||||||
|  | +                                         bool value)
 | ||||||
|  | +{
 | ||||||
|  | +	return_if_fail (enroll != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	enroll->trusted_for_delegation = value;
 | ||||||
|  | +}
 | ||||||
|  | diff --git a/library/adenroll.h b/library/adenroll.h
 | ||||||
|  | index 31ca0bc..be2ca18 100644
 | ||||||
|  | --- a/library/adenroll.h
 | ||||||
|  | +++ b/library/adenroll.h
 | ||||||
|  | @@ -109,6 +109,10 @@ unsigned int       adcli_enroll_get_computer_password_lifetime (adcli_enroll *en
 | ||||||
|  |  void               adcli_enroll_set_computer_password_lifetime (adcli_enroll *enroll, | ||||||
|  |                                                           unsigned int lifetime); | ||||||
|  |   | ||||||
|  | +bool               adcli_enroll_get_trusted_for_delegation (adcli_enroll *enroll);
 | ||||||
|  | +void               adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
 | ||||||
|  | +                                                            bool value);
 | ||||||
|  | +
 | ||||||
|  |  krb5_kvno          adcli_enroll_get_kvno                (adcli_enroll *enroll); | ||||||
|  |   | ||||||
|  |  void               adcli_enroll_set_kvno                (adcli_enroll *enroll, | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index f86548b..b905fd1 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -109,6 +109,7 @@ typedef enum {
 | ||||||
|  |  	opt_computer_password_lifetime, | ||||||
|  |  	opt_add_samba_data, | ||||||
|  |  	opt_samba_data_tool, | ||||||
|  | +	opt_trusted_for_delegation,
 | ||||||
|  |  } Option; | ||||||
|  |   | ||||||
|  |  static adcli_tool_desc common_usages[] = { | ||||||
|  | @@ -135,6 +136,8 @@ static adcli_tool_desc common_usages[] = {
 | ||||||
|  |  	{ opt_os_service_pack, "the computer operating system service pack", }, | ||||||
|  |  	{ opt_user_principal, "add an authentication principal to the account", }, | ||||||
|  |  	{ 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_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" | ||||||
|  | @@ -279,6 +282,13 @@ parse_option (Option opt,
 | ||||||
|  |  			adcli_enroll_set_samba_data_tool (enroll, optarg); | ||||||
|  |  		} | ||||||
|  |  		return; | ||||||
|  | +	case opt_trusted_for_delegation:
 | ||||||
|  | +		if (strcasecmp (optarg, "true") == 0 || strcasecmp (optarg, "yes") == 0) {
 | ||||||
|  | +			adcli_enroll_set_trusted_for_delegation (enroll, true);
 | ||||||
|  | +		} else {
 | ||||||
|  | +			adcli_enroll_set_trusted_for_delegation (enroll, false);
 | ||||||
|  | +		}
 | ||||||
|  | +		return;
 | ||||||
|  |  	case opt_verbose: | ||||||
|  |  		return; | ||||||
|  |   | ||||||
|  | @@ -342,6 +352,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 }, | ||||||
|  |  		{ "user-principal", optional_argument, NULL, opt_user_principal }, | ||||||
|  | +		{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation },
 | ||||||
|  |  		{ "show-details", no_argument, NULL, opt_show_details }, | ||||||
|  |  		{ "show-password", no_argument, NULL, opt_show_password }, | ||||||
|  |  		{ "add-samba-data", no_argument, NULL, opt_add_samba_data }, | ||||||
|  | @@ -446,6 +457,7 @@ adcli_tool_computer_update (adcli_conn *conn,
 | ||||||
|  |  		{ "os-service-pack", optional_argument, NULL, opt_os_service_pack }, | ||||||
|  |  		{ "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 },
 | ||||||
|  |  		{ "show-details", no_argument, NULL, opt_show_details }, | ||||||
|  |  		{ "show-password", no_argument, NULL, opt_show_password }, | ||||||
|  |  		{ "add-samba-data", no_argument, NULL, opt_add_samba_data }, | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										126
									
								
								0017-Only-update-attributes-given-on-the-command-line.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								0017-Only-update-attributes-given-on-the-command-line.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,126 @@ | |||||||
|  | From 27c7dde2c0e84c3bb610d1aadb0fd8faff70d3fa Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Fri, 1 Jun 2018 21:26:47 +0200 | ||||||
|  | Subject: [PATCH 17/23] Only update attributes given on the command line | ||||||
|  | 
 | ||||||
|  | When updating attributes of the LDAP computer object we only want to | ||||||
|  | update attributes which are related to options given on the command | ||||||
|  | line. Otherwise a simple call of 'adcli update' to check if the machine | ||||||
|  | account password needs an update might unexpectedly reset other | ||||||
|  | attributes as well. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1547013 | ||||||
|  |            https://bugzilla.redhat.com/show_bug.cgi?id=1545568 | ||||||
|  |            https://bugzilla.redhat.com/show_bug.cgi?id=1538730 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 35 ++++++++++++++++++++++++++++++----- | ||||||
|  |  1 file changed, 30 insertions(+), 5 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index eca3c37..ee845ef 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -99,8 +99,11 @@ struct _adcli_enroll {
 | ||||||
|  |  	int user_princpal_generate; | ||||||
|  |   | ||||||
|  |  	char *os_name; | ||||||
|  | +	int os_name_explicit;
 | ||||||
|  |  	char *os_version; | ||||||
|  | +	int os_version_explicit;
 | ||||||
|  |  	char *os_service_pack; | ||||||
|  | +	int os_service_pack_explicit;
 | ||||||
|  |   | ||||||
|  |  	krb5_kvno kvno; | ||||||
|  |  	char *keytab_name; | ||||||
|  | @@ -113,6 +116,7 @@ struct _adcli_enroll {
 | ||||||
|  |  	int computer_password_lifetime_explicit; | ||||||
|  |  	char *samba_data_tool; | ||||||
|  |  	bool trusted_for_delegation; | ||||||
|  | +	int trusted_for_delegation_explicit;
 | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static adcli_result | ||||||
|  | @@ -1212,7 +1216,11 @@ update_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  	ldap = adcli_conn_get_ldap_connection (enroll->conn); | ||||||
|  |  	return_if_fail (ldap != NULL); | ||||||
|  |   | ||||||
|  | -	{
 | ||||||
|  | +	/* Only update attributes which are explicitly given on the command
 | ||||||
|  | +	 * line. Otherwise 'adcli update' must be always called with the same
 | ||||||
|  | +	 * set of options to make sure existing attributes are not deleted or
 | ||||||
|  | +	 * overwritten with different values. */
 | ||||||
|  | +	if (enroll->host_fqdn_explicit) {
 | ||||||
|  |  		char *vals_dNSHostName[] = { enroll->host_fqdn, NULL }; | ||||||
|  |  		LDAPMod dNSHostName = { LDAP_MOD_REPLACE, "dNSHostName", { vals_dNSHostName, } }; | ||||||
|  |  		LDAPMod *mods[] = { &dNSHostName, NULL }; | ||||||
|  | @@ -1220,7 +1228,7 @@ update_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  		res |= update_computer_attribute (enroll, ldap, mods); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if (res == ADCLI_SUCCESS) {
 | ||||||
|  | +	if (res == ADCLI_SUCCESS && enroll->trusted_for_delegation_explicit) {
 | ||||||
|  |  		char *vals_userAccountControl[] = { NULL , NULL }; | ||||||
|  |  		LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } }; | ||||||
|  |  		LDAPMod *mods[] = { &userAccountControl, NULL }; | ||||||
|  | @@ -1240,12 +1248,25 @@ update_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  		LDAPMod operatingSystemVersion = { LDAP_MOD_REPLACE, "operatingSystemVersion", { vals_operatingSystemVersion, } }; | ||||||
|  |  		char *vals_operatingSystemServicePack[] = { enroll->os_service_pack, NULL }; | ||||||
|  |  		LDAPMod operatingSystemServicePack = { LDAP_MOD_REPLACE, "operatingSystemServicePack", { vals_operatingSystemServicePack, } }; | ||||||
|  | -		LDAPMod *mods[] = { &operatingSystem, &operatingSystemVersion, &operatingSystemServicePack, NULL };
 | ||||||
|  | +		LDAPMod *mods[] = { NULL, NULL, NULL, NULL };
 | ||||||
|  | +		size_t c = 0;
 | ||||||
|  |   | ||||||
|  | -		res |= update_computer_attribute (enroll, ldap, mods);
 | ||||||
|  | +		if (enroll->os_name_explicit) {
 | ||||||
|  | +			mods[c++] = &operatingSystem;
 | ||||||
|  | +		}
 | ||||||
|  | +		if (enroll->os_version_explicit) {
 | ||||||
|  | +			mods[c++] = &operatingSystemVersion;
 | ||||||
|  | +		}
 | ||||||
|  | +		if (enroll->os_service_pack_explicit) {
 | ||||||
|  | +			mods[c++] = &operatingSystemServicePack;
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +		if (c != 0) {
 | ||||||
|  | +			res |= update_computer_attribute (enroll, ldap, mods);
 | ||||||
|  | +		}
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if (res == ADCLI_SUCCESS) {
 | ||||||
|  | +	if (res == ADCLI_SUCCESS && !enroll->user_princpal_generate) {
 | ||||||
|  |  		char *vals_userPrincipalName[] = { enroll->user_principal, NULL }; | ||||||
|  |  		LDAPMod userPrincipalName = { LDAP_MOD_REPLACE, "userPrincipalName", { vals_userPrincipalName, }, }; | ||||||
|  |  		LDAPMod *mods[] = { &userPrincipalName, NULL, }; | ||||||
|  | @@ -2337,6 +2358,7 @@ adcli_enroll_set_os_name (adcli_enroll *enroll,
 | ||||||
|  |  	if (value && value[0] == '\0') | ||||||
|  |  		value = NULL; | ||||||
|  |  	_adcli_str_set (&enroll->os_name, value); | ||||||
|  | +	enroll->os_name_explicit = 1;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  const char * | ||||||
|  | @@ -2354,6 +2376,7 @@ adcli_enroll_set_os_version (adcli_enroll *enroll,
 | ||||||
|  |  	if (value && value[0] == '\0') | ||||||
|  |  		value = NULL; | ||||||
|  |  	_adcli_str_set (&enroll->os_version, value); | ||||||
|  | +	enroll->os_version_explicit = 1;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  const char * | ||||||
|  | @@ -2371,6 +2394,7 @@ adcli_enroll_set_os_service_pack (adcli_enroll *enroll,
 | ||||||
|  |  	if (value && value[0] == '\0') | ||||||
|  |  		value = NULL; | ||||||
|  |  	_adcli_str_set (&enroll->os_service_pack, value); | ||||||
|  | +	enroll->os_service_pack_explicit = 1;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  const char * | ||||||
|  | @@ -2450,4 +2474,5 @@ adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
 | ||||||
|  |  	return_if_fail (enroll != NULL); | ||||||
|  |   | ||||||
|  |  	enroll->trusted_for_delegation = value; | ||||||
|  | +	enroll->trusted_for_delegation_explicit = 1;
 | ||||||
|  |  } | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										387
									
								
								0018-update-allow-to-add-service-names.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										387
									
								
								0018-update-allow-to-add-service-names.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,387 @@ | |||||||
|  | From 54c3d176326f719ffefded17bb797bc9e6c7f3c0 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 4 Jun 2018 10:49:33 +0200 | ||||||
|  | Subject: [PATCH 18/23] update: allow to add service names | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1547013 | ||||||
|  |            https://bugzilla.redhat.com/show_bug.cgi?id=1545568 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c  | 136 +++++++++++++++++++++++++++++++++------------------- | ||||||
|  |  library/adkrb5.c    | 113 +++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  library/adprivate.h |   6 +++ | ||||||
|  |  3 files changed, 206 insertions(+), 49 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index ee845ef..6fdc773 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -305,13 +305,37 @@ ensure_service_names (adcli_result res,
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static adcli_result | ||||||
|  | -ensure_service_principals (adcli_result res,
 | ||||||
|  | -                           adcli_enroll *enroll)
 | ||||||
|  | +add_service_names_to_service_principals (adcli_enroll *enroll)
 | ||||||
|  |  { | ||||||
|  |  	char *name; | ||||||
|  |  	int length = 0; | ||||||
|  |  	int i; | ||||||
|  |   | ||||||
|  | +	if (enroll->service_principals != NULL) {
 | ||||||
|  | +		length = seq_count (enroll->service_principals);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0; enroll->service_names[i] != NULL; i++) {
 | ||||||
|  | +		if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->computer_name) < 0)
 | ||||||
|  | +			return_unexpected_if_reached ();
 | ||||||
|  | +		enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | +			                                      name, &length);
 | ||||||
|  | +
 | ||||||
|  | +		if (enroll->host_fqdn) {
 | ||||||
|  | +			if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->host_fqdn) < 0)
 | ||||||
|  | +				return_unexpected_if_reached ();
 | ||||||
|  | +			enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | +				                                      name, &length);
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return ADCLI_SUCCESS;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static adcli_result
 | ||||||
|  | +ensure_service_principals (adcli_result res,
 | ||||||
|  | +                           adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  |  	if (res != ADCLI_SUCCESS) | ||||||
|  |  		return res; | ||||||
|  |   | ||||||
|  | @@ -319,20 +343,7 @@ ensure_service_principals (adcli_result res,
 | ||||||
|  |   | ||||||
|  |  	if (!enroll->service_principals) { | ||||||
|  |  		assert (enroll->service_names != NULL); | ||||||
|  | -
 | ||||||
|  | -		for (i = 0; enroll->service_names[i] != NULL; i++) {
 | ||||||
|  | -			if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->computer_name) < 0)
 | ||||||
|  | -				return_unexpected_if_reached ();
 | ||||||
|  | -			enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | -			                                              name, &length);
 | ||||||
|  | -
 | ||||||
|  | -			if (enroll->host_fqdn) {
 | ||||||
|  | -				if (asprintf (&name, "%s/%s", enroll->service_names[i], enroll->host_fqdn) < 0)
 | ||||||
|  | -					return_unexpected_if_reached ();
 | ||||||
|  | -				enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | -				                                              name, &length);
 | ||||||
|  | -			}
 | ||||||
|  | -		}
 | ||||||
|  | +		return add_service_names_to_service_principals (enroll);
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  | @@ -356,6 +367,7 @@ ensure_keytab_principals (adcli_result res,
 | ||||||
|  |  	return_unexpected_if_fail (k5 != NULL); | ||||||
|  |   | ||||||
|  |  	enroll->keytab_principals = calloc (count + 3, sizeof (krb5_principal)); | ||||||
|  | +	return_unexpected_if_fail (enroll->keytab_principals != NULL);
 | ||||||
|  |  	at = 0; | ||||||
|  |   | ||||||
|  |  	/* First add the principal for the computer account name */ | ||||||
|  | @@ -1266,7 +1278,7 @@ update_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if (res == ADCLI_SUCCESS && !enroll->user_princpal_generate) {
 | ||||||
|  | +	if (res == ADCLI_SUCCESS && enroll->user_principal != NULL && !enroll->user_princpal_generate) {
 | ||||||
|  |  		char *vals_userPrincipalName[] = { enroll->user_principal, NULL }; | ||||||
|  |  		LDAPMod userPrincipalName = { LDAP_MOD_REPLACE, "userPrincipalName", { vals_userPrincipalName, }, }; | ||||||
|  |  		LDAPMod *mods[] = { &userPrincipalName, NULL, }; | ||||||
|  | @@ -1519,7 +1531,8 @@ add_principal_to_keytab (adcli_enroll *enroll,
 | ||||||
|  |                           krb5_context k5, | ||||||
|  |                           krb5_principal principal, | ||||||
|  |                           const char *principal_name, | ||||||
|  | -                         int *which_salt)
 | ||||||
|  | +                         int *which_salt,
 | ||||||
|  | +                         adcli_enroll_flags flags)
 | ||||||
|  |  { | ||||||
|  |  	match_principal_kvno closure; | ||||||
|  |  	krb5_data password; | ||||||
|  | @@ -1547,41 +1560,47 @@ add_principal_to_keytab (adcli_enroll *enroll,
 | ||||||
|  |  		             enroll->keytab_name); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	password.data = enroll->computer_password;
 | ||||||
|  | -	password.length = strlen (enroll->computer_password);
 | ||||||
|  | -
 | ||||||
|  |  	enctypes = adcli_enroll_get_keytab_enctypes (enroll); | ||||||
|  |   | ||||||
|  | -	/*
 | ||||||
|  | -	 * So we need to discover which salt to use. As a side effect we are
 | ||||||
|  | -	 * also testing that our account works.
 | ||||||
|  | -	 */
 | ||||||
|  | +	if (flags & ADCLI_ENROLL_PASSWORD_VALID) {
 | ||||||
|  | +		code = _adcli_krb5_keytab_copy_entries (k5, enroll->keytab, principal,
 | ||||||
|  | +		                                        enroll->kvno, enctypes);
 | ||||||
|  | +	} else {
 | ||||||
|  |   | ||||||
|  | -	salts = build_principal_salts (enroll, k5, principal);
 | ||||||
|  | -	return_unexpected_if_fail (salts != NULL);
 | ||||||
|  | +		password.data = enroll->computer_password;
 | ||||||
|  | +		password.length = strlen (enroll->computer_password);
 | ||||||
|  |   | ||||||
|  | -	if (*which_salt < 0) {
 | ||||||
|  | -		code = _adcli_krb5_keytab_discover_salt (k5, principal, enroll->kvno, &password,
 | ||||||
|  | -		                                         enctypes, salts, which_salt);
 | ||||||
|  | -		if (code != 0) {
 | ||||||
|  | -			_adcli_warn ("Couldn't authenticate with keytab while discovering which salt to use: %s: %s",
 | ||||||
|  | -			             principal_name, krb5_get_error_message (k5, code));
 | ||||||
|  | -			*which_salt = DEFAULT_SALT;
 | ||||||
|  | -		} else {
 | ||||||
|  | -			assert (*which_salt >= 0);
 | ||||||
|  | -			_adcli_info ("Discovered which keytab salt to use");
 | ||||||
|  | +		/*
 | ||||||
|  | +		 * So we need to discover which salt to use. As a side effect we are
 | ||||||
|  | +		 * also testing that our account works.
 | ||||||
|  | +		 */
 | ||||||
|  | +
 | ||||||
|  | +		salts = build_principal_salts (enroll, k5, principal);
 | ||||||
|  | +		return_unexpected_if_fail (salts != NULL);
 | ||||||
|  | +
 | ||||||
|  | +		if (*which_salt < 0) {
 | ||||||
|  | +			code = _adcli_krb5_keytab_discover_salt (k5, principal, enroll->kvno, &password,
 | ||||||
|  | +			                                         enctypes, salts, which_salt);
 | ||||||
|  | +			if (code != 0) {
 | ||||||
|  | +				_adcli_warn ("Couldn't authenticate with keytab while discovering which salt to use: %s: %s",
 | ||||||
|  | +				             principal_name, krb5_get_error_message (k5, code));
 | ||||||
|  | +				*which_salt = DEFAULT_SALT;
 | ||||||
|  | +			} else {
 | ||||||
|  | +				assert (*which_salt >= 0);
 | ||||||
|  | +				_adcli_info ("Discovered which keytab salt to use");
 | ||||||
|  | +			}
 | ||||||
|  |  		} | ||||||
|  | -	}
 | ||||||
|  |   | ||||||
|  | -	code = _adcli_krb5_keytab_add_entries (k5, enroll->keytab, principal,
 | ||||||
|  | -	                                       enroll->kvno, &password, enctypes, &salts[*which_salt]);
 | ||||||
|  | +		code = _adcli_krb5_keytab_add_entries (k5, enroll->keytab, principal,
 | ||||||
|  | +		                                       enroll->kvno, &password, enctypes, &salts[*which_salt]);
 | ||||||
|  |   | ||||||
|  | -	free_principal_salts (k5, salts);
 | ||||||
|  | +		free_principal_salts (k5, salts);
 | ||||||
|  |   | ||||||
|  | -	if (code != 0) {
 | ||||||
|  | -		_adcli_err ("Couldn't add keytab entries: %s: %s",
 | ||||||
|  | -		            enroll->keytab_name, krb5_get_error_message (k5, code));
 | ||||||
|  | -		return ADCLI_ERR_FAIL;
 | ||||||
|  | +		if (code != 0) {
 | ||||||
|  | +			_adcli_err ("Couldn't add keytab entries: %s: %s",
 | ||||||
|  | +			            enroll->keytab_name, krb5_get_error_message (k5, code));
 | ||||||
|  | +			return ADCLI_ERR_FAIL;
 | ||||||
|  | +		}
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |   | ||||||
|  | @@ -1591,7 +1610,8 @@ add_principal_to_keytab (adcli_enroll *enroll,
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static adcli_result | ||||||
|  | -update_keytab_for_principals (adcli_enroll *enroll)
 | ||||||
|  | +update_keytab_for_principals (adcli_enroll *enroll,
 | ||||||
|  | +                              adcli_enroll_flags flags)
 | ||||||
|  |  { | ||||||
|  |  	krb5_context k5; | ||||||
|  |  	adcli_result res; | ||||||
|  | @@ -1608,7 +1628,7 @@ update_keytab_for_principals (adcli_enroll *enroll)
 | ||||||
|  |  		if (krb5_unparse_name (k5, enroll->keytab_principals[i], &name) != 0) | ||||||
|  |  			name = ""; | ||||||
|  |  		res = add_principal_to_keytab (enroll, k5, enroll->keytab_principals[i], | ||||||
|  | -		                               name, &which_salt);
 | ||||||
|  | +		                               name, &which_salt, flags);
 | ||||||
|  |  		krb5_free_unparsed_name (k5, name); | ||||||
|  |   | ||||||
|  |  		if (res != ADCLI_SUCCESS) | ||||||
|  | @@ -1807,6 +1827,20 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
 | ||||||
|  |  	/* We ignore failures of setting these fields */ | ||||||
|  |  	update_and_calculate_enctypes (enroll); | ||||||
|  |  	update_computer_account (enroll); | ||||||
|  | +
 | ||||||
|  | +	/* service_names is only set from input on the command line, so no
 | ||||||
|  | +	 * additional check for explicit is needed here */
 | ||||||
|  | +	if (enroll->service_names != NULL) {
 | ||||||
|  | +		res = add_service_names_to_service_principals (enroll);
 | ||||||
|  | +		if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +			return res;
 | ||||||
|  | +		}
 | ||||||
|  | +		res = ensure_keytab_principals (res, enroll);
 | ||||||
|  | +		if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +			return res;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	update_service_principals (enroll); | ||||||
|  |   | ||||||
|  |  	if ( (flags & ADCLI_ENROLL_ADD_SAMBA_DATA) && ! (flags & ADCLI_ENROLL_PASSWORD_VALID)) { | ||||||
|  | @@ -1826,7 +1860,7 @@ enroll_join_or_update_tasks (adcli_enroll *enroll,
 | ||||||
|  |  	 * that we use for salting. | ||||||
|  |  	 */ | ||||||
|  |   | ||||||
|  | -	return update_keytab_for_principals (enroll);
 | ||||||
|  | +	return update_keytab_for_principals (enroll, flags);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  adcli_result | ||||||
|  | @@ -1927,7 +1961,11 @@ adcli_enroll_update (adcli_enroll *enroll,
 | ||||||
|  |   | ||||||
|  |  	if (_adcli_check_nt_time_string_lifetime (value, | ||||||
|  |  	                adcli_enroll_get_computer_password_lifetime (enroll))) { | ||||||
|  | -		flags |= ADCLI_ENROLL_NO_KEYTAB;
 | ||||||
|  | +		/* Do not update keytab if neither new service principals have
 | ||||||
|  | +                 * to be added nor the user principal has to be changed. */
 | ||||||
|  | +		if (enroll->service_names == NULL && (enroll->user_principal == NULL || enroll->user_princpal_generate)) {
 | ||||||
|  | +			flags |= ADCLI_ENROLL_NO_KEYTAB;
 | ||||||
|  | +		}
 | ||||||
|  |  		flags |= ADCLI_ENROLL_PASSWORD_VALID; | ||||||
|  |  	} | ||||||
|  |  	free (value); | ||||||
|  | diff --git a/library/adkrb5.c b/library/adkrb5.c
 | ||||||
|  | index b0e903e..033c181 100644
 | ||||||
|  | --- a/library/adkrb5.c
 | ||||||
|  | +++ b/library/adkrb5.c
 | ||||||
|  | @@ -204,6 +204,119 @@ _adcli_krb5_open_keytab (krb5_context k5,
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +typedef struct {
 | ||||||
|  | +	krb5_kvno kvno;
 | ||||||
|  | +	krb5_enctype enctype;
 | ||||||
|  | +	int matched;
 | ||||||
|  | +} match_enctype_kvno;
 | ||||||
|  | +
 | ||||||
|  | +static krb5_boolean
 | ||||||
|  | +match_enctype_and_kvno (krb5_context k5,
 | ||||||
|  | +                        krb5_keytab_entry *entry,
 | ||||||
|  | +                        void *data)
 | ||||||
|  | +{
 | ||||||
|  | +	krb5_boolean similar = FALSE;
 | ||||||
|  | +	match_enctype_kvno *closure = data;
 | ||||||
|  | +	krb5_error_code code;
 | ||||||
|  | +
 | ||||||
|  | +	assert (closure->enctype);
 | ||||||
|  | +
 | ||||||
|  | +	code = krb5_c_enctype_compare (k5, closure->enctype, entry->key.enctype,
 | ||||||
|  | +	                               &similar);
 | ||||||
|  | +
 | ||||||
|  | +	if (code == 0 && entry->vno == closure->kvno && similar) {
 | ||||||
|  | +		closure->matched = 1;
 | ||||||
|  | +		return 1;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static krb5_error_code
 | ||||||
|  | +_adcli_krb5_get_keyblock (krb5_context k5,
 | ||||||
|  | +                          krb5_keytab keytab,
 | ||||||
|  | +                          krb5_keyblock *keyblock,
 | ||||||
|  | +                          krb5_boolean (* match_func) (krb5_context,
 | ||||||
|  | +                                                       krb5_keytab_entry *,
 | ||||||
|  | +                                                       void *),
 | ||||||
|  | +                          void *match_data)
 | ||||||
|  | +{
 | ||||||
|  | +	krb5_kt_cursor cursor;
 | ||||||
|  | +	krb5_keytab_entry entry;
 | ||||||
|  | +	krb5_error_code code;
 | ||||||
|  | +
 | ||||||
|  | +	code = krb5_kt_start_seq_get (k5, keytab, &cursor);
 | ||||||
|  | +	if (code == KRB5_KT_END || code == ENOENT)
 | ||||||
|  | +		return 0;
 | ||||||
|  | +	else if (code != 0)
 | ||||||
|  | +		return code;
 | ||||||
|  | +
 | ||||||
|  | +	for (;;) {
 | ||||||
|  | +		code = krb5_kt_next_entry (k5, keytab, &entry, &cursor);
 | ||||||
|  | +		if (code != 0)
 | ||||||
|  | +			break;
 | ||||||
|  | +
 | ||||||
|  | +		/* See if we should remove this entry */
 | ||||||
|  | +		if (!match_func (k5, &entry, match_data)) {
 | ||||||
|  | +			krb5_free_keytab_entry_contents (k5, &entry);
 | ||||||
|  | +			continue;
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +		code = krb5_copy_keyblock_contents (k5, &entry.key, keyblock);
 | ||||||
|  | +		krb5_free_keytab_entry_contents (k5, &entry);
 | ||||||
|  | +		break;
 | ||||||
|  | +
 | ||||||
|  | +
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	if (code == KRB5_KT_END)
 | ||||||
|  | +		code = 0;
 | ||||||
|  | +
 | ||||||
|  | +	krb5_kt_end_seq_get (k5, keytab, &cursor);
 | ||||||
|  | +	return code;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +krb5_error_code
 | ||||||
|  | +_adcli_krb5_keytab_copy_entries (krb5_context k5,
 | ||||||
|  | +                                 krb5_keytab keytab,
 | ||||||
|  | +                                 krb5_principal principal,
 | ||||||
|  | +                                 krb5_kvno kvno,
 | ||||||
|  | +                                 krb5_enctype *enctypes)
 | ||||||
|  | +{
 | ||||||
|  | +	krb5_keytab_entry entry;
 | ||||||
|  | +	krb5_error_code code;
 | ||||||
|  | +	int i;
 | ||||||
|  | +	match_enctype_kvno closure;
 | ||||||
|  | +
 | ||||||
|  | +	for (i = 0; enctypes[i] != 0; i++) {
 | ||||||
|  | +
 | ||||||
|  | +		closure.kvno = kvno;
 | ||||||
|  | +		closure.enctype = enctypes[i];
 | ||||||
|  | +		closure.matched = 0;
 | ||||||
|  | +
 | ||||||
|  | +		memset (&entry, 0, sizeof (entry));
 | ||||||
|  | +
 | ||||||
|  | +		code = _adcli_krb5_get_keyblock (k5, keytab, &entry.key,
 | ||||||
|  | +		                                 match_enctype_and_kvno, &closure);
 | ||||||
|  | +		if (code != 0) {
 | ||||||
|  | +			return code;
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +
 | ||||||
|  | +		entry.principal = principal;
 | ||||||
|  | +		entry.vno = kvno;
 | ||||||
|  | +
 | ||||||
|  | +		code = krb5_kt_add_entry (k5, keytab, &entry);
 | ||||||
|  | +
 | ||||||
|  | +		entry.principal = NULL;
 | ||||||
|  | +		krb5_free_keytab_entry_contents (k5, &entry);
 | ||||||
|  | +
 | ||||||
|  | +		if (code != 0)
 | ||||||
|  | +			return code;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return 0;
 | ||||||
|  | +}
 | ||||||
|  |   | ||||||
|  |  krb5_error_code | ||||||
|  |  _adcli_krb5_keytab_add_entries (krb5_context k5, | ||||||
|  | diff --git a/library/adprivate.h b/library/adprivate.h
 | ||||||
|  | index 83a88f6..7485249 100644
 | ||||||
|  | --- a/library/adprivate.h
 | ||||||
|  | +++ b/library/adprivate.h
 | ||||||
|  | @@ -282,6 +282,12 @@ krb5_enctype *   _adcli_krb5_parse_enctypes       (const char *value);
 | ||||||
|  |   | ||||||
|  |  char *           _adcli_krb5_format_enctypes      (krb5_enctype *enctypes); | ||||||
|  |   | ||||||
|  | +krb5_error_code  _adcli_krb5_keytab_copy_entries  (krb5_context k5,
 | ||||||
|  | +                                                   krb5_keytab keytab,
 | ||||||
|  | +                                                   krb5_principal principal,
 | ||||||
|  | +                                                   krb5_kvno kvno,
 | ||||||
|  | +                                                   krb5_enctype *enctypes);
 | ||||||
|  | +
 | ||||||
|  |  struct _adcli_attrs { | ||||||
|  |  	LDAPMod **mods; | ||||||
|  |  	int len; | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										181
									
								
								0019-Calculate-enctypes-in-a-separate-function.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								0019-Calculate-enctypes-in-a-separate-function.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,181 @@ | |||||||
|  | From 9ad1164405e7b4decb7c4ad96fe5ab27d6e53366 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Wed, 6 Jun 2018 16:31:32 +0200 | ||||||
|  | Subject: [PATCH 19/23] Calculate enctypes in a separate function | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1542354 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 137 +++++++++++++++++++++++++++++++---------------------- | ||||||
|  |  1 file changed, 81 insertions(+), 56 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 6fdc773..75ac1e4 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -542,6 +542,83 @@ calculate_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static adcli_result
 | ||||||
|  | +calculate_enctypes (adcli_enroll *enroll, char **enctype)
 | ||||||
|  | +{
 | ||||||
|  | +	char *value = NULL;
 | ||||||
|  | +	krb5_enctype *read_enctypes;
 | ||||||
|  | +	char *new_value = NULL;
 | ||||||
|  | +	int is_2008_or_later;
 | ||||||
|  | +	LDAP *ldap;
 | ||||||
|  | +
 | ||||||
|  | +	*enctype = NULL;
 | ||||||
|  | +	/*
 | ||||||
|  | +	 * Because we're using a keytab we want the server to be aware of the
 | ||||||
|  | +	 * encryption types supported on the client, because we can't dynamically
 | ||||||
|  | +	 * use a new one that's thrown at us.
 | ||||||
|  | +	 *
 | ||||||
|  | +	 * If the encryption types are not explicitly set by the caller of this
 | ||||||
|  | +	 * library, then see if the account already has some encryption types
 | ||||||
|  | +	 * marked on it.
 | ||||||
|  | +	 *
 | ||||||
|  | +	 * If not, write our default set to the account.
 | ||||||
|  | +	 *
 | ||||||
|  | +	 * Note that Windows 2003 and earlier have a standard set of encryption
 | ||||||
|  | +	 * types, and no msDS-supportedEncryptionTypes attribute.
 | ||||||
|  | +	 */
 | ||||||
|  | +
 | ||||||
|  | +	ldap = adcli_conn_get_ldap_connection (enroll->conn);
 | ||||||
|  | +	return_unexpected_if_fail (ldap != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	is_2008_or_later = adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID);
 | ||||||
|  | +
 | ||||||
|  | +	/* In 2008 or later, use the msDS-supportedEncryptionTypes attribute */
 | ||||||
|  | +	if (is_2008_or_later) {
 | ||||||
|  | +		value = _adcli_ldap_parse_value (ldap, enroll->computer_attributes,
 | ||||||
|  | +		                                 "msDS-supportedEncryptionTypes");
 | ||||||
|  | +
 | ||||||
|  | +		if (!enroll->keytab_enctypes_explicit && value != NULL) {
 | ||||||
|  | +			read_enctypes = _adcli_krb5_parse_enctypes (value);
 | ||||||
|  | +			if (read_enctypes == NULL) {
 | ||||||
|  | +				_adcli_warn ("Invalid or unsupported encryption types are set on "
 | ||||||
|  | +				             "the computer account (%s).", value);
 | ||||||
|  | +			} else {
 | ||||||
|  | +				free (enroll->keytab_enctypes);
 | ||||||
|  | +				enroll->keytab_enctypes = read_enctypes;
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  | +	/* In 2003 or earlier, standard set of enc types */
 | ||||||
|  | +	} else {
 | ||||||
|  | +		value = _adcli_krb5_format_enctypes (v51_earlier_enctypes);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	new_value = _adcli_krb5_format_enctypes (adcli_enroll_get_keytab_enctypes (enroll));
 | ||||||
|  | +	if (new_value == NULL) {
 | ||||||
|  | +		free (value);
 | ||||||
|  | +		_adcli_warn ("The encryption types desired are not available in active directory");
 | ||||||
|  | +		return ADCLI_ERR_CONFIG;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	/* If we already have this value, then don't need to update */
 | ||||||
|  | +	if (value && strcmp (new_value, value) == 0) {
 | ||||||
|  | +		free (value);
 | ||||||
|  | +		free (new_value);
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  | +	}
 | ||||||
|  | +	free (value);
 | ||||||
|  | +
 | ||||||
|  | +	if (!is_2008_or_later) {
 | ||||||
|  | +		free (new_value);
 | ||||||
|  | +		_adcli_warn ("Server does not support setting encryption types");
 | ||||||
|  | +		return ADCLI_SUCCESS;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	*enctype = new_value;
 | ||||||
|  | +	return ADCLI_SUCCESS;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +
 | ||||||
|  |  static adcli_result | ||||||
|  |  create_computer_account (adcli_enroll *enroll, | ||||||
|  |                           LDAP *ldap) | ||||||
|  | @@ -1053,75 +1130,23 @@ retrieve_computer_account (adcli_enroll *enroll)
 | ||||||
|  |  static adcli_result | ||||||
|  |  update_and_calculate_enctypes (adcli_enroll *enroll) | ||||||
|  |  { | ||||||
|  | -	char *value = NULL;
 | ||||||
|  | -	krb5_enctype *read_enctypes;
 | ||||||
|  |  	char *vals_supportedEncryptionTypes[] = { NULL, NULL }; | ||||||
|  |  	LDAPMod mod = { LDAP_MOD_REPLACE, "msDS-supportedEncryptionTypes", { vals_supportedEncryptionTypes, } }; | ||||||
|  |  	LDAPMod *mods[2] = { &mod, NULL }; | ||||||
|  | -	int is_2008_or_later;
 | ||||||
|  |  	char *new_value; | ||||||
|  |  	LDAP *ldap; | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  | -	/*
 | ||||||
|  | -	 * Because we're using a keytab we want the server to be aware of the
 | ||||||
|  | -	 * encryption types supported on the client, because we can't dynamically
 | ||||||
|  | -	 * use a new one that's thrown at us.
 | ||||||
|  | -	 *
 | ||||||
|  | -	 * If the encryption types are not explicitly set by the caller of this
 | ||||||
|  | -	 * library, then see if the account already has some encryption types
 | ||||||
|  | -	 * marked on it.
 | ||||||
|  | -	 *
 | ||||||
|  | -	 * If not, write our default set to the account.
 | ||||||
|  | -	 *
 | ||||||
|  | -	 * Note that Windows 2003 and earlier have a standard set of encryption
 | ||||||
|  | -	 * types, and no msDS-supportedEncryptionTypes attribute.
 | ||||||
|  | -	 */
 | ||||||
|  | -
 | ||||||
|  |  	ldap = adcli_conn_get_ldap_connection (enroll->conn); | ||||||
|  |  	return_unexpected_if_fail (ldap != NULL); | ||||||
|  |   | ||||||
|  | -	is_2008_or_later = adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID);
 | ||||||
|  | -
 | ||||||
|  | -	/* In 2008 or later, use the msDS-supportedEncryptionTypes attribute */
 | ||||||
|  | -	if (is_2008_or_later) {
 | ||||||
|  | -		value = _adcli_ldap_parse_value (ldap, enroll->computer_attributes,
 | ||||||
|  | -		                                 "msDS-supportedEncryptionTypes");
 | ||||||
|  | -
 | ||||||
|  | -		if (!enroll->keytab_enctypes_explicit && value != NULL) {
 | ||||||
|  | -			read_enctypes = _adcli_krb5_parse_enctypes (value);
 | ||||||
|  | -			if (read_enctypes == NULL) {
 | ||||||
|  | -				_adcli_warn ("Invalid or unsupported encryption types are set on "
 | ||||||
|  | -				             "the computer account (%s).", value);
 | ||||||
|  | -			} else {
 | ||||||
|  | -				free (enroll->keytab_enctypes);
 | ||||||
|  | -				enroll->keytab_enctypes = read_enctypes;
 | ||||||
|  | -			}
 | ||||||
|  | -		}
 | ||||||
|  | -
 | ||||||
|  | -	/* In 2003 or earlier, standard set of enc types */
 | ||||||
|  | -	} else {
 | ||||||
|  | -		value = _adcli_krb5_format_enctypes (v51_earlier_enctypes);
 | ||||||
|  | -	}
 | ||||||
|  | -
 | ||||||
|  | -	new_value = _adcli_krb5_format_enctypes (adcli_enroll_get_keytab_enctypes (enroll));
 | ||||||
|  | -	if (new_value == NULL) {
 | ||||||
|  | -		free (value);
 | ||||||
|  | -		_adcli_warn ("The encryption types desired are not available in active directory");
 | ||||||
|  | -		return ADCLI_ERR_CONFIG;
 | ||||||
|  | -	}
 | ||||||
|  | -
 | ||||||
|  | -	/* If we already have this value, then don't need to update */
 | ||||||
|  | -	if (value && strcmp (new_value, value) == 0) {
 | ||||||
|  | -		free (value);
 | ||||||
|  | +	ret = calculate_enctypes (enroll, &new_value);
 | ||||||
|  | +	if (ret != ADCLI_SUCCESS) {
 | ||||||
|  |  		free (new_value); | ||||||
|  | -		return ADCLI_SUCCESS;
 | ||||||
|  | +		return ret;
 | ||||||
|  |  	} | ||||||
|  | -	free (value);
 | ||||||
|  |   | ||||||
|  | -	if (!is_2008_or_later) {
 | ||||||
|  | -		free (new_value);
 | ||||||
|  | -		_adcli_warn ("Server does not support setting encryption types");
 | ||||||
|  | +	if (new_value == NULL) {
 | ||||||
|  |  		return ADCLI_SUCCESS; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										110
									
								
								0020-join-add-all-attributes-while-creating-computer-obje.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								0020-join-add-all-attributes-while-creating-computer-obje.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,110 @@ | |||||||
|  | From cbe33b3e6d0d3415e4642d71942380d1793311f1 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Mon, 11 Jun 2018 09:44:49 +0200 | ||||||
|  | Subject: [PATCH 20/23] join: add all attributes while creating computer object | ||||||
|  | 
 | ||||||
|  | It is possible to create special accounts which can only join a computer | ||||||
|  | to a domain but is not allowed to do any further operations which the | ||||||
|  | computer object. As a result if such an account is used during the join | ||||||
|  | only the ldapadd operation is permitted but not any later ldapmodify | ||||||
|  | operation. To create the computer object correctly in this case all | ||||||
|  | attributes must be added while the object is created and not later. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1542354 | ||||||
|  | ---
 | ||||||
|  |  library/adenroll.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- | ||||||
|  |  1 file changed, 47 insertions(+), 5 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adenroll.c b/library/adenroll.c
 | ||||||
|  | index 75ac1e4..b508caf 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -573,7 +573,7 @@ calculate_enctypes (adcli_enroll *enroll, char **enctype)
 | ||||||
|  |  	is_2008_or_later = adcli_conn_server_has_capability (enroll->conn, ADCLI_CAP_V60_OID); | ||||||
|  |   | ||||||
|  |  	/* In 2008 or later, use the msDS-supportedEncryptionTypes attribute */ | ||||||
|  | -	if (is_2008_or_later) {
 | ||||||
|  | +	if (is_2008_or_later && enroll->computer_attributes != NULL) {
 | ||||||
|  |  		value = _adcli_ldap_parse_value (ldap, enroll->computer_attributes, | ||||||
|  |  		                                 "msDS-supportedEncryptionTypes"); | ||||||
|  |   | ||||||
|  | @@ -618,7 +618,6 @@ calculate_enctypes (adcli_enroll *enroll, char **enctype)
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -
 | ||||||
|  |  static adcli_result | ||||||
|  |  create_computer_account (adcli_enroll *enroll, | ||||||
|  |                           LDAP *ldap) | ||||||
|  | @@ -628,22 +627,65 @@ create_computer_account (adcli_enroll *enroll,
 | ||||||
|  |  	char *vals_sAMAccountName[] = { enroll->computer_sam, NULL }; | ||||||
|  |  	LDAPMod sAMAccountName = { LDAP_MOD_ADD, "sAMAccountName", { vals_sAMAccountName, } }; | ||||||
|  |  	char *vals_userAccountControl[] = { "69632", NULL }; /* WORKSTATION_TRUST_ACCOUNT | DONT_EXPIRE_PASSWD */ | ||||||
|  | -	LDAPMod userAccountControl = { LDAP_MOD_REPLACE, "userAccountControl", { vals_userAccountControl, } };
 | ||||||
|  | +	LDAPMod userAccountControl = { LDAP_MOD_ADD, "userAccountControl", { vals_userAccountControl, } };
 | ||||||
|  | +	char *vals_supportedEncryptionTypes[] = { NULL, NULL };
 | ||||||
|  | +	LDAPMod encTypes = { LDAP_MOD_ADD, "msDS-supportedEncryptionTypes", { vals_supportedEncryptionTypes, } };
 | ||||||
|  | +	char *vals_dNSHostName[] = { enroll->host_fqdn, NULL };
 | ||||||
|  | +	LDAPMod dNSHostName = { LDAP_MOD_ADD, "dNSHostName", { vals_dNSHostName, } };
 | ||||||
|  | +	char *vals_operatingSystem[] = { enroll->os_name, NULL };
 | ||||||
|  | +	LDAPMod operatingSystem = { LDAP_MOD_ADD, "operatingSystem", { vals_operatingSystem, } };
 | ||||||
|  | +	char *vals_operatingSystemVersion[] = { enroll->os_version, NULL };
 | ||||||
|  | +	LDAPMod operatingSystemVersion = { LDAP_MOD_ADD, "operatingSystemVersion", { vals_operatingSystemVersion, } };
 | ||||||
|  | +	char *vals_operatingSystemServicePack[] = { enroll->os_service_pack, NULL };
 | ||||||
|  | +	LDAPMod operatingSystemServicePack = { LDAP_MOD_ADD, "operatingSystemServicePack", { vals_operatingSystemServicePack, } };
 | ||||||
|  | +	char *vals_userPrincipalName[] = { enroll->user_principal, NULL };
 | ||||||
|  | +	LDAPMod userPrincipalName = { LDAP_MOD_ADD, "userPrincipalName", { vals_userPrincipalName, }, };
 | ||||||
|  | +	LDAPMod servicePrincipalName = { LDAP_MOD_ADD, "servicePrincipalName", { enroll->service_principals, } };
 | ||||||
|  | +
 | ||||||
|  | +	char *val = NULL;
 | ||||||
|  |   | ||||||
|  |  	int ret; | ||||||
|  | +	size_t c;
 | ||||||
|  | +	size_t m;
 | ||||||
|  |   | ||||||
|  | -	LDAPMod *mods[] = {
 | ||||||
|  | +	LDAPMod *all_mods[] = {
 | ||||||
|  |  		&objectClass, | ||||||
|  |  		&sAMAccountName, | ||||||
|  |  		&userAccountControl, | ||||||
|  | -		NULL,
 | ||||||
|  | +		&encTypes,
 | ||||||
|  | +		&dNSHostName,
 | ||||||
|  | +		&operatingSystem,
 | ||||||
|  | +		&operatingSystemVersion,
 | ||||||
|  | +		&operatingSystemServicePack,
 | ||||||
|  | +		&userPrincipalName,
 | ||||||
|  | +		&servicePrincipalName,
 | ||||||
|  | +		NULL
 | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  | +	size_t mods_count = sizeof (all_mods) / sizeof (LDAPMod *);
 | ||||||
|  | +	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 */ | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	ret = calculate_enctypes (enroll, &val);
 | ||||||
|  | +	if (ret != ADCLI_SUCCESS) {
 | ||||||
|  | +		return ret;
 | ||||||
|  | +	}
 | ||||||
|  | +	vals_supportedEncryptionTypes[0] = val;
 | ||||||
|  | +
 | ||||||
|  | +	m = 0;
 | ||||||
|  | +	for (c = 0; c < mods_count - 1; c++) {
 | ||||||
|  | +		/* Skip empty LDAP sttributes */
 | ||||||
|  | +		if (all_mods[c]->mod_vals.modv_strvals[0] != NULL) {
 | ||||||
|  | +			mods[m++] = all_mods[c];
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +	mods[m] = NULL;
 | ||||||
|  | +
 | ||||||
|  |  	ret = ldap_add_ext_s (ldap, enroll->computer_dn, mods, NULL, NULL); | ||||||
|  | +	free (val);
 | ||||||
|  |   | ||||||
|  |  	/* | ||||||
|  |  	 * Hand to head. This is really dumb... AD returns | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										288
									
								
								0021-util-add-_adcli_strv_remove_unsorted.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								0021-util-add-_adcli_strv_remove_unsorted.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,288 @@ | |||||||
|  | From 4208646609da9b25b70c21f5f39c92fabbd59dfc Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 14 Jun 2018 16:48:22 +0200 | ||||||
|  | Subject: [PATCH 21/23] util: add _adcli_strv_remove_unsorted | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1547014 | ||||||
|  | ---
 | ||||||
|  |  library/adprivate.h |   4 ++ | ||||||
|  |  library/adutil.c    |  21 ++++++++ | ||||||
|  |  library/seq.c       | 149 +++++++++++++++++++++++++++++++++++++++++++++++++--- | ||||||
|  |  library/seq.h       |  12 +++++ | ||||||
|  |  4 files changed, 179 insertions(+), 7 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adprivate.h b/library/adprivate.h
 | ||||||
|  | index 7485249..bc9df6d 100644
 | ||||||
|  | --- a/library/adprivate.h
 | ||||||
|  | +++ b/library/adprivate.h
 | ||||||
|  | @@ -111,6 +111,10 @@ char **        _adcli_strv_add               (char **strv,
 | ||||||
|  |                                                char *string, | ||||||
|  |                                                int *length) GNUC_WARN_UNUSED; | ||||||
|  |   | ||||||
|  | +void           _adcli_strv_remove_unsorted   (char **strv,
 | ||||||
|  | +                                              const char *string,
 | ||||||
|  | +                                              int *length);
 | ||||||
|  | +
 | ||||||
|  |  void           _adcli_strv_free              (char **strv); | ||||||
|  |   | ||||||
|  |  int            _adcli_strv_has               (char **strv, | ||||||
|  | diff --git a/library/adutil.c b/library/adutil.c
 | ||||||
|  | index a27bd68..6334b52 100644
 | ||||||
|  | --- a/library/adutil.c
 | ||||||
|  | +++ b/library/adutil.c
 | ||||||
|  | @@ -221,6 +221,27 @@ _adcli_strv_add (char **strv,
 | ||||||
|  |  	return seq_push (strv, length, string); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +_adcli_strv_remove_unsorted (char **strv,
 | ||||||
|  | +                             const char *string,
 | ||||||
|  | +                             int *length)
 | ||||||
|  | +{
 | ||||||
|  | +	int len;
 | ||||||
|  | +
 | ||||||
|  | +	return_if_fail (string != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	if (!length) {
 | ||||||
|  | +		len = seq_count (strv);
 | ||||||
|  | +		length = &len;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return seq_remove_unsorted (strv, length, discard_const (string),
 | ||||||
|  | +	                            (seq_compar)strcasecmp, free);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +
 | ||||||
|  |  int | ||||||
|  |  _adcli_strv_has (char **strv, | ||||||
|  |                   const char *str) | ||||||
|  | diff --git a/library/seq.c b/library/seq.c
 | ||||||
|  | index 627dcaf..8e7475d 100644
 | ||||||
|  | --- a/library/seq.c
 | ||||||
|  | +++ b/library/seq.c
 | ||||||
|  | @@ -111,6 +111,24 @@ seq_push (seq_voidp sequence,
 | ||||||
|  |  	return seq; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static int
 | ||||||
|  | +linear_search (void **seq,
 | ||||||
|  | +               int low,
 | ||||||
|  | +               int high,
 | ||||||
|  | +               void *match,
 | ||||||
|  | +               seq_compar compar)
 | ||||||
|  | +{
 | ||||||
|  | +	int at;
 | ||||||
|  | +
 | ||||||
|  | +	for (at = low; at < high; at++) {
 | ||||||
|  | +		if (compar (match, seq[at]) == 0) {
 | ||||||
|  | +			break;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return at;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static int | ||||||
|  |  binary_search (void **seq, | ||||||
|  |                 int low, | ||||||
|  | @@ -171,12 +189,13 @@ seq_insert (seq_voidp sequence,
 | ||||||
|  |  	return seq; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -void
 | ||||||
|  | -seq_remove (seq_voidp sequence,
 | ||||||
|  | -            int *length,
 | ||||||
|  | -            void *match,
 | ||||||
|  | -            seq_compar compar,
 | ||||||
|  | -            seq_destroy destroy)
 | ||||||
|  | +static void
 | ||||||
|  | +seq_remove_int (seq_voidp sequence,
 | ||||||
|  | +                int *length,
 | ||||||
|  | +                void *match,
 | ||||||
|  | +                seq_search search,
 | ||||||
|  | +                seq_compar compar,
 | ||||||
|  | +                seq_destroy destroy)
 | ||||||
|  |  { | ||||||
|  |  	void **seq = sequence; | ||||||
|  |  	int at; | ||||||
|  | @@ -187,7 +206,7 @@ seq_remove (seq_voidp sequence,
 | ||||||
|  |  	assert (match != NULL); | ||||||
|  |   | ||||||
|  |  	len = *length; | ||||||
|  | -	at = binary_search (seq, 0, len, match, compar);
 | ||||||
|  | +	at = search (seq, 0, len, match, compar);
 | ||||||
|  |   | ||||||
|  |  	/* We have a matching value */ | ||||||
|  |  	if (at < len && compar (match, seq[at]) == 0) { | ||||||
|  | @@ -201,6 +220,26 @@ seq_remove (seq_voidp sequence,
 | ||||||
|  |  	*length = len; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void
 | ||||||
|  | +seq_remove (seq_voidp sequence,
 | ||||||
|  | +            int *length,
 | ||||||
|  | +            void *match,
 | ||||||
|  | +            seq_compar compar,
 | ||||||
|  | +            seq_destroy destroy)
 | ||||||
|  | +{
 | ||||||
|  | +	return seq_remove_int (sequence, length, match, binary_search, compar, destroy);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +seq_remove_unsorted (seq_voidp sequence,
 | ||||||
|  | +                     int *length,
 | ||||||
|  | +                     void *match,
 | ||||||
|  | +                     seq_compar compar,
 | ||||||
|  | +                     seq_destroy destroy)
 | ||||||
|  | +{
 | ||||||
|  | +	return seq_remove_int (sequence, length, match, linear_search, compar, destroy);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  void | ||||||
|  |  seq_filter (seq_voidp sequence, | ||||||
|  |              int *length, | ||||||
|  | @@ -430,6 +469,99 @@ test_remove (void)
 | ||||||
|  |  	seq_free (seq, NULL); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static void
 | ||||||
|  | +test_remove_unsorted (void)
 | ||||||
|  | +{
 | ||||||
|  | +	void **seq = NULL;
 | ||||||
|  | +	int len = 0;
 | ||||||
|  | +
 | ||||||
|  | +	seq = seq_push (seq, &len, "3");
 | ||||||
|  | +	seq = seq_push (seq, &len, "5");
 | ||||||
|  | +	seq = seq_push (seq, &len, "1");
 | ||||||
|  | +	seq = seq_push (seq, &len, "4");
 | ||||||
|  | +	seq = seq_push (seq, &len, "2");
 | ||||||
|  | +
 | ||||||
|  | +	assert_str_eq (seq[0], "3");
 | ||||||
|  | +	assert_str_eq (seq[1], "5");
 | ||||||
|  | +	assert_str_eq (seq[2], "1");
 | ||||||
|  | +	assert_str_eq (seq[3], "4");
 | ||||||
|  | +	assert_str_eq (seq[4], "2");
 | ||||||
|  | +	assert (seq[5] == NULL);
 | ||||||
|  | +	assert_num_eq (len, 5);
 | ||||||
|  | +
 | ||||||
|  | +	seq_remove_unsorted (seq, &len, "3", (seq_compar)strcmp, NULL);
 | ||||||
|  | +	seq_remove_unsorted (seq, &len, "2", (seq_compar)strcmp, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	assert_str_eq (seq[0], "5");
 | ||||||
|  | +	assert_str_eq (seq[1], "1");
 | ||||||
|  | +	assert_str_eq (seq[2], "4");
 | ||||||
|  | +	assert (seq[3] == NULL);
 | ||||||
|  | +	assert_num_eq (len, 3);
 | ||||||
|  | +
 | ||||||
|  | +	seq_free (seq, NULL);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static void
 | ||||||
|  | +test_remove_first (void)
 | ||||||
|  | +{
 | ||||||
|  | +	void **seq = NULL;
 | ||||||
|  | +	int len = 0;
 | ||||||
|  | +
 | ||||||
|  | +	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
 | ||||||
|  | +	seq = seq_insert (seq, &len, "5", (seq_compar)strcmp, NULL);
 | ||||||
|  | +	seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
 | ||||||
|  | +	seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
 | ||||||
|  | +	seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	assert_str_eq (seq[0], "1");
 | ||||||
|  | +	assert_str_eq (seq[1], "2");
 | ||||||
|  | +	assert_str_eq (seq[2], "3");
 | ||||||
|  | +	assert_str_eq (seq[3], "4");
 | ||||||
|  | +	assert_str_eq (seq[4], "5");
 | ||||||
|  | +	assert (seq[5] == NULL);
 | ||||||
|  | +	assert_num_eq (len, 5);
 | ||||||
|  | +
 | ||||||
|  | +	seq_remove (seq, &len, "1", (seq_compar)strcmp, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	assert_str_eq (seq[0], "2");
 | ||||||
|  | +	assert_str_eq (seq[1], "3");
 | ||||||
|  | +	assert_str_eq (seq[2], "4");
 | ||||||
|  | +	assert_str_eq (seq[3], "5");
 | ||||||
|  | +	assert (seq[4] == NULL);
 | ||||||
|  | +	assert_num_eq (len, 4);
 | ||||||
|  | +
 | ||||||
|  | +	seq_free (seq, NULL);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +static void
 | ||||||
|  | +test_remove_last (void)
 | ||||||
|  | +{
 | ||||||
|  | +	void **seq = NULL;
 | ||||||
|  | +	int len = 0;
 | ||||||
|  | +
 | ||||||
|  | +	seq = seq_insert (seq, &len, "3", (seq_compar)strcmp, NULL);
 | ||||||
|  | +	seq = seq_insert (seq, &len, "1", (seq_compar)strcmp, NULL);
 | ||||||
|  | +	seq = seq_insert (seq, &len, "4", (seq_compar)strcmp, NULL);
 | ||||||
|  | +	seq = seq_insert (seq, &len, "2", (seq_compar)strcmp, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	assert_str_eq (seq[0], "1");
 | ||||||
|  | +	assert_str_eq (seq[1], "2");
 | ||||||
|  | +	assert_str_eq (seq[2], "3");
 | ||||||
|  | +	assert_str_eq (seq[3], "4");
 | ||||||
|  | +	assert (seq[4] == NULL);
 | ||||||
|  | +	assert_num_eq (len, 4);
 | ||||||
|  | +
 | ||||||
|  | +	seq_remove (seq, &len, "4", (seq_compar)strcmp, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	assert_str_eq (seq[0], "1");
 | ||||||
|  | +	assert_str_eq (seq[1], "2");
 | ||||||
|  | +	assert_str_eq (seq[2], "3");
 | ||||||
|  | +	assert (seq[3] == NULL);
 | ||||||
|  | +	assert_num_eq (len, 3);
 | ||||||
|  | +
 | ||||||
|  | +	seq_free (seq, NULL);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static int | ||||||
|  |  compar_even (void *match, | ||||||
|  |               void *value) | ||||||
|  | @@ -631,6 +763,9 @@ main (int argc,
 | ||||||
|  |  	test_func (test_insert, "/seq/insert"); | ||||||
|  |  	test_func (test_insert_destroys, "/seq/insert_destroys"); | ||||||
|  |  	test_func (test_remove, "/seq/remove"); | ||||||
|  | +	test_func (test_remove_unsorted, "/seq/remove_unsorted");
 | ||||||
|  | +	test_func (test_remove_first, "/seq/remove_first");
 | ||||||
|  | +	test_func (test_remove_last, "/seq/remove_last");
 | ||||||
|  |  	test_func (test_remove_destroys, "/seq/remove_destroys"); | ||||||
|  |  	test_func (test_filter, "/seq/filter"); | ||||||
|  |  	test_func (test_filter_null, "/seq/filter_null"); | ||||||
|  | diff --git a/library/seq.h b/library/seq.h
 | ||||||
|  | index 694965b..5d48848 100644
 | ||||||
|  | --- a/library/seq.h
 | ||||||
|  | +++ b/library/seq.h
 | ||||||
|  | @@ -44,6 +44,12 @@ typedef void *     (* seq_copy)               (void *value);
 | ||||||
|  |   | ||||||
|  |  typedef void       (* seq_destroy)            (void *value); | ||||||
|  |   | ||||||
|  | +typedef int        (* seq_search)             (void **seq,
 | ||||||
|  | +                                               int low,
 | ||||||
|  | +                                               int high,
 | ||||||
|  | +                                               void *match,
 | ||||||
|  | +                                               seq_compar compar);
 | ||||||
|  | +
 | ||||||
|  |  seq_voidp          seq_push                   (seq_voidp seq, | ||||||
|  |                                                 int *length, | ||||||
|  |                                                 void *value) WARN_UNUSED; | ||||||
|  | @@ -62,6 +68,12 @@ void               seq_remove                 (seq_voidp seq,
 | ||||||
|  |                                                 seq_compar compar, | ||||||
|  |                                                 seq_destroy destroy); | ||||||
|  |   | ||||||
|  | +void               seq_remove_unsorted        (seq_voidp seq,
 | ||||||
|  | +                                               int *length,
 | ||||||
|  | +                                               void *match,
 | ||||||
|  | +                                               seq_compar compar,
 | ||||||
|  | +                                               seq_destroy destroy);
 | ||||||
|  | +
 | ||||||
|  |  seq_voidp          seq_lookup                 (seq_voidp seq, | ||||||
|  |                                                 int *length, | ||||||
|  |                                                 void *match, | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										360
									
								
								0022-Add-add-service-principal-and-remove-service-princip.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								0022-Add-add-service-principal-and-remove-service-princip.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,360 @@ | |||||||
|  | From ee71c4c0614a504b4472bf64a24fc3c18c6b9987 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 14 Jun 2018 16:49:26 +0200 | ||||||
|  | Subject: [PATCH 22/23] Add add-service-principal and remove-service-principal | ||||||
|  |  options | ||||||
|  | 
 | ||||||
|  | Currently it is only possible to specific a service name for service | ||||||
|  | principals but not to set the full service principal. This is e.g. | ||||||
|  | needed if there is a service running on a host which should be reachable | ||||||
|  | by a different DNS name as well. | ||||||
|  | 
 | ||||||
|  | With this patch service principal can be added and removed by specifying | ||||||
|  | the full name. | ||||||
|  | 
 | ||||||
|  | Related to https://bugzilla.redhat.com/show_bug.cgi?id=1547014 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml      |  21 ++++++++ | ||||||
|  |  library/adenroll.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++-- | ||||||
|  |  library/adenroll.h |   8 +++ | ||||||
|  |  library/adldap.c   |  16 ++++-- | ||||||
|  |  tools/computer.c   |  13 +++++ | ||||||
|  |  5 files changed, 189 insertions(+), 8 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index b246190..83b6981 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -290,6 +290,14 @@ Password for Administrator:
 | ||||||
|  |  			not allow that Kerberos tickets can be forwarded to the | ||||||
|  |  			host.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--add-service-principal=<parameter>service/hostname</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Add a service principal name. In
 | ||||||
|  | +			contrast to the <option>--service-name</option> the
 | ||||||
|  | +			hostname part can be specified as well in case the
 | ||||||
|  | +			service should be accessible with a different host
 | ||||||
|  | +			name as well.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>--show-details</option></term> | ||||||
|  |  			<listitem><para>After a successful join print out information | ||||||
|  | @@ -416,6 +424,19 @@ $ adcli update --login-ccache=/tmp/krbcc_123
 | ||||||
|  |  			not allow that Kerberos tickets can be forwarded to the | ||||||
|  |  			host.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--add-service-principal=<parameter>service/hostname</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Add a service principal name. In
 | ||||||
|  | +			contrast to the <option>--service-name</option> the
 | ||||||
|  | +			hostname part can be specified as well in case the
 | ||||||
|  | +			service should be accessible with a different host
 | ||||||
|  | +			name as well.</para></listitem>
 | ||||||
|  | +		</varlistentry>
 | ||||||
|  | +		<varlistentry>
 | ||||||
|  | +			<term><option>--remove-service-principal=<parameter>service/hostname</parameter></option></term>
 | ||||||
|  | +			<listitem><para>Remove a service principal name from
 | ||||||
|  | +			the keytab and the AD host object.</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 b508caf..c4ba537 100644
 | ||||||
|  | --- a/library/adenroll.c
 | ||||||
|  | +++ b/library/adenroll.c
 | ||||||
|  | @@ -95,6 +95,9 @@ struct _adcli_enroll {
 | ||||||
|  |  	char **service_principals; | ||||||
|  |  	int service_principals_explicit; | ||||||
|  |   | ||||||
|  | +	char **service_principals_to_add;
 | ||||||
|  | +	char **service_principals_to_remove;
 | ||||||
|  | +
 | ||||||
|  |  	char *user_principal; | ||||||
|  |  	int user_princpal_generate; | ||||||
|  |   | ||||||
|  | @@ -332,6 +335,43 @@ add_service_names_to_service_principals (adcli_enroll *enroll)
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static adcli_result
 | ||||||
|  | +add_and_remove_service_principals (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	int length = 0;
 | ||||||
|  | +	size_t c;
 | ||||||
|  | +	const char **list;
 | ||||||
|  | +
 | ||||||
|  | +	if (enroll->service_principals != NULL) {
 | ||||||
|  | +		length = seq_count (enroll->service_principals);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	list = adcli_enroll_get_service_principals_to_add (enroll);
 | ||||||
|  | +	if (list != NULL) {
 | ||||||
|  | +		for (c = 0; list[c] != NULL; c++) {
 | ||||||
|  | +			enroll->service_principals = _adcli_strv_add (enroll->service_principals,
 | ||||||
|  | +			                                              strdup (list[c]),
 | ||||||
|  | +			                                              &length);
 | ||||||
|  | +			if (enroll->service_principals == NULL) {
 | ||||||
|  | +				return ADCLI_ERR_UNEXPECTED;
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	list = adcli_enroll_get_service_principals_to_remove (enroll);
 | ||||||
|  | +	if (list != NULL) {
 | ||||||
|  | +		for (c = 0; list[c] != NULL; c++) {
 | ||||||
|  | +			/* enroll->service_principals typically refects the
 | ||||||
|  | +			 * order of the principal in the keytabm so it is not
 | ||||||
|  | +			 * ordered. */
 | ||||||
|  | +			_adcli_strv_remove_unsorted (enroll->service_principals,
 | ||||||
|  | +			                             list[c], &length);
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return ADCLI_SUCCESS;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static adcli_result | ||||||
|  |  ensure_service_principals (adcli_result res, | ||||||
|  |                             adcli_enroll *enroll) | ||||||
|  | @@ -343,10 +383,14 @@ ensure_service_principals (adcli_result res,
 | ||||||
|  |   | ||||||
|  |  	if (!enroll->service_principals) { | ||||||
|  |  		assert (enroll->service_names != NULL); | ||||||
|  | -		return add_service_names_to_service_principals (enroll);
 | ||||||
|  | +		res = add_service_names_to_service_principals (enroll);
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	return ADCLI_SUCCESS;
 | ||||||
|  | +	if (res == ADCLI_SUCCESS) {
 | ||||||
|  | +		res = add_and_remove_service_principals (enroll);
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return res;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static adcli_result | ||||||
|  | @@ -1593,6 +1637,39 @@ free_principal_salts (krb5_context k5,
 | ||||||
|  |  	free (salts); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static adcli_result
 | ||||||
|  | +remove_principal_from_keytab (adcli_enroll *enroll,
 | ||||||
|  | +                              krb5_context k5,
 | ||||||
|  | +                              const char *principal_name)
 | ||||||
|  | +{
 | ||||||
|  | +	krb5_error_code code;
 | ||||||
|  | +	krb5_principal principal;
 | ||||||
|  | +	match_principal_kvno closure;
 | ||||||
|  | +
 | ||||||
|  | +	code = krb5_parse_name (k5, principal_name, &principal);
 | ||||||
|  | +	if (code != 0) {
 | ||||||
|  | +		_adcli_err ("Couldn't parse principal: %s: %s",
 | ||||||
|  | +		            principal_name, krb5_get_error_message (k5, code));
 | ||||||
|  | +		return ADCLI_ERR_FAIL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	closure.kvno = enroll->kvno;
 | ||||||
|  | +	closure.principal = principal;
 | ||||||
|  | +	closure.matched = 0;
 | ||||||
|  | +
 | ||||||
|  | +	code = _adcli_krb5_keytab_clear (k5, enroll->keytab,
 | ||||||
|  | +	                                 match_principal_and_kvno, &closure);
 | ||||||
|  | +	krb5_free_principal (k5, principal);
 | ||||||
|  | +
 | ||||||
|  | +	if (code != 0) {
 | ||||||
|  | +		_adcli_err ("Couldn't update keytab: %s: %s",
 | ||||||
|  | +		            enroll->keytab_name, krb5_get_error_message (k5, code));
 | ||||||
|  | +		return ADCLI_ERR_FAIL;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return ADCLI_SUCCESS;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  static adcli_result | ||||||
|  |  add_principal_to_keytab (adcli_enroll *enroll, | ||||||
|  |                           krb5_context k5, | ||||||
|  | @@ -1702,6 +1779,17 @@ update_keytab_for_principals (adcli_enroll *enroll,
 | ||||||
|  |  			return res; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	if (enroll->service_principals_to_remove != NULL) {
 | ||||||
|  | +		for (i = 0; enroll->service_principals_to_remove[i] != NULL; i++) {
 | ||||||
|  | +			res = remove_principal_from_keytab (enroll, k5,
 | ||||||
|  | +			                                    enroll->service_principals_to_remove[i]);
 | ||||||
|  | +			if (res != ADCLI_SUCCESS) {
 | ||||||
|  | +				_adcli_warn ("Failed to remove %s from keytab.",
 | ||||||
|  | +				             enroll->service_principals_to_remove[i]);
 | ||||||
|  | +			}
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	return ADCLI_SUCCESS; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -2029,8 +2117,11 @@ adcli_enroll_update (adcli_enroll *enroll,
 | ||||||
|  |  	if (_adcli_check_nt_time_string_lifetime (value, | ||||||
|  |  	                adcli_enroll_get_computer_password_lifetime (enroll))) { | ||||||
|  |  		/* Do not update keytab if neither new service principals have | ||||||
|  | -                 * to be added nor the user principal has to be changed. */
 | ||||||
|  | -		if (enroll->service_names == NULL && (enroll->user_principal == NULL || enroll->user_princpal_generate)) {
 | ||||||
|  | +                 * to be added or deleted nor the user principal has to be changed. */
 | ||||||
|  | +		if (enroll->service_names == NULL
 | ||||||
|  | +		              && (enroll->user_principal == NULL || enroll->user_princpal_generate)
 | ||||||
|  | +		              && enroll->service_principals_to_add == NULL
 | ||||||
|  | +		              && enroll->service_principals_to_remove == NULL) {
 | ||||||
|  |  			flags |= ADCLI_ENROLL_NO_KEYTAB; | ||||||
|  |  		} | ||||||
|  |  		flags |= ADCLI_ENROLL_PASSWORD_VALID; | ||||||
|  | @@ -2581,3 +2672,43 @@ adcli_enroll_set_trusted_for_delegation (adcli_enroll *enroll,
 | ||||||
|  |  	enroll->trusted_for_delegation = value; | ||||||
|  |  	enroll->trusted_for_delegation_explicit = 1; | ||||||
|  |  } | ||||||
|  | +
 | ||||||
|  | +const char **
 | ||||||
|  | +adcli_enroll_get_service_principals_to_add (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	return_val_if_fail (enroll != NULL, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	return (const char **)enroll->service_principals_to_add;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +adcli_enroll_add_service_principal_to_add (adcli_enroll *enroll,
 | ||||||
|  | +                                           const char *value)
 | ||||||
|  | +{
 | ||||||
|  | +	return_if_fail (enroll != NULL);
 | ||||||
|  | +	return_if_fail (value != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	enroll->service_principals_to_add = _adcli_strv_add (enroll->service_principals_to_add,
 | ||||||
|  | +							    strdup (value), NULL);
 | ||||||
|  | +	return_if_fail (enroll->service_principals_to_add != NULL);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +const char **
 | ||||||
|  | +adcli_enroll_get_service_principals_to_remove (adcli_enroll *enroll)
 | ||||||
|  | +{
 | ||||||
|  | +	return_val_if_fail (enroll != NULL, NULL);
 | ||||||
|  | +
 | ||||||
|  | +	return (const char **)enroll->service_principals_to_remove;
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  | +void
 | ||||||
|  | +adcli_enroll_add_service_principal_to_remove (adcli_enroll *enroll,
 | ||||||
|  | +                                              const char *value)
 | ||||||
|  | +{
 | ||||||
|  | +	return_if_fail (enroll != NULL);
 | ||||||
|  | +	return_if_fail (value != NULL);
 | ||||||
|  | +
 | ||||||
|  | +	enroll->service_principals_to_remove = _adcli_strv_add (enroll->service_principals_to_remove,
 | ||||||
|  | +							    strdup (value), NULL);
 | ||||||
|  | +	return_if_fail (enroll->service_principals_to_remove != NULL);
 | ||||||
|  | +}
 | ||||||
|  | diff --git a/library/adenroll.h b/library/adenroll.h
 | ||||||
|  | index be2ca18..f87dffa 100644
 | ||||||
|  | --- a/library/adenroll.h
 | ||||||
|  | +++ b/library/adenroll.h
 | ||||||
|  | @@ -98,6 +98,14 @@ const char **      adcli_enroll_get_service_principals  (adcli_enroll *enroll);
 | ||||||
|  |  void               adcli_enroll_set_service_principals  (adcli_enroll *enroll, | ||||||
|  |                                                           const char **value); | ||||||
|  |   | ||||||
|  | +const char **      adcli_enroll_get_service_principals_to_add (adcli_enroll *enroll);
 | ||||||
|  | +void               adcli_enroll_add_service_principal_to_add (adcli_enroll *enroll,
 | ||||||
|  | +                                                              const char *value);
 | ||||||
|  | +
 | ||||||
|  | +const char **      adcli_enroll_get_service_principals_to_remove (adcli_enroll *enroll);
 | ||||||
|  | +void               adcli_enroll_add_service_principal_to_remove (adcli_enroll *enroll,
 | ||||||
|  | +                                                                 const char *value);
 | ||||||
|  | +
 | ||||||
|  |  const char *       adcli_enroll_get_user_principal      (adcli_enroll *enroll); | ||||||
|  |   | ||||||
|  |  void               adcli_enroll_set_user_principal      (adcli_enroll *enroll, | ||||||
|  | diff --git a/library/adldap.c b/library/adldap.c
 | ||||||
|  | index 07dc373..d93efb7 100644
 | ||||||
|  | --- a/library/adldap.c
 | ||||||
|  | +++ b/library/adldap.c
 | ||||||
|  | @@ -210,16 +210,24 @@ _adcli_ldap_have_in_mod (LDAPMod *mod,
 | ||||||
|  |  	struct berval *vals; | ||||||
|  |  	struct berval **pvals; | ||||||
|  |  	int count = 0; | ||||||
|  | +	int count_have = 0;
 | ||||||
|  |  	int i; | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  | -	/* Already in berval format, just compare */
 | ||||||
|  | -	if (mod->mod_op & LDAP_MOD_BVALUES)
 | ||||||
|  | -		return _adcli_ldap_have_vals (mod->mod_vals.modv_bvals, have);
 | ||||||
|  | -
 | ||||||
|  |  	/* Count number of values */ | ||||||
|  |  	for (i = 0; mod->mod_vals.modv_strvals[i] != 0; i++) | ||||||
|  |  		count++; | ||||||
|  | +	for (i = 0; have[i] != 0; i++)
 | ||||||
|  | +		count_have++;
 | ||||||
|  | +
 | ||||||
|  | +	/* If numbers different something has to be added or removed */
 | ||||||
|  | +	if (count != count_have) {
 | ||||||
|  | +		return 0;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	/* Already in berval format, just compare */
 | ||||||
|  | +	if (mod->mod_op & LDAP_MOD_BVALUES)
 | ||||||
|  | +		return _adcli_ldap_have_vals (mod->mod_vals.modv_bvals, have);
 | ||||||
|  |   | ||||||
|  |  	vals = malloc (sizeof (struct berval) * (count + 1)); | ||||||
|  |  	pvals = malloc (sizeof (struct berval *) * (count + 1)); | ||||||
|  | diff --git a/tools/computer.c b/tools/computer.c
 | ||||||
|  | index b905fd1..377d449 100644
 | ||||||
|  | --- a/tools/computer.c
 | ||||||
|  | +++ b/tools/computer.c
 | ||||||
|  | @@ -110,6 +110,8 @@ typedef enum {
 | ||||||
|  |  	opt_add_samba_data, | ||||||
|  |  	opt_samba_data_tool, | ||||||
|  |  	opt_trusted_for_delegation, | ||||||
|  | +	opt_add_service_principal,
 | ||||||
|  | +	opt_remove_service_principal,
 | ||||||
|  |  } Option; | ||||||
|  |   | ||||||
|  |  static adcli_tool_desc common_usages[] = { | ||||||
|  | @@ -138,6 +140,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_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_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" | ||||||
|  | @@ -289,6 +293,12 @@ parse_option (Option opt,
 | ||||||
|  |  			adcli_enroll_set_trusted_for_delegation (enroll, false); | ||||||
|  |  		} | ||||||
|  |  		return; | ||||||
|  | +	case opt_add_service_principal:
 | ||||||
|  | +		adcli_enroll_add_service_principal_to_add (enroll, optarg);
 | ||||||
|  | +		return;
 | ||||||
|  | +	case opt_remove_service_principal:
 | ||||||
|  | +		adcli_enroll_add_service_principal_to_remove (enroll, optarg);
 | ||||||
|  | +		return;
 | ||||||
|  |  	case opt_verbose: | ||||||
|  |  		return; | ||||||
|  |   | ||||||
|  | @@ -353,6 +363,7 @@ adcli_tool_computer_join (adcli_conn *conn,
 | ||||||
|  |  		{ "os-service-pack", optional_argument, NULL, opt_os_service_pack }, | ||||||
|  |  		{ "user-principal", optional_argument, NULL, opt_user_principal }, | ||||||
|  |  		{ "trusted-for-delegation", required_argument, NULL, opt_trusted_for_delegation }, | ||||||
|  | +		{ "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 }, | ||||||
|  |  		{ "add-samba-data", no_argument, NULL, opt_add_samba_data }, | ||||||
|  | @@ -458,6 +469,8 @@ 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 }, | ||||||
|  | +		{ "add-service-principal", required_argument, NULL, opt_add_service_principal },
 | ||||||
|  | +		{ "remove-service-principal", required_argument, NULL, opt_remove_service_principal },
 | ||||||
|  |  		{ "show-details", no_argument, NULL, opt_show_details }, | ||||||
|  |  		{ "show-password", no_argument, NULL, opt_show_password }, | ||||||
|  |  		{ "add-samba-data", no_argument, NULL, opt_add_samba_data }, | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,32 @@ | |||||||
|  | From 026cfacabfad58ae2cebcdf6cd82d905023ea289 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 31 May 2018 17:01:36 +0200 | ||||||
|  | Subject: [PATCH 23/23] adcli_conn_is_writeable: do not crash id domain_disco | ||||||
|  |  is missing | ||||||
|  | 
 | ||||||
|  | Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1575554 | ||||||
|  | ---
 | ||||||
|  |  library/adconn.c | 9 +++++++-- | ||||||
|  |  1 file changed, 7 insertions(+), 2 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/library/adconn.c b/library/adconn.c
 | ||||||
|  | index d2fb1d5..e2250e3 100644
 | ||||||
|  | --- a/library/adconn.c
 | ||||||
|  | +++ b/library/adconn.c
 | ||||||
|  | @@ -1567,6 +1567,11 @@ adcli_conn_server_has_capability (adcli_conn *conn,
 | ||||||
|  |   | ||||||
|  |  bool adcli_conn_is_writeable (adcli_conn *conn) | ||||||
|  |  { | ||||||
|  | -    disco_dance_if_necessary (conn);
 | ||||||
|  | -    return ( (conn->domain_disco->flags & ADCLI_DISCO_WRITABLE) != 0);
 | ||||||
|  | +	disco_dance_if_necessary (conn);
 | ||||||
|  | +
 | ||||||
|  | +	if (conn->domain_disco == NULL) {
 | ||||||
|  | +		return false;
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  | +	return ( (conn->domain_disco->flags & ADCLI_DISCO_WRITABLE) != 0);
 | ||||||
|  |  } | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										203
									
								
								0024-doc-fix-typos-in-the-adcli-man-page.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								0024-doc-fix-typos-in-the-adcli-man-page.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,203 @@ | |||||||
|  | From 1e57862cf5d8f4f774868b3599e4a34c525ae348 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sumit Bose <sbose@redhat.com> | ||||||
|  | Date: Thu, 5 Jul 2018 13:06:26 +0200 | ||||||
|  | Subject: [PATCH 24/24] doc: fix typos in the adcli man page | ||||||
|  | 
 | ||||||
|  | Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1440533 | ||||||
|  | ---
 | ||||||
|  |  doc/adcli.xml | 44 ++++++++++++++++++++++---------------------- | ||||||
|  |  1 file changed, 22 insertions(+), 22 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/doc/adcli.xml b/doc/adcli.xml
 | ||||||
|  | index 83b6981..97dec08 100644
 | ||||||
|  | --- a/doc/adcli.xml
 | ||||||
|  | +++ b/doc/adcli.xml
 | ||||||
|  | @@ -105,19 +105,19 @@
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-D, --domain=<parameter>domain</parameter></option></term> | ||||||
|  |  			<listitem><para>The domain to connect to. If a domain is | ||||||
|  | -			not specified then the domain part of the local computer's
 | ||||||
|  | +			not specified, then the domain part of the local computer's
 | ||||||
|  |  			host name is used.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-R, --domain-realm=<parameter>REALM</parameter></option></term> | ||||||
|  |  			<listitem><para>Kerberos realm for the domain. If not | ||||||
|  | -			specified then the upper cased domain name is
 | ||||||
|  | +			specified, then the upper cased domain name is
 | ||||||
|  |  			used.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-S, --domain-controller=<parameter>server</parameter></option></term> | ||||||
|  |  			<listitem><para>Connect to a specific domain controller. | ||||||
|  | -			If not specified then an appropriate domain controller
 | ||||||
|  | +			If not specified, then an appropriate domain controller
 | ||||||
|  |  			is automatically discovered.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  | @@ -134,7 +134,7 @@
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-U, --login-user=<parameter>User</parameter></option></term> | ||||||
|  |  			<listitem><para>Use the specified user account to | ||||||
|  | -			authenticate with the domain. If not specified then
 | ||||||
|  | +			authenticate with the domain. If not specified, then
 | ||||||
|  |  			the name 'Administrator' will be used.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  | @@ -181,7 +181,7 @@ $ adcli info --domain-controller=dc.domain.example.com
 | ||||||
|  |  	<para><command>adcli info</command> will output as much information as | ||||||
|  |  	it can about the domain. The information is designed to be both machine | ||||||
|  |  	and human readable. The command will exit with a non-zero exit code | ||||||
|  | -	if the domain does note exist or cannot be reached.</para>
 | ||||||
|  | +	if the domain does not exist or cannot be reached.</para>
 | ||||||
|  |   | ||||||
|  |  	<para>To show domain info for a specific domain controller use the | ||||||
|  |  	<option>--domain-controller</option> option to specify which domain | ||||||
|  | @@ -213,35 +213,35 @@ Password for Administrator:
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-N, --computer-name=<parameter>computer</parameter></option></term> | ||||||
|  |  			<listitem><para>The short non-dotted name of the computer | ||||||
|  | -			account that will be created in the domain. If not specified
 | ||||||
|  | +			account that will be created in the domain. If not specified,
 | ||||||
|  |  			then the first portion of the <option>--host-fqdn</option> | ||||||
|  |  			is used.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-O, --domain-ou=<parameter>OU=xxx</parameter></option></term> | ||||||
|  |  			<listitem><para>The full distinguished name of the OU in | ||||||
|  | -			which to create the computer account. If not specified
 | ||||||
|  | +			which to create the computer account. If not specified,
 | ||||||
|  |  			then the computer account will be created in a default | ||||||
|  |  			location.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-H, --host-fqdn=<parameter>host</parameter></option></term> | ||||||
|  |  			<listitem><para>Override the local machine's fully qualified | ||||||
|  | -			domain name. If not specified the local machine's hostname
 | ||||||
|  | +			domain name. If not specified, the local machine's hostname
 | ||||||
|  |  			will be retrieved via <function>gethostname()</function>.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-K, --host-keytab=<parameter>/path/to/keytab</parameter></option></term> | ||||||
|  |  			<listitem><para>Specify the path to the host keytab where | ||||||
|  |  			host credentials will be written after a successful join | ||||||
|  | -			operation. If not specified the default location will be
 | ||||||
|  | +			operation. If not specified, the default location will be
 | ||||||
|  |  			used, usually <filename>/etc/krb5.keytab</filename>.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>--login-type=<parameter>{computer|user}</parameter></option></term> | ||||||
|  |  			<listitem><para>Specify the type of authentication that | ||||||
|  |  			will be performed before creating the machine account in | ||||||
|  | -			the domain. If set to 'computer' then the computer must
 | ||||||
|  | +			the domain. If set to 'computer', then the computer must
 | ||||||
|  |  			already have a preset account in the domain. If not | ||||||
|  |  			specified and none of the other <option>--login-xxx</option> | ||||||
|  |  			arguments have been specified, then will try both | ||||||
|  | @@ -329,7 +329,7 @@ Password for Administrator:
 | ||||||
|  |  			<term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term> | ||||||
|  |  			<listitem><para>If Samba's <command>net</command> | ||||||
|  |  			cannot be found at | ||||||
|  | -			<filename>&samba_data_tool;</filename> this option can
 | ||||||
|  | +			<filename>&samba_data_tool;</filename>, this option can
 | ||||||
|  |  			be used to specific an alternative location with the | ||||||
|  |  			help of an absolute path.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | @@ -351,7 +351,7 @@ Password for Administrator:
 | ||||||
|  |  $ adcli update | ||||||
|  |  </programlisting> | ||||||
|  |   | ||||||
|  | -	<para>If used with a credential cache other attributes of the computer
 | ||||||
|  | +	<para>If used with a credential cache, other attributes of the computer
 | ||||||
|  |  	account can be changed as well if the principal has sufficient | ||||||
|  |  	privileges.</para> | ||||||
|  |   | ||||||
|  | @@ -367,20 +367,20 @@ $ adcli update --login-ccache=/tmp/krbcc_123
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-N, --computer-name=<parameter>computer</parameter></option></term> | ||||||
|  |  			<listitem><para>The short non-dotted name of the computer | ||||||
|  | -			account that will be created in the domain. If not specified
 | ||||||
|  | +			account that will be created in the domain. If not specified,
 | ||||||
|  |  			it will be retrieved from the keytab entries.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-H, --host-fqdn=<parameter>host</parameter></option></term> | ||||||
|  |  			<listitem><para>The local machine's fully qualified | ||||||
|  | -			domain name. If not specified the local machine's hostname
 | ||||||
|  | +			domain name. If not specified, the local machine's hostname
 | ||||||
|  |  			will be retrieved from the keytab entries.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-K, --host-keytab=<parameter>/path/to/keytab</parameter></option></term> | ||||||
|  |  			<listitem><para>Specify the path to the host keytab where | ||||||
|  |  			current host credentials are stored and the new ones | ||||||
|  | -			will be written to.  If not specified the default
 | ||||||
|  | +			will be written to.  If not specified, the default
 | ||||||
|  |  			location will be used, usually | ||||||
|  |  			<filename>/etc/krb5.keytab</filename>.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | @@ -462,7 +462,7 @@ $ adcli update --login-ccache=/tmp/krbcc_123
 | ||||||
|  |  			<term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term> | ||||||
|  |  			<listitem><para>If Samba's <command>net</command> | ||||||
|  |  			cannot be found at | ||||||
|  | -			<filename>&samba_data_tool;</filename> this option can
 | ||||||
|  | +			<filename>&samba_data_tool;</filename>, this option can
 | ||||||
|  |  			be used to specific an alternative location with the | ||||||
|  |  			help of an absolute path.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | @@ -493,7 +493,7 @@ $ adcli create-user Fry --domain=domain.example.com \
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-O, --domain-ou=<parameter>OU=xxx</parameter></option></term> | ||||||
|  |  			<listitem><para>The full distinguished name of the OU in | ||||||
|  | -			which to create the user account. If not specified
 | ||||||
|  | +			which to create the user account. If not specified,
 | ||||||
|  |  			then the computer account will be created in a default | ||||||
|  |  			location.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | @@ -569,7 +569,7 @@ $ adcli create-group Pilots --domain=domain.example.com \
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-O, --domain-ou=<parameter>OU=xxx</parameter></option></term> | ||||||
|  |  			<listitem><para>The full distinguished name of the OU in | ||||||
|  | -			which to create the group. If not specified
 | ||||||
|  | +			which to create the group. If not specified,
 | ||||||
|  |  			then the group will be created in a default | ||||||
|  |  			location.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | @@ -649,14 +649,14 @@ Password for Administrator:
 | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>-O, --domain-ou=<parameter>OU=xxx</parameter></option></term> | ||||||
|  |  			<listitem><para>The full distinguished name of the OU in | ||||||
|  | -			which to create the computer accounts. If not specified
 | ||||||
|  | +			which to create the computer accounts. If not specified,
 | ||||||
|  |  			then the computer account will be created in a default | ||||||
|  |  			location.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  |  		<varlistentry> | ||||||
|  |  			<term><option>--one-time-password</option></term> | ||||||
|  |  			<listitem><para>Specify a one time password to use when | ||||||
|  | -			presetting the computer accounts. If not specified then
 | ||||||
|  | +			presetting the computer accounts. If not specified, then
 | ||||||
|  |  			a default password will be used, which allows for later | ||||||
|  |  			automatic joins.</para></listitem> | ||||||
|  |  		</varlistentry> | ||||||
|  | @@ -696,7 +696,7 @@ Password for Administrator:
 | ||||||
|  |  	<title>Reset Computer Account</title> | ||||||
|  |   | ||||||
|  |  	<para><command>adcli reset-computer</command> resets a computer account | ||||||
|  | -	in the domain. If a the appropriate machine is currently joined to the
 | ||||||
|  | +	in the domain. If the appropriate machine is currently joined to the
 | ||||||
|  |  	domain, then its membership will be broken. The account must already | ||||||
|  |  	exist.</para> | ||||||
|  |   | ||||||
|  | @@ -716,7 +716,7 @@ $ adcli reset-computer --domain=domain.example.com host2
 | ||||||
|  |  			<term><option>--login-type=<parameter>{computer|user}</parameter></option></term> | ||||||
|  |  			<listitem><para>Specify the type of authentication that | ||||||
|  |  			will be performed before creating the machine account in | ||||||
|  | -			the domain. If set to 'computer' then the computer must
 | ||||||
|  | +			the domain. If set to 'computer', then the computer must
 | ||||||
|  |  			already have a preset account in the domain. If not | ||||||
|  |  			specified and none of the other <option>--login-xxx</option> | ||||||
|  |  			arguments have been specified, then will try both | ||||||
|  | -- 
 | ||||||
|  | 2.14.4 | ||||||
|  | 
 | ||||||
							
								
								
									
										395
									
								
								adcli.spec
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										395
									
								
								adcli.spec
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,395 @@ | |||||||
|  | Name:		adcli | ||||||
|  | Version:	0.8.2 | ||||||
|  | Release:	12%{?dist} | ||||||
|  | Summary:	Active Directory enrollment | ||||||
|  | License:	LGPLv2+ | ||||||
|  | URL:		http://cgit.freedesktop.org/realmd/adcli | ||||||
|  | Source0:	http://www.freedesktop.org/software/realmd/releases/adcli-%{version}.tar.gz | ||||||
|  | 
 | ||||||
|  | Patch1:		0001-Remove-upper-case-only-check-when-looking-for-the-Ne.patch | ||||||
|  | Patch2:		0002-Use-strdup-if-offset-are-used.patch | ||||||
|  | Patch3:		0003-correct-spelling-of-adcli_tool_computer_delete-descr.patch | ||||||
|  | Patch4:		0004-doc-explain-that-all-credential-cache-types-are-supp.patch | ||||||
|  | Patch5:		0005-library-add-adcli_conn_is_writeable.patch | ||||||
|  | Patch6:		0006-Handle-kvno-increment-for-RODCs.patch | ||||||
|  | Patch7:		0007-Fix-memory-leak-in-test_check_nt_time_string_lifetim.patch | ||||||
|  | Patch8:		0008-library-add-_adcli_bin_sid_to_str.patch | ||||||
|  | Patch9:		0009-library-add-_adcli_call_external_program.patch | ||||||
|  | Patch10:	0010-library-add-_adcli_ldap_parse_sid.patch | ||||||
|  | Patch11:	0011-library-add-lookup_domain_sid.patch | ||||||
|  | Patch12:	0012-library-add-adcli_conn_get_domain_sid.patch | ||||||
|  | Patch13:	0013-tools-add-option-add-samba-data.patch | ||||||
|  | Patch14:	0014-tools-store-Samba-data-if-requested.patch | ||||||
|  | Patch15:	0015-make-Samba-data-tool-configurable.patch | ||||||
|  | Patch16:	0016-Add-trusted-for-delegation-option.patch | ||||||
|  | Patch17:	0017-Only-update-attributes-given-on-the-command-line.patch | ||||||
|  | Patch18:	0018-update-allow-to-add-service-names.patch | ||||||
|  | Patch19:	0019-Calculate-enctypes-in-a-separate-function.patch | ||||||
|  | Patch20:	0020-join-add-all-attributes-while-creating-computer-obje.patch | ||||||
|  | Patch21:	0021-util-add-_adcli_strv_remove_unsorted.patch | ||||||
|  | Patch22:	0022-Add-add-service-principal-and-remove-service-princip.patch | ||||||
|  | Patch23:	0023-adcli_conn_is_writeable-do-not-crash-id-domain_disco.patch | ||||||
|  | Patch24:	0024-doc-fix-typos-in-the-adcli-man-page.patch | ||||||
|  | 
 | ||||||
|  | Patch25:	0001-fix-typo-in-flag-value.patch | ||||||
|  | Patch26:	0002-_adcli_call_external_program-silence-noisy-debug-mes.patch | ||||||
|  | Patch27:	0003-Do-not-add-service-principals-twice.patch | ||||||
|  | Patch28:	0004-Do-not-depend-on-default_realm-in-krb5.conf.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1677194 -  Realm cannot join domain when hostname is not FQDN | ||||||
|  | Patch29:	0001-adutil-add-_adcli_strv_add_unique.patch | ||||||
|  | Patch30:	0002-adenroll-use-_adcli_strv_add_unique-for-service-prin.patch | ||||||
|  | 
 | ||||||
|  | # Forward port of RHEL-7.7 ticket rhbz#1642546 - adcli exports kerberos ticket | ||||||
|  | # with old kvno | ||||||
|  | Patch31:	0001-Increment-kvno-after-password-change-with-user-creds.patch | ||||||
|  | 
 | ||||||
|  | # Forward port of RHEL-7.7 ticket rhbz#1595911 - [RFE] Have `adcli join` work | ||||||
|  | # without FQDN in `hostname` output | ||||||
|  | Patch32:	0001-library-use-getaddrinfo-with-AI_CANONNAME-to-find-a-.patch | ||||||
|  | 
 | ||||||
|  | # Forward port of RHEL-7.7 ticket rhbz#1644311 - Improve handling of service | ||||||
|  | # principals | ||||||
|  | Patch33:	0001-join-always-add-service-principals.patch | ||||||
|  | Patch34:	0002-library-return-error-if-no-matching-key-was-found.patch | ||||||
|  | 
 | ||||||
|  | # Forward port of RHEL-7.7 ticket rhbz#1337489 - [RFE] adcli command with | ||||||
|  | # --unix-* options doesn't update values in UnixAttributes Tab for user | ||||||
|  | Patch35:	0001-create-user-add-nis-domain-option.patch | ||||||
|  | Patch36:	0002-create-user-try-to-find-NIS-domain-if-needed.patch | ||||||
|  | 
 | ||||||
|  | # Forward port of RHEL-7.7 ticket rhbz#1630187 - [RFE] adcli join should | ||||||
|  | # preserve SPN added by adcli preset-computer | ||||||
|  | Patch37:	0001-ensure_keytab_principals-do-not-leak-memory-when-cal.patch | ||||||
|  | Patch38:	0002-library-make-_adcli_strv_has_ex-public.patch | ||||||
|  | Patch39:	0003-library-_adcli_krb5_build_principal-allow-principals.patch | ||||||
|  | Patch40:	0004-library-make-sure-server-side-SPNs-are-preserved.patch | ||||||
|  | 
 | ||||||
|  | # Forward port of RHEL-7.7 ticket rhbz#1622583 - [RFE] Need an option for adcli | ||||||
|  | # command which will show domain join status. | ||||||
|  | Patch41:	0001-Implement-adcli-testjoin.patch | ||||||
|  | 
 | ||||||
|  | # Forward port of RHEL-7.7 ticket rhbz#1630187 - [RFE] adcli join should | ||||||
|  | # preserve SPN added by adcli preset-computer - additional patch | ||||||
|  | Patch42:	0001-library-add-missing-strdup.patch | ||||||
|  | 
 | ||||||
|  | # Forward port of RHEL-7.7 ticket rhbz#1588596 - many adcli-krb5-????? | ||||||
|  | # directories are created /tmp | ||||||
|  | Patch43:	0001-tools-remove-errx-from-computer-commands.patch | ||||||
|  | Patch44:	0002-tools-remove-errx-from-user-and-group-commands.patch | ||||||
|  | Patch45:	0003-tools-remove-errx-from-info-commands.patch | ||||||
|  | Patch46:	0004-tools-remove-errx-from-adcli_read_password_func.patch | ||||||
|  | Patch47:	0005-tools-remove-errx-from-setup_krb5_conf_directory.patch | ||||||
|  | Patch48:	0006-tools-entry-remove-errx-from-parse_option.patch | ||||||
|  | Patch49:	0007-tools-computer-remove-errx-from-parse_option.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1717355 - `adcli join` fails in FIPS enabled environment | ||||||
|  | Patch50:	0001-Fix-for-issues-found-by-Coverity.patch | ||||||
|  | Patch51:	0001-adenroll-make-sure-only-allowed-enctypes-are-used-in.patch | ||||||
|  | Patch52:	0002-adconn-add-adcli_conn_set_krb5_context.patch | ||||||
|  | Patch53:	0003-adenroll-add-adcli_enroll_get_permitted_keytab_encty.patch | ||||||
|  | Patch54:	0004-adenroll-use-only-enctypes-permitted-by-Kerberos-con.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1745931 - adcli update --add-samba-data does not work as expected | ||||||
|  | Patch55:	0001-doc-explain-how-to-force-password-reset.patch | ||||||
|  | Patch56:	0001-man-move-note-to-the-right-section.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1745932 - Issue is that with arcfour-hmac as first encryption type | ||||||
|  | Patch57:	0001-Do-not-use-arcfour-hmac-md5-when-discovering-the-sal.patch | ||||||
|  | 
 | ||||||
|  | Patch58:	0001-Fix-for-issue-found-by-Coverity.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1737342 - [RFE] enhancement adcli to set description attribute and to | ||||||
|  | # show all AD attributes | ||||||
|  | Patch59:	0001-tools-add-show-computer-command.patch | ||||||
|  | Patch60:	0002-add-description-option-to-join-and-update.patch | ||||||
|  | 
 | ||||||
|  | Patch61:	0001-Use-GSS-SPNEGO-if-available.patch | ||||||
|  | Patch62:	0002-add-option-use-ldaps.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1806260 - [abrt] [faf] adcli: raise(): /usr/sbin/adcli killed by 6 | ||||||
|  | Patch63:	0001-Make-adcli-info-DC-location-mechanism-more-compliant.patch | ||||||
|  | Patch64:	0001-discovery-fix.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1846882 - No longer able to delete computer from AD using adcli | ||||||
|  | Patch65:	0001-delete-do-not-exit-if-keytab-cannot-be-read.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1846878 - adcli: presetting $computer in $domain domain failed: Cannot | ||||||
|  | # set computer password: Authentication error | ||||||
|  | Patch66:	0001-tools-disable-SSSD-s-locator-plugin.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1791611 - Typo in adcli update --help option | ||||||
|  | Patch67:	0001-tools-fix-typo-in-show-password-help-output.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1791545 - Manpage and help does not explain the use of "-C" option | ||||||
|  | Patch68:	0001-man-explain-optional-parameter-of-login-ccache-bette.patch | ||||||
|  | Patch69:	0001-man-make-handling-of-optional-credential-cache-more-.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1883467 - Add --use-ldaps option to adcli update as well | ||||||
|  | Patch70:	0001-tools-add-missing-use-ldaps-option-to-update-and-tes.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1734764 - Cannot join a pre-staged Computer Account on AD in Custom OU | ||||||
|  | # using Delegated user | ||||||
|  | Patch71:	0001-join-update-set-dNSHostName-if-not-set.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1852080 - missing documentation for required AD rights for adcli join | ||||||
|  | # and net join | ||||||
|  | Patch72:	0001-doc-add-missing-samba_data_tool_path.xml-.in-to-EXTR.patch | ||||||
|  | Patch73:	0001-doc-explain-required-AD-permissions.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1854112 - [RFE] Add new mode to just create an AD account to be able to | ||||||
|  | # connect to LDAP | ||||||
|  | Patch74:	0001-enroll-add-is_service-member.patch | ||||||
|  | Patch75:	0002-computer-add-create-msa-sub-command.patch | ||||||
|  | Patch76:	0003-enroll-use-computer-or-service-in-debug-messages.patch | ||||||
|  | Patch77:	0004-enroll-more-filters-for-random-characters.patch | ||||||
|  | Patch78:	0005-enroll-make-adcli_enroll_add_keytab_for_service_acco.patch | ||||||
|  | Patch79:	0006-enroll-allow-fqdn-for-locate_computer_account.patch | ||||||
|  | Patch80:	0007-service-account-add-random-suffix-to-account-name.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1906303 - Typo in CREATE A SERVICE ACCOUNT section of man page of adcli | ||||||
|  | Patch81:	0001-service-account-fix-typo-in-the-man-page-entry.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1889386 - [RFE] Adcli and Realm Error Code Optimization Request | ||||||
|  | Patch82:	0001-build-add-with-vendor-error-message-configure-option.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1769644 - [RFE] adcli should allow to modify DONT_EXPIRE_PASSWORD attribute | ||||||
|  | Patch83:	0001-coverity-add-missing-NULL-checks.patch | ||||||
|  | Patch84:	0002-Add-dont-expire-password-option.patch | ||||||
|  | Patch85:	0001-Fix-for-dont-expire-password-option-and-join.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1952828 - [RFE] Allow adcli to create AD user with password as well as | ||||||
|  | # set or reset existing user password | ||||||
|  | Patch86:	0001-library-move-UAC-flags-to-a-more-common-header-file.patch | ||||||
|  | Patch87:	0002-adcli_entry-add-entry_attrs-with-userAccountControl-.patch | ||||||
|  | Patch88:	0003-entry-add-passwd-user-sub-command.patch | ||||||
|  | 
 | ||||||
|  | # rhbz#1690920 - [RFE] add option to populate "managed by" computer attribute | ||||||
|  | Patch89:	0001-Add-setattr-option.patch | ||||||
|  | Patch90:	0002-Add-delattr-option.patch | ||||||
|  | 
 | ||||||
|  | BuildRequires:	gcc | ||||||
|  | BuildRequires:	intltool pkgconfig | ||||||
|  | BuildRequires:	libtool | ||||||
|  | BuildRequires:	gettext-devel | ||||||
|  | BuildRequires:	krb5-devel | ||||||
|  | BuildRequires:	openldap-devel | ||||||
|  | BuildRequires:	libxslt | ||||||
|  | BuildRequires:	xmlto | ||||||
|  | 
 | ||||||
|  | Requires:	cyrus-sasl-gssapi | ||||||
|  | 
 | ||||||
|  | # 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 {} ';' | ||||||
|  | 
 | ||||||
|  | %post -p /sbin/ldconfig | ||||||
|  | 
 | ||||||
|  | %postun -p /sbin/ldconfig | ||||||
|  | 
 | ||||||
|  | %clean | ||||||
|  | 
 | ||||||
|  | %files | ||||||
|  | %{_sbindir}/adcli | ||||||
|  | %doc AUTHORS COPYING ChangeLog NEWS README | ||||||
|  | %doc %{_mandir}/*/* | ||||||
|  | 
 | ||||||
|  | %package doc | ||||||
|  | Summary: adcli documentation | ||||||
|  | BuildArch: noarch | ||||||
|  | 
 | ||||||
|  | %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 Jun 14 2021 Sumit Bose <sbose@redhat.com> - 0.8.2-12 | ||||||
|  | - [RFE] Allow adcli to create AD user with password as well as set or reset | ||||||
|  |   existing user password [#1952828] | ||||||
|  | - [RFE] add option to populate "managed by" computer attribute [#1690920] | ||||||
|  | 
 | ||||||
|  | * Thu Jun 03 2021 Sumit Bose <sbose@redhat.com> - 0.8.2-11 | ||||||
|  | - Add missing patch for [#1769644] | ||||||
|  | 
 | ||||||
|  | * Thu Jun 03 2021 Sumit Bose <sbose@redhat.com> - 0.8.2-10 | ||||||
|  | - [RFE] Adcli and Realm Error Code Optimization Request [#1889386] | ||||||
|  | - [RFE] adcli should allow to modify DONT_EXPIRE_PASSWORD attribute [#1769644] | ||||||
|  | 
 | ||||||
|  | * Fri Dec 11 2020 Sumit Bose <sbose@redhat,com> - 0.8.2-9 | ||||||
|  | - Typo in CREATE A SERVICE ACCOUNT section of man page of adcli [#1906303] | ||||||
|  | 
 | ||||||
|  | * Wed Nov 11 2020 Sumit Bose <sbose@redhat.com> - 0.8.2-8 | ||||||
|  | - Add --use-ldaps option to adcli update as well [#1883467] | ||||||
|  | - Cannot join a pre-staged Computer Account on AD in Custom OU using Delegated | ||||||
|  |   user [#1734764] | ||||||
|  | - missing documentation for required AD rights for adcli join and net | ||||||
|  |   join [#1852080] | ||||||
|  | - [RFE] Add new mode to just create an AD account to be able to connect to | ||||||
|  |   LDAP [#1854112] | ||||||
|  | 
 | ||||||
|  | * Thu Aug 13 2020 Sumit Bose <sbose@redhat.com> - 0.8.2-7 | ||||||
|  | - Improve "-C" option description in man page even more [#1791545] | ||||||
|  | 
 | ||||||
|  | * Mon Jun 15 2020 Sumit Bose <sbose@redhat.com> - 0.8.2-6 | ||||||
|  | - [abrt] [faf] adcli: raise(): /usr/sbin/adcli killed by 6 [#1806260] | ||||||
|  | - No longer able to delete computer from AD using adcli [#1846882] | ||||||
|  | - adcli: presetting $computer in $domain domain failed: Cannot set computer | ||||||
|  |   password: Authentication error [#1846878] | ||||||
|  | - Typo in adcli update --help option [#1791611] | ||||||
|  | - Manpage and help does not explain the use of "-C" option [#1791545] | ||||||
|  | 
 | ||||||
|  | * Wed Jan 29 2020 Sumit Bose <sbose@redhat.com> - 0.8.2-5 | ||||||
|  | - adcli should be able to Force LDAPS over 636 with AD Access Provider w.r.t | ||||||
|  |   sssd [#1762420] | ||||||
|  | 
 | ||||||
|  | * Thu Nov 28 2019 Sumit Bose <sbose@redhat.com> - 0.8.2-4 | ||||||
|  | - adcli update --add-samba-data does not work as expected [#1745931] | ||||||
|  | - Issue is that with arcfour-hmac as first encryption type [#1745932] | ||||||
|  | - [RFE] enhancement adcli to set description attribute and to show all AD | ||||||
|  |   attributes [#1737342] | ||||||
|  | 
 | ||||||
|  | * Fri Jun 14 2019 Sumit Bose <sbose@redhat.com> - 0.8.2-3 | ||||||
|  | - use autosetup macro to simplify patch handling | ||||||
|  | - fixed rpmlint warnings in the spec file | ||||||
|  | - join failed if hostname is not FQDN [#1677194] | ||||||
|  | - adcli join fails in FIPS enabled environment [#1717355] | ||||||
|  | - forward port of RHEL-7.7 fixes and enhancements | ||||||
|  | 
 | ||||||
|  | * Tue Oct 09 2018 Sumit Bose <sbose@redhat.com> - 0.8.2-2 | ||||||
|  | - Do not add service principals twice and related fixes | ||||||
|  | - Resolves: rhbz#1631734 | ||||||
|  | 
 | ||||||
|  | * Thu Jul 05 2018 Sumit Bose <sbose@redhat.com> - 0.8.2-1 | ||||||
|  | - Update to upstream release 0.8.2 | ||||||
|  | - various other fixes and improvements from the latest Fedora update | ||||||
|  | 
 | ||||||
|  | * 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 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user