Blog Archive

AS400 how to Switch user profile programmatically during runtime

Well a few days back I was working on a program that was using DDM files. Now for DDM files to work you have to add authority for each user profile that will be running that program using ADDSVRAUTE for the QDDMSERVER. So why not run the program under a specific user profile for anyone who wants to runs this program, that way we have to setup just one entry in the SYSTEM. That's when I came across two security APIS from IBM
  • QSYGETPH - Get Profile Handle 
    • The Get Profile Handle API validates user IDs and passwords and creates a profile handle for use in jobs that run under more than one user profile. The profile handle is temporary; you can use it only in the job that created it.
  • QWTSETP - Set Profile Handle 
    • The Set Profile Handle API validates the profile handle, locks the user profile, and changes the current thread to run under the user and group profiles represented by the profile handle. Once the change has been made, any open files and objects allocated by the original profile are accessible to the new profile.
Here is a sample program that uses both the aforementioned APIs to switch the user profile at run time before calling another program and then after the program returns it switches the user profile back to the original user profile.

h dftactgrp(*NO) bnddir('QC2LE')                                        
d ProgStatus     sds                                                    
d  Parms            *PARMS                                              
d  ProgName         *PROC                                               
d  ErrMsgID              40     46                                      
d  ErrMsg                91    169                                      
d  JobName              244    253                                      
d  UserId               254    263                                      
d  JobNumber            264    269                                      
d MyProgram       PR                  ExtPgm('MYPROGRAM')                  
d GetUserProfile  PR                  ExtPgm('QSYGETPH')                
d  $userID                      10A   const                             
d  $password                    10A   const                             
d  $handle                      12A                                     
d  $errorCode                32766A   options(*varsize: *nopass)        
d  $length                      10I 0 const options(*nopass)            
d  $ccsid                       10I 0 const options(*nopass)            
d SetUserProfile  PR                  ExtPgm('QWTSETP')                 
d  $handle                      12A   const                             
d  $errorCode                32766A   options(*varsize: *nopass)   
d ErrorDS         DS                                               
d  $bytesPrv              1      4I 0 INZ(256)                     
d  $bytesAvl              5      8I 0 INZ(0)                       
d  $errMsgID              9     15                                 
d  $reserved             16     16                                 
d  $errMsgDta            17    256                                 
d  curHandle      s             12a                                
d  newHandle      s             12a                                
d  nUserId        s             10a   inz('VAI')                   
d  nPassword      s             10a   inz('VAI9')                  
d  length         s              4B 0 inz(10)                      
d  ccsid          s              4B 0 inz(37)                      
   //Get handle on the current user profile, password not needed                                                               
   GetUserprofile(UserId: '*NOPWDCHK': curHandle: ErrorDS);        
   if $bytesAvl > 0;                                               
     //Get hanlde on the new user profile, password is needed here                             
     if $bytesAvl > 0;                      
       //Switch to new user profile   
       SetUserProfile(newHandle: ErrorDs);  
       if $bytesAvl > 0;                    
   //Change this to your own program call 
         //Set the user profile back to the original user                    
         SetUserProfile(curHandle: ErrorDs);
         if $bytesAvl > 0;                  
   eval *inlr = *on;