GithubHelp home page GithubHelp logo

ambitus / pyracf Goto Github PK

View Code? Open in Web Editor NEW
8.0 8.0 4.0 2.31 MB

Python interface to the RACF Command interface.

Home Page: https://ambitus.github.io/pyracf/

License: Apache License 2.0

Python 99.14% C 0.86%
mainframe-automation mainframe-simplification pyracf python racf security-automation

pyracf's Issues

Feature Request: pyRACF should Leverage IRRSMO00's ability to compensate for small buffers

Is your feature request related to a problem? Please describe.
pyRACF is about to start using a dynamic buffer size to interact with IRRSMO00 which means it is possible for a user or application to specify a buffer too small for command output. This will result in a DownstreamFatalError surfacing IRRSMO00 return codes of 8/4000/Len, but the partial data would be discarded and this would require the application or user to re-drive the activity with a larger buffer which is undesirable.

Describe the solution you'd like
Note: It is possible for IRRSMO00 to process a part of the input document, and then find there is not enough space in the result buffer to return the results. In this situation, the results for that portion of the input are lost, and that part of the request is repeated on the next call to IRRSMO00. This may result in unexpected output, such as a 'not found' error if the work in question was a delete operation. This can only happen If the result is too small.

https://www.ibm.com/docs/en/zos/3.1.0?topic=rsismo-usage-notes

Describe alternatives you've considered
We could try to implement this at the C level, but it would complicate the simple nature of its existing structure, and it would also require a lot of dynamic memory management as there would need to be a lot of "simultaneous" storage held to build the buffer into a large response before returning to the python layer.

We could try to implement this at the python layer, but I am uncertain all the necessary memory objects will exist and still be accessible when a call comes in to re-drive the c code from python with the added handle pointer.

Additional context
N/A

Feature Request: pyRACF should do Input validation

Is your feature request related to a problem? Please describe.
It is very possible to pass improper or non-functional arguments to pyRACF unwittingly.

Describe the solution you'd like
pyRACF should directly enforce valid types and values for defined traits based on documented RACF behavior.

Describe alternatives you've considered
The current implementation allows RACF to fail improperly defined parameters, resulting in SecurityRequestError's returned to the caller.

Additional context
N/A

Bug Report: SegmentError and SegmentTraitError keep built dictionaries

Describe the bug
SegmentError and SegmentTraitError exit the code without clearing segment trait dictionaries. This leads to improper request dictionaries built on the next request.

To Reproduce
Make a request that will encounter SegmentTraitError or SegmentError. Make another request incompatible with those traits.

Expected behavior
These requests should be independent of one another if at all possible

Console Output
N/A

Environment Information:

  • IBM Python 3.11 on z/OS 2.4

Additional context
N/A

Feature Request: Better Error Handling for Empty Return from IRRSMO00

Is your feature request related to a problem? Please describe.
Users are starting to use pyracf without ensuring all setup steps are complete like the IRR.IRRSMO00.PRECHECK profile that we document. Without this profile, alter profile requests result in empty return values from IRRSMO00, which pyracf does not handle gracefully as shown:

  File "/usr/lpp/IBM/cyp/v3r10/pyz/lib/python3.10/site-packages/pyracf/user/user_admin.py", line 295, in set_passphrase
    result = self.alter(userid, traits={"base:passphrase": passphrase})
  File "/usr/lpp/IBM/cyp/v3r10/pyz/lib/python3.10/site-packages/pyracf/user/user_admin.py", line 801, in alter
    return self._make_request(user_request, irrsmo00_precheck=True)
  File "/usr/lpp/IBM/cyp/v3r10/pyz/lib/python3.10/site-packages/pyracf/common/security_admin.py", line 178, in _make_request
    results = SecurityResult(result_xml)
  File "/usr/lpp/IBM/cyp/v3r10/pyz/lib/python3.10/site-packages/pyracf/common/security_result.py", line 13, in __init__
    self.__result = XMLParser.fromstring(result_xml)
  File "/usr/lpp/IBM/cyp/v3r10/pyz/lib/python3.10/site-packages/defusedxml/common.py", line 127, in fromstring
    return parser.close()
  File "/usr/lpp/IBM/cyp/v3r10/pyz/lib/python3.10/xml/etree/ElementTree.py", line 1724, in close
    self._raiseerror(v)
  File "/usr/lpp/IBM/cyp/v3r10/pyz/lib/python3.10/xml/etree/ElementTree.py", line 1624, in _raiseerror
    raise err
xml.etree.ElementTree.ParseError: no element found: line 1, column 0

Describe the solution you'd like
This should result in a new error that should also steer users to this documentation to correct this mistake on their own.

Describe alternatives you've considered
Writing errors this severe to a log file of some sort could also be beneficial.

Additional context
N/A

Feature Request: Robust Error Handling

Is your feature request related to a problem? Please describe.
-pyRACF ignores unknown fields and traits passed into it, this can cause problems if output it not closely monitored for validation
-pyRACF also allows "bad" or "invalid" data types to be passed to RACF, which will throw a security request error on failure
-pyRACF's ADD and ALTER requests are not mutually exclusive. ADD can inadvertently ALTER existing users, and ALTER can create new ones

Describe the solution you'd like
-pyRACF should validate these fields and traits, and throw errors for unknowns
-pyRACF should throw its own errors for obviously invalid data before it is passed to RACF
-pyRACF's ADD and ALTER functions should check to ensure ADD will not ALTER an existing user and ALTER will not ADD a new one

Additional context
IRRSMO00 has a flag for TERMINATE ON FIRST ERROR which will likely stop ADD from altering an existing user as long as ADD does not use the PRECHECK flag.

Feature Request: Improved Secrets redaction

IRRSMO00 has an optional feature already to redact secret fields, and customers may also have fields beyond passwords and password phrases that require redaction. Both of these are features we should implement for additional security with pyRACF

Bug Report: Extra Messages Not Removed From Profile Extract Data

Describe the bug
If extra messages get added to profile extract data in result xml returned by IRRSMO00, it should not be included in the Python dictionary that the XML gets transformed into.

To Reproduce
Steps to reproduce the behavior:

  • Logon to a z/OS user id that is only authorized to extract their own base segment but no other segments.
  • Ensure an affected version of pyRACF is installed.
  • Extract the user's own profile and include additional segments.
from pyracf import UserAdmin
user_admin = UserAdmin()
# An even number of additional segments results in extraneous
# malformed data being added to the extracted profile data
user_admin.extract("squidwrd", segments=["omvs", "tso"]
# An odd number of additional segments results in a stack trace.
user_admin.extract("squidwrd", segments=["omvs"]

Expected behavior
All profile extract functions or more specifically anything that executes the listdata operation, should exclude any extra messages attached to the end of the result xml.

Console Output

Two Additional Segments:

user_admin.extract("squidwrd", segments=["omvs", "tso"]

Result XML

<?xml version="1.0" encoding="IBM-1047"?>
<securityresult xmlns="http://www.ibm.com/systems/zos/saf/IRRSMO00Result1">
  <user name="SQUIDWRD" operation="listdata" requestid="UserRequest">
    <command>
      <safreturncode>0</safreturncode>
      <returncode>0</returncode>
      <reasoncode>0</reasoncode>
      <image>LISTUSER SQUIDWRD  OMVS     TSO      OVM     </image>
      <message>USER=SQUIDWRD  NAME=SQUIDWARD             OWNER=LEONARD   CREATED=23.094</message>
      <message> DEFAULT-GROUP=SYS1     PASSDATE=00.000 PASS-INTERVAL=186 PHRASEDATE=N/A</message>
      <message> ATTRIBUTES=NONE</message>
      <message> REVOKE DATE=NONE   RESUME DATE=NONE</message>
      <message> LAST-ACCESS=23.094/12:55:37</message>
      <message> CLASS AUTHORIZATIONS=NONE</message>
      <message> NO-INSTALLATION-DATA</message>
      <message> NO-MODEL-NAME</message>
      <message> LOGON ALLOWED   (DAYS)          (TIME)</message>
      <message> ---------------------------------------------</message>
      <message> ANYDAY                          ANYTIME</message>
      <message>  GROUP=SYS1      AUTH=USE      CONNECT-OWNER=LEONARD   CONNECT-DATE=23.094</message>
      <message>    CONNECTS=    00  UACC=NONE     LAST-CONNECT=UNKNOWN</message>
      <message>    CONNECT ATTRIBUTES=NONE</message>
      <message>    REVOKE DATE=NONE   RESUME DATE=NONE</message>
      <message>SECURITY-LEVEL=NONE SPECIFIED</message>
      <message>CATEGORY-AUTHORIZATION</message>
      <message> NONE SPECIFIED</message>
      <message>SECURITY-LABEL=NONE SPECIFIED</message>
      <message>IRR52021I You are not authorized to view OMVS segments.</message>
      <message>IRR52021I You are not authorized to view TSO segments.</message>
    </command>
  </user>
  <returncode>0</returncode>
  <reasoncode>0</reasoncode>
</securityresult>

Result Dictionary

{
  "securityResult": {
    "user": {
      "name": "SQUIDWRD",
      "operation": "listdata",
      "requestId": "UserRequest",
      "commands": [
        {
          "safReturnCode": 0,
          "returnCode": 0,
          "reasonCode": 0,
          "image": "LISTUSER SQUIDWRD  OMVS     TSO      OVM     ",
          "profiles": [
            {
              "base": {
                "user": "squidwrd",
                "name": "squidward",
                "owner": "leonard",
                "created": "4/4/2023",
                "defaultGroup": "sys1",
                "passwordDate": null,
                "passwordInterval": 186,
                "passphraseDate": null,
                "attributes": [],
                "revokeDate": null,
                "resumeDate": null,
                "lastAccess": "4/4/2023 12:55 PM",
                "classAuthorizations": [],
                "logonAllowedDays": "anyday",
                "logonAllowedTime": "anytime",
                "groups": {
                  "SYS1": {
                    "auth": "use",
                    "connectOwner": "leonard",
                    "connectDate": "4/4/2023",
                    "connects": 0,
                    "uacc": null,
                    "lastConnect": null,
                    "connectAttributes": [],
                    "revokeDate": null,
                    "resumeDate": null
                  }
                },
                "securityLevel": null,
                "categoryAuthorization": null,
                "securityLabel": null,
                "irr52021iYouAreNotAuthorizedToViewOmvsSegments.": "irr52021i you are not authorized to view tso segments."
              }
            }
          ]
        }
      ]
    },
    "returnCode": 0,
    "reasonCode": 0
  }
}

One Additional Segment

user_admin.extract("squidwrd", segments=["omvs"]

Result XML

<?xml version="1.0" encoding="IBM-1047"?>
<securityresult xmlns="http://www.ibm.com/systems/zos/saf/IRRSMO00Result1">
  <user name="SQUIDWRD" operation="listdata" requestid="UserRequest">
    <command>
      <safreturncode>0</safreturncode>
      <returncode>0</returncode>
      <reasoncode>0</reasoncode>
      <image>LISTUSER SQUIDWRD  OMVS     TSO     </image>
      <message>USER=SQUIDWRD  NAME=SQUIDWARD             OWNER=LEONARD   CREATED=23.094</message>
      <message> DEFAULT-GROUP=SYS1     PASSDATE=00.000 PASS-INTERVAL=186 PHRASEDATE=N/A</message>
      <message> ATTRIBUTES=NONE</message>
      <message> REVOKE DATE=NONE   RESUME DATE=NONE</message>
      <message> LAST-ACCESS=23.094/12:55:37</message>
      <message> CLASS AUTHORIZATIONS=NONE</message>
      <message> NO-INSTALLATION-DATA</message>
      <message> NO-MODEL-NAME</message>
      <message> LOGON ALLOWED   (DAYS)          (TIME)</message>
      <message> ---------------------------------------------</message>
      <message> ANYDAY                          ANYTIME</message>
      <message>  GROUP=SYS1      AUTH=USE      CONNECT-OWNER=LEONARD   CONNECT-DATE=23.094</message>
      <message>    CONNECTS=    00  UACC=NONE     LAST-CONNECT=UNKNOWN</message>
      <message>    CONNECT ATTRIBUTES=NONE</message>
      <message>    REVOKE DATE=NONE   RESUME DATE=NONE</message>
      <message>SECURITY-LEVEL=NONE SPECIFIED</message>
      <message>CATEGORY-AUTHORIZATION</message>
      <message> NONE SPECIFIED</message>
      <message>SECURITY-LABEL=NONE SPECIFIED</message>
      <message>IRR52021I You are not authorized to view OMVS segments.</message>
      <message>IRR52021I You are not authorized to view TSO segments.</message>
    </command>
  </user>
  <returncode>0</returncode>
  <reasoncode>0</reasoncode>
</securityresult>

Stack Trace

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/u/squidwrd/.local/lib/python3.11/site-packages/pyracf/user/user_admin.py", line 810, in extract
    result = self._extract_and_check_result(user_request)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/u/squidwrd/.local/lib/python3.11/site-packages/pyracf/common/security_admin.py", line 130, in _extract_and_check_result
    self._format_profile(result)
  File "/u/squidwrd/.local/lib/python3.11/site-packages/pyracf/user/user_admin.py", line 838, in _format_profile
    profile = self._format_profile_generic(
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/u/squidwrd/.local/lib/python3.11/site-packages/pyracf/common/security_admin.py", line 379, in _format_profile_generic
    i = self.__format_user_profile_data(
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/u/squidwrd/.local/lib/python3.11/site-packages/pyracf/common/security_admin.py", line 478, in __format_user_profile_data
    messages[i] = f"{messages[i]}={messages[i+1]}"
                                   ~~~~~~~~^^^^^
IndexError: list index out of range

Environment Information:

  • z/OS Version: 2.4
  • Python Version: 3.11
  • is R_SecMgtOper (IRRSMO00) setup? Yes

Additional context
Add any other context about the problem here.

Feature Request: Another round of RAS Items

Is your feature request related to a problem? Please describe.

  • pyRACF should be capable of interrogating security response objects for specific messages, and some profile alterations should also be able to surface information from these messages. An example would be the resource_admin.alter or add methods should be able to alert a user if the change requires a REFRESH to take effect.
  • Installation Data (and other "block of text" fields like it) may cause problems in user_admin.extract when parsed. We do not have a lot of sample data for this, but stabilizing this behavior is vital to a full release
  • There are other SETROPTS REFRESH commands that are not RACLIST that have their uses, adding them in would be helpful
  • DataSet Admin is missing get_user_access and audit_rules functions given to ResourceAdmin
  • Profiles on extract should map to a "template" that could be used for definitions. This requires a mapping of extract traits to traits usable on input.

Describe the solution you'd like
See above

Describe alternatives you've considered
See above

Additional context
No

Enhancement: Use poetry build backend instead of setuptools

Is your feature request related to a problem? Please describe.
Setuptools does not give us the ability to publish packages to a pypi repository. Twine could be used to fill the gap, but it no longer works on z/OS because one of it's dependencies has a dependency on Rust, which is unsupported on z/OS.

Describe the solution you'd like
Switch to the poetry build backend.

  • Use poetry install --no-root to install runtime/development dependencies.
  • Use poetry build to build wheel and source tar.
  • Use poetry publish to upload wheels to a pypi repository.
  • IRRSMO00 Python extension can be built using poetry.
  • After installing development dependencies with poetry, they can all be invoked using poetry run <tool> <tool-args>
  • Poetry provides a built-in virtual environment that enables environments for multiple Python versions to be built and used.

Describe alternatives you've considered
Twine did work for us until one of it's dependencies was updated to use Rust, which is not supported on z/OS.

Additional context
The Poetry build backend should resolve all of our current build problems with the exception of pandas not working on z/OS, which will need to be addressed separately in order to integrate the reporting functionality from https://github.com/wizardofzos/pyracf

Note that pip doesn't have any support for configuring the repository source for packages and that the standard is for the user to specify the repository to use. This is almost certainly enforced for good reason, since it is probably bad security practice to allow the package metadata to specify the repository source, but it leaves pyRACF with a dependency resolution problem. Some packages will be able to be installed directly from pypi and some will need to be installed from somewhere else (i.e., Python AI Toolkit for z/OS), which makes the installation procedure for pyRACF unnecessarily difficult. Regardless, a separate discussion will need to be had to discuss how to approach this particular problem.

Bug Report: SecurityRequestError Doc references out of date

Describe the bug
Documentation error in 1.0b3. Numerous functions document SecurityRequestError as

Raises SecurityRequestErrorwhen the **Return Code** of a **Security Result** returned by IRRSMO00 is **NOT** equal to0``

This needs to be updated and all functions capable of raising SecurityRequestError in this way can also raise DownstreamFatalError as well.

To Reproduce
N/A

Expected behavior
Change documentation to

Raises SecurityRequestErrorwhen the **Return Code** of a **Security Result** returned by IRRSMO00 is equal to4``

also include comparable documentation for DownstreamFatalError

Console Output
N/A

Feature Request: Improve Additional Secrets Redaction

Is your feature request related to a problem? Please describe.
Additional Secrets Redaction is currently marked experimental because messages returned by IRRSMO00 from RACF can contain the redacted content. Additionally the regex implementation of the redaction is not exhaustive and seems that it could be error prone if the weaknesses of it were deliberately exploited.

Describe the solution you'd like
Error messages containing redacted content should also be redacted.
Redaction should be employed in a way to minimize false positives and guarantee redaction of the target pattern.

Describe alternatives you've considered
No alternatives as there is no defined implementation for this

Additional context
N/A

Feature Request: SecurityRequestError Structure Standardization

Is your feature request related to a problem? Please describe.
When you run into "error" xml returned from IRRSMO00, there are effectively two kinds of structures:

Structure 1 is the case we based SecurityResultError on, RACF returns with a non-zero RC and the following XML:

<?xml version="1.0" encoding="IBM-1047"?>
<securityresult xmlns="http://www.ibm.com/systems/zos/saf/IRRSMO00Result1">
  <user name="TESTBOY" operation="set" requestid="UserRequest">
    <info>Definition exists. Add command skipped due  to precheck option</info>
    <command>
      <safreturncode>8</safreturncode>
      <returncode>16</returncode>
      <reasoncode>8</reasoncode>
      <image>ALTUSER TESTBOY  OMVS     (UID         (STRING))</image>
      <message>IKJ56701I MISSING OMVS UID+</message>
      <message>IKJ56701I MISSING OMVS USER ID (UID), 1-10 NUMERIC DIGITS</message>
      <message>IKJ56716I EXTRANEOUS INFORMATION WAS IGNORED: STRING</message>
    </command>
  </user>
  <returncode>4</returncode>
  <reasoncode>0</reasoncode>
</securityresult>

Structure 2 is the case where IRRSMO00 itself is returning an error to the user as XML:

<?xml version="1.0" encoding="IBM-1047"?>
<securityresult xmlns="http://www.ibm.com/systems/zos/saf/IRRSMO00Result1">
  <user name="TESTBOY" operation="set" requestid="UserRequest">
    <error>
      <errorfunction>10</errorfunction>
      <errorcode>2000</errorcode>
      <errorreason>76</errorreason>
      <errormessage>Data may not be specified for a boolean field.</errormessage>
      <erroroffset>216</erroroffset>
      <textinerror>STRING</textinerror>
    </error>
  </user>
  <returncode>2000</returncode>
  <reasoncode>76</reasoncode>
</securityresult>

Because the internal XML structure is so different, the SecurityRequestError is very different. Our documented sample of:

from pyracf import UserAdmin
from pyracf import SecurityRequestError

user_admin = UserAdmin()

try:
    user_admin.alter("squidwrd", traits={"base:password": "passwordtoolong"})
except SecurityRequestError as e:
    return_code = e.result["securityResult"]["user"]["returnCode"]
    reason_code = e.result["securityResult"]["user"]["reasonCode"]
    messages = "\n".join(e.result["securityResult"]["user"]["commands"][0]["messages"])
    print(f"Return Code: {return_code}")
    print(f"Reason Code: {reason_code}")
    print(f"Messages:\n\n{messages}")

would not work because there is no commands dictionary and no 'messages', just all sorts of error tags.

Describe the solution you'd like
We should make one structure conform to the other at least when added under the SecurityRequestError object so that errors thrown either by SMO or RACF can be handled by users without having to change their exception handling logic.

Describe alternatives you've considered
We could also split these into two entirely separate error objects to be handled differently, but that could still leave users with complications.

Additional context
The SMO errors also have some nice fields like erroroffset and textinerror. It would be nice to incorporate these into the SecurityRequestError in some way so that end users could quickly access that information to correct user error.

Feature Request: Install Script/Documentation Improvements

Is your feature request related to a problem? Please describe.
Users are having issues with the setup and definition of the IRR.IRRSMO00.PRECHECK resource in the XFACILIT class.

Describe the solution you'd like
We should potentially have a script that could define this resource so that auditing would flag attempts to use it when it fails.

Describe alternatives you've considered
Another alternative would be to DIRECTLY REFERENCE this general resource in the install steps in the documentation.

Additional context
N/A

Feature Request: RAS Enhancements

Is your feature request related to a problem? Please describe.

  • If a response returned by IRRSMO00 is either unable to be decoded using the cp1047 codec (encoding problems will be captured by XML parsing failures) or the returned XML is unable to be parsed, the user may not have enough information for problem determination.
  • There is no way to audit audit RACF commands that get run through IRRSMO00. (Revisit)

Describe the solution you'd like

  • If a response returned by IRRSMO00 is either unable to be decoded using the cp1047 codec (encoding problems will be captured by XML parsing failures) or the returned XML is unable to be parsed, a raw dump of the response should be created.
  • The ~/.pyracf/dumps folder is where raw dumps should be stored.
  • ~/.pyracf/audit.log is where executed RACF commands will be written to. (Revisit)
  • ~/.pyracf/pyracf.conf will be used to enable or disable audit logging. (Revisit)

Describe alternatives you've considered
N/A

Additional context
N/A

Repository House Keeping

Feature Request: RunsAs_userID

Is your feature request related to a problem? Please describe.
IRRSMO00 has a parameter that would allow the XML passed to it to be run under a different User ID.

Describe the solution you'd like
Allowing pyracf to leverage this would be beneficial for automated tasking, and could also allow for a variation on resource profile access checking.

Describe alternatives you've considered
N/A

Additional context
Link to IRRSMO00 Documentation discussing this

Feature Request: EXPIRED/NOEXPIRED option on set_password and set_passphrase

Is your feature request related to a problem? Please describe.
set_password and set_passphrase options currently don't have the option to set non-expired passwords.

Describe the solution you'd like
We should add an optional argument to these functions to make the password non-expired.

Describe alternatives you've considered
N/A

Additional context
N/A

Bug Report: Resource Profile Subfunctions extract "" as "" and not as null

Describe the bug
Resource Profile Subfunctions extract "" as "" and not as null

To Reproduce
Set a trait like grouping_class_name to "" in a resource profile and extract it with any applicable profile extract function.

Expected behavior
This should be cast to null rather than left as an empty string

Console Output
Visible in unit tests and documentation for resource profile subfunctions

Environment Information:
N/A

Additional context
N/A

Bug Report: Secrets redaction code causes result XML that contains secrets to be truncated

Describe the bug
Secrets redaction logic causes result XML to be truncated. This bug affects pyRACF version 1.0a2.

                                 [pyRACF:Debug]
                                   Result XML
                            UserAdmin.set_password()


<?xml version="1.0" encoding="IBM-1047"?>
<securityresult xmlns="http://www.ibm.com/systems/zos/saf/IRRSMO00Result1">
  <user name="SQUIDWRD" operation="set" requestid="UserRequest">
    <info>Definition exists. Add command skipped due  to precheck option</info>
    <command>
      <safreturncode>0</safreturncode>
      <returncode>0</returncode>
      <reasoncode>0</reasoncode>
      <image>

Traceback (most recent call last):
  File "/usr/lpp/IBM/cyp/v3r11/pyz/lib/python3.11/xml/etree/ElementTree.py", line 1716, in close
    self.parser.Parse(b"", True) # end of data
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
xml.parsers.expat.ExpatError: no element found: line 1, column 394

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/u/<userid>/.local/lib/python3.11/site-packages/pyracf/user/user_admin.py", line 288, in set_password
    result = self.alter(userid, traits={"base:password": password})
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/u/<userid>/.local/lib/python3.11/site-packages/pyracf/user/user_admin.py", line 410, in alter
    return self._make_request(user_request, irrsmo00_precheck=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/u/<userid>/.local/lib/python3.11/site-packages/pyracf/common/security_admin.py", line 174, in _make_request
    results = SecurityResult(result_xml)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/u/<userid>/.local/lib/python3.11/site-packages/pyracf/common/security_result.py", line 12, in __init__
    self.__result = XMLParser.fromstring(result_xml)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/u/<userid>/.local/lib/python3.11/site-packages/defusedxml/common.py", line 127, in fromstring
    return parser.close()
           ^^^^^^^^^^^^^^
  File "/usr/lpp/IBM/cyp/v3r11/pyz/lib/python3.11/xml/etree/ElementTree.py", line 1718, in close
    self._raiseerror(v)
  File "/usr/lpp/IBM/cyp/v3r11/pyz/lib/python3.11/xml/etree/ElementTree.py", line 1618, in _raiseerror
    raise err

To Reproduce
Steps to reproduce the behavior:

from pyracf import UserAdmin
user_admin = UserAdmin()
user_admin.set_password("userid", "password")

Expected behavior
A description of what you expected to happen.

Result XML should not be truncated when secrets are redacted. Secrets redaction should complete successfully with no issues.

Console Output

                                 [pyRACF:Debug]
                               Result Dictionary
                            UserAdmin.set_password()


{
  "securityResult": {
    "user": {
      "name": "SQUIDWRD",
      "operation": "set",
      "requestId": "UserRequest",
      "info": [
        "Definition exists. Add command skipped due  to precheck option"
      ],
      "commands": [
        {
          "safReturnCode": 0,
          "returnCode": 0,
          "reasonCode": 0,
          "image": "ALTUSER SQUIDWRD  PASSWORD    (********)"
        }
      ]
    },
    "returnCode": 0,
    "reasonCode": 0
  }
}

{'step1': {'securityResult': {'user': {'name': 'SQUIDWRD', 'operation': 'set', 'requestId': 'UserRequest', 'info': ['Definition exists. Add command skipped due  to precheck option'], 'commands': [{'safReturnCode': 0, 'returnCode': 0, 'reasonCode': 0, 'image': 'ALTUSER SQUIDWRD  PASSWORD    (********)'}]}, 'returnCode': 0, 'reasonCode': 0}}}

Environment Information:

  • z/OS Version: 2.4
  • Python Version: 3.11.0
  • is R_SecMgtOper (IRRSMO00) setup? Yes

Additional context

This bug can be fixed by changing the following line in the redact_result_xml function in common/logger.py as follows.

Code that is causing bug:

            xml_string = self.__redact_string(xml_string, match.end(), ") ")

Fixed code (remove the space from the last argument):

            xml_string = self.__redact_string(xml_string, match.end(), ")")

Feature Request: Simplify Creating Resource Classes

Is your feature request related to a problem? Please describe.
Even for developing tests in certain environments, creating resource classes and adjusting their attributes is a needlessly complex process. We have the building blocks in resource administration already, so let's make this more attainable.

Bug Report: Resource Profile Extract Auditing Issues

Describe the bug
When Resource Profiles are extracted, the Auditing trait is not correctly parsed, leading to invalid data in the dictionary.

To Reproduce
Add or alter a resource such that it has multiple Auditing values such as: "SUCCESS(READ),FAILURES(UPDATE)" in the example, the result dictionary showed:

                "auditing": {
                  "success": "update"
                }

Expected behavior
Result dictionary should show:

                "auditing": {
                  "success": "read",
                  "failures":"update"
                }

Console Output

                             [pyRACF:Debug]                                
                           Result Dictionary                               
                        ResourceAdmin.extract()                            

{
"securityResult": {
"resource": {
"name": "TSTRES2",
"class": "ELIJTEST",
"operation": "listdata",
"requestId": "ResourceRequest",
"commands": [
{
"safReturnCode": 0,
"returnCode": 0,
"reasonCode": 0,
"image": "RLIST ELIJTEST (TSTRES2) ",
"messages": [
"CLASS NAME",
"----- ----",
"ELIJTEST TSTRES2",
" ",
"LEVEL OWNER UNIVERSAL ACCESS YOUR ACCESS WARNING",
"----- -------- ---------------- ----------- -------",
" 00 ESWIFT NONE NONE NO",
" ",
"INSTALLATION DATA",
"-----------------",
"NONE",
" ",
"APPLICATION DATA",
"----------------",
"NONE",
" ",
"AUDITING",
"--------",
"SUCCESS(READ),FAILURES(UPDATE)",
" ",
"NOTIFY",
"------",
"NO USER TO BE NOTIFIED"
]
}
]
},
"returnCode": 0,
"reasonCode": 0
}
}

                             [pyRACF:Debug]                                
                 Result Dictionary (Formatted Profile)                     
                        ResourceAdmin.extract()                            

{
"securityResult": {
"resource": {
"name": "TSTRES2",
"class": "ELIJTEST",
"operation": "listdata",
"requestId": "ResourceRequest",
"commands": [
{
"safReturnCode": 0,
"returnCode": 0,
"reasonCode": 0,
"image": "RLIST ELIJTEST (TSTRES2) ",
"profiles": [
{
"base": {
"class": "elijtest",
"name": "tstres2",
"level": 0,
"owner": "eswift",
"universalAccess": null,
"yourAccess": null,
"warning": null,
"installationData": null,
"applicationData": null,
"auditing": {
"success": "update"
},
"notify": null,
"generic": false
}
}
]
}
]
},
"returnCode": 0,
"reasonCode": 0
}
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.