diff --git a/ACI.txt b/ACI.txt
index 5e84d05e8..a4c346f2c 100644
--- a/ACI.txt
+++ b/ACI.txt
@@ -61,7 +61,7 @@ aci: (targetattr = "cn || description || ipacertprofilestoreissued")(targetfilte
 dn: cn=certprofiles,cn=ca,dc=ipa,dc=example
 aci: (targetattr = "cn || createtimestamp || description || entryusn || ipacertprofilestoreissued || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipacertprofile)")(version 3.0;acl "permission:System: Read Certificate Profiles";allow (compare,read,search) userdn = "ldap:///all";)
 dn: cn=ipaconfig,cn=etc,dc=ipa,dc=example
-aci: (targetattr = "cn || createtimestamp || entryusn || ipacertificatesubjectbase || ipaconfigstring || ipacustomfields || ipadefaultemaildomain || ipadefaultloginshell || ipadefaultprimarygroup || ipagroupobjectclasses || ipagroupsearchfields || ipahomesrootdir || ipakrbauthzdata || ipamaxusernamelength || ipamigrationenabled || ipapwdexpadvnotify || ipasearchrecordslimit || ipasearchtimelimit || ipaselinuxusermapdefault || ipaselinuxusermaporder || ipauserauthtype || ipauserobjectclasses || ipausersearchfields || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaguiconfig)")(version 3.0;acl "permission:System: Read Global Configuration";allow (compare,read,search) userdn = "ldap:///all";)
+aci: (targetattr = "cn || createtimestamp || entryusn || ipacertificatesubjectbase || ipaconfigstring || ipacustomfields || ipadefaultemaildomain || ipadefaultloginshell || ipadefaultprimarygroup || ipadomainresolutionorder || ipagroupobjectclasses || ipagroupsearchfields || ipahomesrootdir || ipakrbauthzdata || ipamaxusernamelength || ipamigrationenabled || ipapwdexpadvnotify || ipasearchrecordslimit || ipasearchtimelimit || ipaselinuxusermapdefault || ipaselinuxusermaporder || ipauserauthtype || ipauserobjectclasses || ipausersearchfields || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaguiconfig)")(version 3.0;acl "permission:System: Read Global Configuration";allow (compare,read,search) userdn = "ldap:///all";)
 dn: cn=costemplates,cn=accounts,dc=ipa,dc=example
 aci: (targetfilter = "(objectclass=costemplate)")(version 3.0;acl "permission:System: Add Group Password Policy costemplate";allow (add) groupdn = "ldap:///cn=System: Add Group Password Policy costemplate,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=costemplates,cn=accounts,dc=ipa,dc=example
diff --git a/API.txt b/API.txt
index 2d6b401be..f876afc76 100644
--- a/API.txt
+++ b/API.txt
@@ -1061,7 +1061,7 @@ args: 0,1,1
 option: Str('version?')
 output: Output('result')
 command: config_mod/1
-args: 0,26,3
+args: 0,27,3
 option: Str('addattr*', cli_name='addattr')
 option: Flag('all', autofill=True, cli_name='all', default=False)
 option: Str('ca_renewal_master_server?', autofill=False)
@@ -1070,6 +1070,7 @@ option: StrEnum('ipaconfigstring*', autofill=False, cli_name='ipaconfigstring',
 option: Str('ipadefaultemaildomain?', autofill=False, cli_name='emaildomain')
 option: Str('ipadefaultloginshell?', autofill=False, cli_name='defaultshell')
 option: Str('ipadefaultprimarygroup?', autofill=False, cli_name='defaultgroup')
+option: Str('ipadomainresolutionorder?', autofill=False, cli_name='domain_resolution_order')
 option: Str('ipagroupobjectclasses*', autofill=False, cli_name='groupobjectclasses')
 option: IA5Str('ipagroupsearchfields?', autofill=False, cli_name='groupsearch')
 option: IA5Str('ipahomesrootdir?', autofill=False, cli_name='homedirectory')
diff --git a/VERSION.m4 b/VERSION.m4
index 246d6bb59..9766c749b 100644
--- a/VERSION.m4
+++ b/VERSION.m4
@@ -73,8 +73,8 @@ define(IPA_DATA_VERSION, 20100614120000)
 #                                                      #
 ########################################################
 define(IPA_API_VERSION_MAJOR, 2)
-define(IPA_API_VERSION_MINOR, 221)
-# Last change: cert: include certificate chain in cert command output
+define(IPA_API_VERSION_MINOR, 222)
+>>>>>>> ipaconfig: add the ability to manipulate domain resolution order
 
 
 ########################################################
diff --git a/ipaserver/plugins/config.py b/ipaserver/plugins/config.py
index 5d574657e..232c88121 100644
--- a/ipaserver/plugins/config.py
+++ b/ipaserver/plugins/config.py
@@ -22,6 +22,7 @@ from ipalib import api
 from ipalib import Bool, Int, Str, IA5Str, StrEnum, DNParam
 from ipalib import errors
 from ipalib.plugable import Registry
+from ipalib.util import validate_domain_name
 from .baseldap import (
     LDAPObject,
     LDAPUpdate,
@@ -34,6 +35,8 @@ from ipapython.dn import DN
 OPERATIONAL_ATTRIBUTES = ('nsaccountlock', 'member', 'memberof',
     'memberindirect', 'memberofindirect',)
 
+DOMAIN_RESOLUTION_ORDER_SEPARATOR = u':'
+
 __doc__ = _("""
 Server configuration
 
@@ -95,7 +98,7 @@ class config(LDAPObject):
         'ipamigrationenabled', 'ipacertificatesubjectbase',
         'ipapwdexpadvnotify', 'ipaselinuxusermaporder',
         'ipaselinuxusermapdefault', 'ipaconfigstring', 'ipakrbauthzdata',
-        'ipauserauthtype'
+        'ipauserauthtype', 'ipadomainresolutionorder'
     ]
     container_dn = DN(('cn', 'ipaconfig'), ('cn', 'etc'))
     permission_filter_objectclasses = ['ipaguiconfig']
@@ -108,7 +111,8 @@ class config(LDAPObject):
                 'cn', 'objectclass',
                 'ipacertificatesubjectbase', 'ipaconfigstring',
                 'ipadefaultemaildomain', 'ipadefaultloginshell',
-                'ipadefaultprimarygroup', 'ipagroupobjectclasses',
+                'ipadefaultprimarygroup', 'ipadomainresolutionorder',
+                'ipagroupobjectclasses',
                 'ipagroupsearchfields', 'ipahomesrootdir',
                 'ipakrbauthzdata', 'ipamaxusernamelength',
                 'ipamigrationenabled', 'ipapwdexpadvnotify',
@@ -250,6 +254,13 @@ class config(LDAPObject):
             label=_('IPA CA renewal master'),
             doc=_('Renewal master for IPA certificate authority'),
             flags={'virtual_attribute', 'no_create'}
+        ),
+        Str(
+            'ipadomainresolutionorder?',
+            cli_name='domain_resolution_order',
+            label=_('Domain resolution order'),
+            doc=_('colon-separated list of domains used for short name'
+                  ' qualification')
         )
     )
 
@@ -266,6 +277,104 @@ class config(LDAPObject):
             config = backend.config_retrieve(role)
             entry_attrs.update(config)
 
+    def gather_trusted_domains(self):
+        """
+        Aggregate all trusted domains into a dict keyed by domain names with
+        values corresponding to domain status (enabled/disabled)
+        """
+        command = self.api.Command
+        try:
+            ad_forests = command.trust_find(sizelimit=0)['result']
+        except errors.NotFound:
+            return {}
+
+        trusted_domains = {}
+        for forest_name in [a['cn'][0] for a in ad_forests]:
+            forest_domains = command.trustdomain_find(
+                forest_name, sizelimit=0)['result']
+
+            trusted_domains.update(
+                {
+                    dom['cn'][0]: dom['domain_enabled'][0]
+                    for dom in forest_domains if 'domain_enabled' in dom
+                }
+            )
+
+        return trusted_domains
+
+    def _validate_single_domain(self, attr_name, domain, known_domains):
+        """
+        Validate a single domain from domain resolution order
+
+        :param attr_name: name of attribute that holds domain resolution order
+        :param domain: domain name
+        :param known_domains: dict of domains known to IPA keyed by domain name
+            and valued by boolean value corresponding to domain status
+            (enabled/disabled)
+
+        :raises: ValidationError if the domain name is empty, syntactically
+            invalid or corresponds to a disable domain
+                 NotFound if a syntactically correct domain name unknown to IPA
+                 is supplied (not IPA domain and not any of trusted domains)
+        """
+        if not domain:
+            raise errors.ValidationError(
+                name=attr_name,
+                error=_("Empty domain is not allowed")
+            )
+
+        try:
+            validate_domain_name(domain)
+        except ValueError as e:
+            raise errors.ValidationError(
+                name=attr_name,
+                error=_("Invalid domain name '%(domain)s': %(e)s")
+                % dict(domain=domain, e=e))
+
+        if domain not in known_domains:
+            raise errors.NotFound(
+                reason=_("Server has no information about domain '%(domain)s'")
+                % dict(domain=domain)
+            )
+
+        if not known_domains[domain]:
+            raise errors.ValidationError(
+                name=attr_name,
+                error=_("Disabled domain '%(domain)s' is not allowed")
+                % dict(domain=domain)
+            )
+
+    def validate_domain_resolution_order(self, entry_attrs):
+        """
+        Validate domain resolution order, e.g. split by the delimiter (colon)
+        and check each domain name for non-emptiness, syntactic correctness,
+        and status (enabled/disabled).
+
+        supplying empty order (':') bypasses validations and allows to specify
+        empty attribute value.
+        """
+        attr_name = 'ipadomainresolutionorder'
+        if attr_name not in entry_attrs:
+            return
+
+        domain_resolution_order = entry_attrs[attr_name]
+
+        # empty resolution order is signalized by single separator, do nothing
+        # and let it pass
+        if domain_resolution_order == DOMAIN_RESOLUTION_ORDER_SEPARATOR:
+            return
+
+        submitted_domains = domain_resolution_order.split(
+                DOMAIN_RESOLUTION_ORDER_SEPARATOR)
+
+        known_domains = self.gather_trusted_domains()
+
+        # add FreeIPA domain to the list of domains. This one is always enabled
+        known_domains.update({self.api.env.domain: True})
+
+        for domain in submitted_domains:
+            self._validate_single_domain(attr_name, domain, known_domains)
+
 
 @register()
 class config_mod(LDAPUpdate):
@@ -396,6 +505,8 @@ class config_mod(LDAPUpdate):
             backend = self.api.Backend.serverroles
             backend.config_update(ca_renewal_master_server=new_master)
 
+        self.obj.validate_domain_resolution_order(entry_attrs)
+
         return dn
 
     def exc_callback(self, keys, options, exc, call_func,