#9583 batch is failing on missing attribute principal in error case using server context
Closed: fixed 8 months ago by rcritten. Opened 9 months ago by twoerner.

Issue

context.principal is used for the info log in the error case of the execution of the commands. But this attribute does not seem to be set in all cases (using server context), which results in a trace in the error handling. Therefore the execution is aborted and real failure is not returned.

Steps to Reproduce

  1. Create batch command with several commands, with an command that will result in an error, for example "no modification to be done"

Actual behavior

Trace back and aborted execution

Expected behavior

No failure and full processing of all commands.

Version/Release/Distribution

$ rpm -q freeipa-server freeipa-client ipa-server ipa-client 389-ds-base pki-ca krb5-server
ipa-server-4.11.0-5.el9.x86_64
ipa-client-4.11.0-5.el9.x86_64
389-ds-base-2.4.5-3.el9.x86_64
krb5-server-1.21.1-1.el9.x86_64


Please provide logs and a reproducer json content. context.principal should be set for all HTTPS-endpoint initiated calls.

Current Output
Init

Add host batch-test-host-01.cos9.local

Run batch:
[{'method': 'host_mod',
'params': (['batch-test-host-01.cos9.local'], {'updatedns': True})},
{'method': 'host_mod',
'params': (['batch-test-host-01.cos9.local'], {'location': 'bar'})}]

AttributeError("'_thread._local' object has no attribute 'principal'")
name 'ret' is not defined

location: None

Expected Output
Init

Add host batch-test-host-01.cos9.local

Run batch:
[{'method': 'host_mod',
'params': (['batch-test-host-01.cos9.local'], {'updatedns': True})},
{'method': 'host_mod',
'params': (['batch-test-host-01.cos9.local'], {'location': 'bar'})}]

ipa: INFO: UNKNOWN: batch: host_mod('batch-test-host-01.cos9.local', updatedns=True): EmptyModlist
ipa: INFO: UNKNOWN: batch: ConversionError
("{'count': 2, 'results': [{'error': 'no modifications to be performed', "
"'error_code': 4202, 'error_name': 'EmptyModlist', 'error_kw': {}}, {'error': "
'"invalid \'params\': Unknown option: location", \'error_code\': 3008, '
"'error_name': 'ConversionError', 'error_kw': {'name': 'params', 'error': "
"'Unknown option: location'}}], 'messages': [{'type': 'warning', 'name': "
'\'VersionMissing\', \'message\': "API Version number was not sent, forward '
'compatibility not guaranteed. Assuming server\'s API version, 2.253", '
"'code': 13001, 'data': {'server_version': '2.253'}}]}")

location: None

This reproducer uses server context which is not expected to provide context.principal because it uses LDAPI with UID binding and is not GSSAPI authentication. We still need to fix places where context.principal is referenced to avoid those issues.

Worse batch

batch_args = [
    {
        "method": "host_mod",
        "params": ([host_fqdn],
                   {
                       "nshostlocation": "foo",
                   })
    },
    {
        "method": "host_mod",
        "params": ([host_fqdn],
                   {
                       "updatedns": True,
                   })
    },
    {
        "method": "host_mod",
        "params": ([host_fqdn],
                   {
                       "nshostlocation": "bar",
                   })
    },
]

Current result
Init

Add host batch-test-host-01.cos9.local

Run batch:
[{'method': 'host_mod',
'params': (['batch-test-host-01.cos9.local'], {'nshostlocation': 'foo'})},
{'method': 'host_mod',
'params': (['batch-test-host-01.cos9.local'], {'updatedns': True})},
{'method': 'host_mod',
'params': (['batch-test-host-01.cos9.local'], {'nshostlocation': 'bar'})}]

ipa: INFO: UNKNOWN: batch: host_mod('batch-test-host-01.cos9.local', nshostlocation='foo'): SUCCESS
AttributeError("'_thread._local' object has no attribute 'principal'")
name 'ret' is not defined

location: ['foo']

Expected result
Init

Add host batch-test-host-01.cos9.local

Run batch:
[{'method': 'host_mod',
'params': (['batch-test-host-01.cos9.local'], {'nshostlocation': 'foo'})},
{'method': 'host_mod',
'params': (['batch-test-host-01.cos9.local'], {'updatedns': True})},
{'method': 'host_mod',
'params': (['batch-test-host-01.cos9.local'], {'nshostlocation': 'bar'})}]

ipa: INFO: UNKNOWN: batch: host_mod('batch-test-host-01.cos9.local', nshostlocation='foo'): SUCCESS
ipa: INFO: UNKNOWN: batch: host_mod('batch-test-host-01.cos9.local', updatedns=True): EmptyModlist
ipa: INFO: UNKNOWN: batch: host_mod('batch-test-host-01.cos9.local', nshostlocation='bar'): SUCCESS
("{'count': 3, 'results': [{'result': {'krbprincipalname': "
"[ipapython.kerberos.Principal('host/batch-test-host-01.cos9.local@COS9.LOCAL')], "
"'fqdn': ['batch-test-host-01.cos9.local'], 'nshostlocation': ['foo'], "
"'krbcanonicalname': "
"[ipapython.kerberos.Principal('host/batch-test-host-01.cos9.local@COS9.LOCAL')], "
"'has_password': False, 'has_keytab': False, 'managedby_host': "
"['batch-test-host-01.cos9.local']}, 'value': "
"'batch-test-host-01.cos9.local', 'summary': 'Modified host "
'"batch-test-host-01.cos9.local"\', \'error\': None}, {\'error\': \'no '
"modifications to be performed', 'error_code': 4202, 'error_name': "
"'EmptyModlist', 'error_kw': {}}, {'result': {'krbprincipalname': "
"[ipapython.kerberos.Principal('host/batch-test-host-01.cos9.local@COS9.LOCAL')], "
"'fqdn': ['batch-test-host-01.cos9.local'], 'nshostlocation': ['bar'], "
"'krbcanonicalname': "
"[ipapython.kerberos.Principal('host/batch-test-host-01.cos9.local@COS9.LOCAL')], "
"'has_password': False, 'has_keytab': False, 'managedby_host': "
"['batch-test-host-01.cos9.local']}, 'value': "
"'batch-test-host-01.cos9.local', 'summary': 'Modified host "
'"batch-test-host-01.cos9.local"\', \'error\': None}], \'messages\': '
'[{\'type\': \'warning\', \'name\': \'VersionMissing\', \'message\': "API '
'Version number was not sent, forward compatibility not guaranteed. Assuming '
'server\'s API version, 2.253", \'code\': 13001, \'data\': '
"{'server_version': '2.253'}}]}")

location: ['bar']

@abbra About batch, why aren't you changing line 177, like I did in PR https://github.com/freeipa/freeipa/pull/7332/ ?

Using just 'UNKNOWN' is incorrect. We have security checks there in place, they need to be done regardless whether context principal is set or not. And that means validating things before we dereference context.principal.

There is getattr(context, 'principal', 'UNKNOWN') in line 177, shouldn't this be replaced with op_account also?

There are more places where getattr(context, 'principal') is used in plugins.

Understood.

Why these comments are here and not in the pull request review, btw?

master:

  • 295ac63 privilege: use context.principal only when it is defined
  • 3608b2b batch: account for auto-binding in server context
  • 71d886f config: use context.principal only when it is defined
  • ab54656 server: use context.principal only when it is defined
  • 08f1e6f trust: use context.principal only when it is defined
  • b6131b5 trust: handle stray pylint warning
  • e386e22 cert: use context.principal only when it is defined
  • 902c8b0 passwd: handle LDAP auto-bind use case as well
  • c325f9c user: handle LDAP auto-bind for whoami case
  • 6cc0a0b pylint: use yield_from for trivial cases
  • 9e86169 batch: add keeponly option

ipa-4-11:

  • 3d03ab4 privilege: use context.principal only when it is defined
  • 83a68fb batch: account for auto-binding in server context
  • 68c072d config: use context.principal only when it is defined
  • 75c50a0 server: use context.principal only when it is defined
  • b9ccc67 trust: use context.principal only when it is defined
  • 092b581 trust: handle stray pylint warning
  • e582634 cert: use context.principal only when it is defined
  • e1177a6 passwd: handle LDAP auto-bind use case as well
  • 3b07e25 user: handle LDAP auto-bind for whoami case
  • 5117a53 pylint: use yield_from for trivial cases
  • 88abda5 batch: add keeponly option

Metadata Update from @rcritten:
- Issue close_status updated to: fixed
- Issue status updated to: Closed (was: Open)

8 months ago

Log in to comment on this ticket.

Metadata
Attachments 1
Attached 9 months ago View Comment