Hi Charles,
There are a few things I would do differently, if I were to write a
program like this.
1) Minor nit, but... I hate it when someone calls an API like QSYGETPH
but calls it with a prototype of a different name like GetProfile().
That makes the code much harder to follow, imho... Especially when
"GetProfile" is in a routine named "RtvProfile" (two phrases that mean
exactly the same thing, so does not clarify at all what the difference
between them is.) This is just a programming style nit, but it
frustrated me whilst trying to understand the code, so I posted it :-)
2) When this program fails, it does not report any errors at all. This
is just a very bad idea -- because the caller has no way to tell whether
it has succeeded or failed, and if it fails has no way to determine why
it failed. If you follow the program logic, the ErrDs specifies to the
API that it should return 256 bytes of error info in the data structure
(and therefore, no errors in the job log.) The routines each then check
that ErrDs and return 0 for failure, 1 for success, but throw away the
valuable information about what failed. The mainline routine then uses
the 1/0 responses to determine whether to swap profiles or not -- but
whether it succeeds or fails, either way, it does not report the error
to the caller or put any message in the job log. This makes it
extremely difficult to troubleshoot problems. To me, this is a major
flaw in the program design.
3) This program never releases the profile handles after getting them.
That means that every time this program is called, memory gets allocated
that remains allocated until the job ends -- aka a memory leak.
Eventually, you'll run out of profile handles this way. Also a major
flaw in the way this is coding. This needs to be fixed!
4) In order to swap back to the original user profile, after the swap,
the job (either directly or through adopted authority) must have
authority to the original profile! Why on earth doesn't it retrieve
the original profile handle BEFORE it swaps, so it can always swap back?
This is just silly.
5) Finally -- on to the question you asked about. IBM made some
changes to this API because it had a huge security hole. Background:
People were writing network servers (such as web applications or TCP/IP
server using the socket API) that would run under authority of a userid
by swapping with these APIs. The server programs would receive a
userid/password over the network, and would plug them into the QSYGETPH
API to get a profile handle. Problem: If the user who was signing on
through this network server sent a password of *NOPWD or *NOPWDCHK, they
could easily bypass the system security and get right in without knowing
the password. This was a huge security hole.
IBM solved this problem by changing the API so that if the program wants
the user to specify the password, parameters 5 & 6 (length of password
and CCSID of password) are required. If the program wants to use a
special value like *NOPWDxxx then these 5/6 parameters are not allowed,
and may not be specified. In this way, the API can tell whether the
program intends the user to be able to use special values like *NOPWD or
not -- thus closing the security hole.
Since the program you provided /never/ specifies the 5th/6th parameters,
it will only work with a special value like *NOPWD. And since all error
information is discarded, if it fails, it just "doesn't swap".
Personally, I'd simplify this greatly, and eliminate the RPG code. Do
the profile swapping in the CL, and make sure you handle errors
properly, pass the right parameters for your intent (use passwords or
not...) and release the profile handles when I'm done.
What I can't tell from your e-mail is whether you intend to have the
user supply the password? Or do you wish to use profiles with *USE
authority to the profiles, so you don't need to?
-SK
On 5/29/2013 10:48 PM, Charles Pascoe wrote:
Attn: Shannon O'Donnell or Scott Klement
The ultimate goal of this process (for us) is to imbed a call to the
program to swap users to a common user that exists on the Windows Network
and create an .XLS or .XLSX file from a spool file and write it out to a
Network Folder.
Scott - Below is the relevant code that I referred to in the email that I
sent to you.
Brief history:
All the code CLP & RPGLE was downloaded from Midrange Programmer OS/400
Edition Vol 2, Number 14 - July 17, 2003.
Author is Shannon O'Donnell.
The code below is original from the site - unmodified.
I understand, from researching QSYGETPH that IBM has made changes to the
parms for this API since the time that Shannon initially created the
source.
I have tried several different suggestions from the web as modifications
to the source to no avail.
What is happening when calling the CLP: SWAPTESTU:
a. Retrieves the calling User Profile ID - and stores it as &ORGUSER.
b. Calls the Swap User Profile program (SWAPUSRPRF) using parms for
&USERID & &PASSWORD.
c. Then issues the command WRKSPLF.
d. Then calls the Swap User Profile program again - using the &ORIGUSER
as the &USERID and *NoPwdChk as the &PASSWORD.
e. Then again issues the command WRKSPLF.
The results are:
a. If SWAPTESTU is called specifying a valid USERID as the &USERID and
`*NoPwdChk' as the &PASSWORD - then the process works - the first
issuance of WRKSPLF will display spool entries for the &USERID and the
second issuance of WRKSPLF will display spool entries for the
&ORIGUSER.
b. If SWAPTESTU is called specifying both a valid USERID and its
associated PASSWORD as the &USERID and &PASSWORD - then, on both
issuances of WRKSPLF only the spool entries for the &ORIGUSER will be
displayed.
Attached is the source for both the CLP and RPGLE code.
All help and assistance from you or anyone else will be most appreciated.
Charles Pascoe
Programming Supervisor
LASCO Fittings, Inc.
414 Morgan Street
P.O. Box 116
Brownsville, TN 38012
(731) 779-1882 Fax (731) 772-7116
[1]cpascoe@xxxxxxxxxxxxxxxxx
Think Green! Please consider before printing.
References
Visible links
1. mailto:cpascoe@xxxxxxxxxxxxxxxxx
As an Amazon Associate we earn from qualifying purchases.