diff --git a/pyracf/common/irrsmo00.c b/pyracf/common/irrsmo00.c index e64def5..f752798 100644 --- a/pyracf/common/irrsmo00.c +++ b/pyracf/common/irrsmo00.c @@ -48,30 +48,21 @@ static PyObject *call_irrsmo00(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; } + PyObject * full_result; char work_area[1024]; unsigned char req_handle[64] = {0}; running_userid_t running_userid_struct = {running_userid_length, {0}}; unsigned int alet = 0; unsigned int acee = 0; - unsigned char result_buffer[result_buffer_size]; + unsigned char * result_buffer = malloc(result_buffer_size); memset(result_buffer, 0, result_buffer_size); - unsigned int saf_rc = 8; - unsigned int racf_rc = 4000; - unsigned int racf_rsn = 85771; + unsigned int saf_rc = 0; + unsigned int racf_rc = 0; + unsigned int racf_rsn = 0; unsigned int result_len = result_buffer_size; unsigned int num_parms = 17; unsigned int fn = 1; - printf("Before Call!!!!!!!!!!!!!!!!!!!!\n"); - printf("Request XML: %s\n", request_xml); - printf("Request XML Length: %d\n", request_xml_length); - printf("Handle value: %s\n", req_handle); - printf("Handle Address: %d\n", &req_handle); - printf("Result Buffer Size: %d\n",result_buffer_size); - printf("Result Buffer Address: %d\n",&result_buffer); - printf("Result Buffer Contents: %s\n",result_buffer); - printf("Result Buffer Len: %d\n",result_len); - strncpy( running_userid_struct.running_userid, running_userid, @@ -96,16 +87,40 @@ static PyObject *call_irrsmo00(PyObject *self, PyObject *args, PyObject *kwargs) &result_len, result_buffer); + // Use a PyList Structure to accumulate "bytes" objects of result_buffers + full_result = PyList_New(1); + PyList_SetItem(full_result, 0, Py_BuildValue("y#", result_buffer, result_len)); + + if ((saf_rc == 8) && (racf_rc == 4000) && (racf_rsn < 100000000)){ + free(result_buffer); + result_len = racf_rsn; + result_buffer = malloc(result_len); + memset(result_buffer, 0, result_len); + + // Call IRRSMO64 Again with the appropriate buffer size + IRRSMO64( + work_area, + alet, + &saf_rc, + alet, + &racf_rc, + alet, + &racf_rsn, + num_parms, + fn, + irrsmo00_options, + request_xml_length, + request_xml, + req_handle, + running_userid_struct, + acee, + &result_len, + result_buffer); + + PyList_Append(full_result, Py_BuildValue("y#", result_buffer, result_len)); + } - printf("After Call!!!!!!!!!!!!!!!!!!!!\n"); - printf("Request XML: %s\n", request_xml); - printf("Request XML Length: %d\n", request_xml_length); - printf("Handle value: %s\n", req_handle); - printf("Handle Address: %d\n", &req_handle); - printf("Result Buffer Size: %d\n",result_buffer_size); - printf("Result Buffer Address: %d\n",&result_buffer); - printf("Result Buffer Contents: %s\n",result_buffer); - printf("Result Buffer Len: %d\n",result_len); + free(result_buffer); // https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue // @@ -144,8 +159,8 @@ static PyObject *call_irrsmo00(PyObject *self, PyObject *args, PyObject *kwargs) // Py_BuildValue() will return a Tuple. return Py_BuildValue( - "{s:y#,s:[B,B,B]}", - "resultBuffer", result_buffer, result_len, + "{s:O,s:[B,B,B]}", + "resultBuffers", full_result, "returnCodes", saf_rc, racf_rc, racf_rsn); } @@ -157,7 +172,7 @@ static char call_irrsmo00_docs[] = " irrsmo00_options: uint,\n" " running_userid: bytes,\n" " running_userid_length: uint,\n" - ") -> Dict{ resultBuffer: bytes, returnCodes: List[int,int,int] }:\n" + ") -> Dict{ resultBuffers: List[bytes], returnCodes: List[int,int,int] }:\n" "# Returns an XML result string and return and reason " "codes from the IRRSMO00 RACF Callable Service.\n"; diff --git a/pyracf/common/irrsmo00.py b/pyracf/common/irrsmo00.py index 4b15053..b8c7f78 100644 --- a/pyracf/common/irrsmo00.py +++ b/pyracf/common/irrsmo00.py @@ -67,25 +67,10 @@ def call_racf( running_userid=running_userid, running_userid_len=len(running_userid), ) - if ( - (result["returnCodes"][0] == 8) - and (result["returnCodes"][1] == 4000) - and (result["returnCodes"][2] < 100000000) - ): - print(result) - result = call_irrsmo00( - request_xml=request_xml, - request_xml_len=len(request_xml), - result_buffer_size=result["returnCodes"][2], - irrsmo00_options=irrsmo00_options, - running_userid=running_userid, - running_userid_len=len(running_userid), - ) - print(result) # Preserve raw result XML just in case we need to create a dump. # If the decoded result XML cannot be parsed with the XML parser, # a dump may need to be taken to aid in problem determination. - self.__raw_result_xml = result["resultBuffer"] + self.__raw_result_xml = b"".join(result["resultBuffers"]) # Replace any null bytes in the result XML with spaces. result_xml = self.__null_byte_fix(self.__raw_result_xml) # 'irrsmo00.c' returns a raw unmodified bytes object containing a copy diff --git a/tests/common/test_irrsmo00_interface.py b/tests/common/test_irrsmo00_interface.py index 7a579e2..bde7ed2 100644 --- a/tests/common/test_irrsmo00_interface.py +++ b/tests/common/test_irrsmo00_interface.py @@ -57,7 +57,7 @@ def test_irrsmo00_null_byte_fix( ]) # fmt: on call_irrsmo00_wrapper_mock.return_value = { - "resultBuffer": xml_containing_null_bytes, + "resultBuffers": [xml_containing_null_bytes], "returnCodes": [0, 0, 0], } self.assertEqual( @@ -71,7 +71,7 @@ def test_irrsmo00_empty_result( ): # Simulate failure due to incomplete 'IRR.IRRSMO00.PRECHECK' setup call_irrsmo00_wrapper_mock.return_value = { - "resultBuffer": bytes([0 for i in range(256)]), + "resultBuffers": [bytes([0 for i in range(256)])], "returnCodes": [8, 200, 16], } self.assertEqual(self.irrsmo00.call_racf(b""), [8, 200, 16]) @@ -82,39 +82,20 @@ def test_irrsmo00_result_buffer_full_failure( ): # Simulate scenario where result buffer is too small. call_irrsmo00_wrapper_mock.return_value = { - "resultBuffer": self.good_xml[:32], - "returnCodes": [8, 4000, 100000000], + "resultBuffers": [self.good_xml[:32]], + "returnCodes": [8, 4000, 32], } self.assertEqual( self.irrsmo00.call_racf(b""), self.good_xml.decode("cp1047")[:32] ) - # def test_irrsmo00_result_buffer_full_redrive( - # self, - # call_irrsmo00_wrapper_mock: Mock, - # ): - # # Simulate scenario where result buffer is too small. - # call_irrsmo00_wrapper_mock.side_effect = [ - # { - # "resultBuffer": self.good_xml[:32], - # "returnCodes": [8, 4000, 32], - # }, - # { - # "resultBuffer": self.good_xml[32:], - # "returnCodes": [0, 0, 0], - # }, - # ] - # self.assertEqual( - # self.irrsmo00.call_racf(b""), self.good_xml.decode("cp1047") - # ) - def test_irrsmo00_result_buffer_full_success( self, call_irrsmo00_wrapper_mock: Mock, ): # Simulate scenario where result buffer is exactly the right size. call_irrsmo00_wrapper_mock.return_value = { - "resultBuffer": self.good_xml[: self.good_xml_null_terminator_index], + "resultBuffers": [self.good_xml[: self.good_xml_null_terminator_index]], "returnCodes": [0, 0, 0], } self.assertEqual( @@ -124,7 +105,7 @@ def test_irrsmo00_result_buffer_full_success( def test_irrsmo00_normal_result(self, call_irrsmo00_wrapper_mock: Mock): call_irrsmo00_wrapper_mock.return_value = { - "resultBuffer": self.good_xml, + "resultBuffers": [self.good_xml], "returnCodes": [0, 0, 0], } self.assertEqual( @@ -137,7 +118,7 @@ def test_irrsmo00_normal_result(self, call_irrsmo00_wrapper_mock: Mock): # ============================================================================ def test_irrsmo00_minimum_arguments(self, call_irrsmo00_wrapper_mock: Mock): call_irrsmo00_wrapper_mock.return_value = { - "resultBuffer": self.good_xml, + "resultBuffers": [self.good_xml], "returnCodes": [0, 0, 0], } self.irrsmo00.call_racf(b"some bytes") @@ -152,7 +133,7 @@ def test_irrsmo00_minimum_arguments(self, call_irrsmo00_wrapper_mock: Mock): def test_irrsmo00_with_precheck_set_to_true(self, call_irrsmo00_wrapper_mock: Mock): call_irrsmo00_wrapper_mock.return_value = { - "resultBuffer": self.good_xml, + "resultBuffers": [self.good_xml], "returnCodes": [0, 0, 0], } self.irrsmo00.call_racf(b"some bytes", precheck=True) @@ -167,7 +148,7 @@ def test_irrsmo00_with_precheck_set_to_true(self, call_irrsmo00_wrapper_mock: Mo def test_irrsmo00_with_run_as_userid_set(self, call_irrsmo00_wrapper_mock: Mock): call_irrsmo00_wrapper_mock.return_value = { - "resultBuffer": self.good_xml, + "resultBuffers": [self.good_xml], "returnCodes": [0, 0, 0], } self.irrsmo00.call_racf(b"some bytes", run_as_userid="KRABS") @@ -184,7 +165,7 @@ def test_irrsmo00_with_custom_result_buffer_size( self, call_irrsmo00_wrapper_mock: Mock ): call_irrsmo00_wrapper_mock.return_value = { - "resultBuffer": self.good_xml, + "resultBuffers": [self.good_xml], "returnCodes": [0, 0, 0], } irrsmo00 = IRRSMO00(result_buffer_size=32768)