× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Jorge,



I was thinking more of how you actually are performing the profile swap
in the server program. Something like this...



Swap to new user by calling IMPERSONAT.

Call program TESTPRT from SERVERPGM.

Release swapped to handle.



From what you provided I can't really tell if the call to TESTPRT is
being performed after a profile swap has occurred.



When swapping/switching to another profile you follow these basic steps.



1. Obtain a profile handle for the current user (The Source) not the
job user. There is a difference.

2. Obtain a profile handle for the user profile you wish to switch to
- The Target.

3. Switch to the desired user profile by setting the profile handle.

4. Do something.

5. Release The Target's handle.

6. Switch to The Source's user profile by setting the profile handle.





Things to keep in mind...



o If the "get of a profile handle" process fails the API returns a
CPF message. It may or may not be in the job log.



o The program getting and setting profile handles needs to have
enough authority to do so. This means the program(s)

performing these functions have to be able to use the profiles
(read *ALLOBJ special authority) and to perform some

work against the profiles (read *SECADM special authority). This can
be accomplished using adopted authority. The

program(s) are owned by a profile with these authorities and the
program adopts the owner's authorities.



o If the "set profile handle" process fails the API returns a CPF
message. It may or may not be in the job log.



o From IBM's documentation:

"Once the change has been made, any open files and objects allocated
by the original profile are accessible to the new profile."



"The qualified job name DOES NOT change to reflect the new
user profile. However, any object created by the thread while

running under the new profile is owned by the new profile or its
group profile."



"any spooled files created are, by default, owned by that profile.
This is controlled by the spool file owner (SPLFOWN) parameter

on the CRTPRTF command and is done by putting the file under a
QPRTJOB job. Any spooled file command that references the

spooled file with the job special value * will only access those
files that were created before the profiles were swapped."



"A QPRTJOB job is the name of a job that files are spooled under when
the current job's user name is not the same as the user

profile currently running. For example, if you use Set Profile
Handle to set the profile to user JOE and create a spooled file, the
file

is spooled under job nnnnnn/JOE/QPRTJOB. This ensures that user JOE
owns the spooled file and if that user uses the WRKSPLF

command, the file is displayed."





Hope this helps.



Gary Monnier



-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx
[mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Jorge Merino
Sent: Monday, July 11, 2011 8:41 PM
To: RPG programming on the IBM i / System i
Subject: RE: Spool files under original User even after QWTSETP was
issuestoSwap a User Profile.



Gary,



The "Server Job" is a job that was submitted to call SERVERPGM program
by using SBMJOB CMD(call SERVERPGM) JOB(&DATAQ) JOBQ(&JOBQ) MSGQ(*NONE),
the jobq runs on a custom Subsystem: crtsbsd sbsd(&lib/&sbsd) pools((1
*BASE)) aut(*use).



So the calling to IMPERSONAT from SERVERPGM is as follows:



<code pgm="SERVERPGM">

... lines of code ...



chgvar &cmdlenght 17

chgvar &cmdstring 'CALL pgm(TESTPRT)'

call impersonat ('NEW_USER' '0' ' ' &cmdlenght &cmdstring )



... lines code ...

</code>



There is not CPF messages returned by any API when it is run on that
"server job", which is what is puzzling me.



I have a TESTPRT program that its only purpose in life is to create
dummy spool files.



So I do my interactive testing: CALL TEST_IMPERS



<code pgm="TEST_IMPERS">

chgvar &cmdlength 17

chgvar &cmdstring 'CALL pgm(TESTPRT)'

call impersonat ('NEW_USER' '0' ' ' &cmdlength &cmdstring )

</code>



I actually can post the entire source code for IMPERSONAT, I think it
could be useful for someone, but for now, I'm just going to put a chunk
of code at the bottom. Once again, it works great calling it
interactively, I've used these APIs before QSYGETPH/QWTSETP/QSYRLSPH but
never encountered this issue before.



The purpose on life for IMPERSONAT is to swap from QPGMR to a given
user, then execute a legacy program/command that will use SDS and
generate reports that have to be generated under the given user.



<code pgm="IMPERSONAT">

d IMPERSONAT PI

d New_User 10 Const

d JobType 1 Const

d Error 1N

d CmdLength 5p 0 Const

d CmdString 5120 Options(*Varsize) Const

/Free

// Log Parameters

ShowOnJobLog('CPF9897'

: 'User [' + %trim(sds_user) + '] Started
Impersonation'

+' for user[' + %trim(New_user) + '],'

+' Job Type[' + JobType + '],'

+' Command Lenght[' + %char(CmdLength) + ']'

:write_qhst);

ShowOnJobLog('CPF9897'

:' -- CMD:'+ %Subst(CmdString : 1 : CmdLength)

:write_qhst);

If validateOK();

error = SwapUser('*SET' : New_User : new_user_ph : ori_user_ph
);

If error;

ShowOnJobLog('CPF9897' : 'There is an Error when +

trying to impersonate ' + new_user );

Else;

error = execute();

SwapUser('*RLS' : *Blanks :
new_user_ph : ori_user_ph );

EndIf;

Else;

error = *On;

ShowOnJobLog('CPF9897'

:'Errors logged on impersonation- See errors in
Job Log'

: write_qhst);

EndIf;

If error;

ErrorLog();

EndIf;

ShowOnJobLog('CPF9897' : 'End Impersonation');

*InLR = *On;

/End-Free





*********************************************

*@function: execute

*@Description:

*********************************************

p execute B

d execute pi n

d tlength s 10i 0

/Free

tlength = CmdLength;

If JobType = '0'; // Batch

tlength += 27; // Add the SBMCMD+Parms string length.

QCmd = 'SBMJOB CMD('

+ %SubSt(CmdString : 1 : CmdLength)

+ ') JOBQ(QINTER)';

Else;

QCmd = CmdString;

EndIf;

Monitor;

QCMDEXC(QCmd : tlength );

On-Error;

error = *On;

ErrorLog();

EndMon;

Return error;

/End-Free

p E





*********************************************

*@function: validateOK

*@Description:

*********************************************

p validateOK B

d validateOK pi n

d return_OK s n Inz(*On)

/Free

// Validation goes here....

Return return_OK;

/End-Free

p E





*********************************************

*@function: SwapUser

*@Description:

*********************************************

p SwapUser B

d SwapUser pi n

d action 5 Const

d new_user 10 Const

d new_user_ph 12

d ori_user_ph 12

d error_return s n

/Free

Select;

When action = '*RLS';

ReleaseUserProfile();

When action = '*SET';

error_return = SetUserProfile();

Other;

error_return = *On;

EndSl;

If error_return;

ShowOnJobLog('CPF9897' : 'Errors on SwapUser()');

EndIf;

return error_return;

/End-Free

p SwapUser E



*********************************************

*@function: SetUserProfile

*@Description:

*********************************************

p SetUserProfile b

d SetUserProfile pi n

d error_return s n inz(*off)

/Free

Monitor;

// Get Profile Handle Profile Handle

QSYGETPH( '*CURRENT'

: '*NOPWD'

: ori_user_ph

: QSYGETPH_error

);

If QSYGETPH_error.bytes_available <> 0;

error_return = *On;

ShowOnJobLog(QSYGETPH_error.exception_id

:QSYGETPH_error.exception_data);

ShowOnJobLog('CPF9897' :'Errors on QSYGETPH *CURRENT');

Else;

// Get Profile Handle for New User

QSYGETPH( New_user

: '*NOPWD'

: new_user_ph

: QSYGETPH_error

);

If QSYGETPH_error.bytes_available <> 0;

error_return = *On;

ShowOnJobLog(QSYGETPH_error.exception_id

:QSYGETPH_error.exception_data);

ShowOnJobLog('CPF9897' :'Errors on QSYGETPH ' + New_user);

Else;

// Swap User, so the current thread runs under this user.

QWTSETP( new_user_ph : QWTSETP_error );

If QWTSETP_error.bytes_available <> 0;

error_return = *On;

ShowOnJobLog(QWTSETP_error.exception_id

:QWTSETP_error.exception_data);

Else;

// Set Job User identity to the name of the Job

QWTSJUID(1: QWTSJUID_error );

If QWTSJUID_error.bytes_available <> 0;

error_return = *On;

ShowOnJobLog(QWTSJUID_error.exception_id

:QWTSJUID_error.exception_data);

EndIf;

EndIf;

EndIf;

EndIf;

On-Error;

error_return = *On;

ErrorLog();

EndMon;

return error_return;

/End-Free

p SetUserProfile e



*********************************************

*@function: ReleaseUserProfile

*@Description: Releases the Swapped User and put back the Original
User.

*********************************************

p ReleaseUserProfile...

p b

d ReleaseUserProfile...

d pi

/Free

QWTSJUID(2: QWTSJUID_error ); // Clear Job User Identity

QWTSETP( ori_user_ph: QWTSETP_error );

QSYRLSPH( new_user_ph : QSYRLSPH_error );

QSYRLSPH( ori_user_ph : QSYRLSPH_error );

/End-Free

p ReleaseUserProfile...

p e

</code>



I spent few hours searching the midrange archives, looking into the IBM
documentation, looking into very old posts and I can't find where the
mistake is.



Your help is highly appreciated.



Jorge Merino

~jmerinoh~



-----Original Message-----

From: rpg400-l-bounces@xxxxxxxxxxxx
[mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Monnier, Gary

Sent: Monday, July 11, 2011 4:59 PM

To: RPG programming on the IBM i / System i

Subject: RE: Spool files under original User even after QWTSETP was
issues toSwap a User Profile.



Jorge,







Which server are you running your IMPERSONAT program from and what CPF

error are you encountering?







I've had a wee bit of experience with profile switching so if you feel

comfortable sending me a pseudo-code of the steps you are taking in the

server and IMPERSONAT I may be able to help.







Gary Monnier







-----Original Message-----

From: rpg400-l-bounces@xxxxxxxxxxxx

[mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Jorge Merino

Sent: Monday, July 11, 2011 3:29 PM

To: RPG programming on the IBM i / System i

Subject: Spool files under original User even after QWTSETP was issues

toSwap a User Profile.







Hi!







I just created a program to do "impersonation" and execute a give

command, that is a small program that basically will swap the user id

and execute a given command.







The program uses the following APIs in the following order:



ori_user_ph = QSYGETPH(*current)



New_user_PH = QSYGETPH(New_user)



QWTSETP(New_user_PH)



QWTSJUID( set )



--Command Execution--



QWTSETP( ori_user_ph )



QWTSJUID( clear )



QSYRLSPH( new_user_ph )



QSYRLSPH( ori_user_ph )







The program gets compiled with a regular PGMR non-*ALLOBJ user. Let's

say that my program is called IMPERSONAT.







After compilation, I have a *SECADM level user to change the program as:



CHGPGM PGM(MYLIB/IMPERSONAT) USRPRF(*OWNER) USEADPAUT(*NO)



CHGOBJOWN OBJ(MYLIB/IMPERSONAT) OBJTYPE(*PGM) NEWOWN(SECADM)







I execute the program in a regular interactive Job and it works great.

It creates some spool files under the new user, so far so good. These

are some job attributes:



Subsystem . . . . . . . . . . . . . . . . . : QINTER



Subsystem pool ID . . . . . . . . . . . . : 2



Type of job . . . . . . . . . . . . . . . . : INTER



Special environment . . . . . . . . . . . . : *NONE







However, this program must be called from a existing server job running

under QPGMR, so I call the new program exactly as I called the program

interactively, and here is the problem: the spool files are still shown

under QPGMR rather than the new user.



Subsystem . . . . . . . . . . . . . . . . . : RNSFIN2



Subsystem pool ID . . . . . . . . . . . . : 1



Type of job . . . . . . . . . . . . . . . . : BATCH



Special environment . . . . . . . . . . . . : *NONE







I'm receiving the Error DS from QWTSETP (and any API involved) in order

to know if there is errors, I even logging every error returned from any

API into the job log but no errors are returned; I'm even doing SBMJOB

CMD(CALL IMPERSONAT) from the server job rather than a regular CALL ,

notice that I'm not using the USER() parameter on SBMJOB but the program

gets executed under the new User even using its Job Description.







The first version of my program was using the Service Program APIs

equivalent, but I changed them to use API OPMs just in case. I also

added QWTSJUID to change the Job User Identity for the Job, just after

QWTSETP (for both to set and to clear).







How can I force the server job to generate the new spool files under the

user just after QWTSETP happened?







Any Ideas, suggestions?



Thanks.







Jorge Merino



~jmerinoh~



http://nuvek.com/



http://vektr.com/




As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.