|
Hi JD,
On a hunch, I decided to do a little googling with your name and found a posting I had missed in the past from 2001. It included the source of your working exit program: http://archive.midrange.com/midrange-l/200103/msg00908.html
Hmmm... that's an older version of the one I'm using now. Here's an updated copy that might work better (or worse, who knows) than that one. I don't remember if the version I posted 5 years ago had bugs that I discovered later :)
Keep in mind that a lot of the code in this exit program is customized to work the way my company wants it. Your company may want theirs to act a little differently...
You'll also see the code herein that I used to test the auto-signon when the device name is 'SCOTT' and comes from IP address 192.168.5.71, it signs on as me, automatically...
** Telnet Device Initialization Exit Program ** ** -------------------------------------------------------- ** This Program Was Written By ** ** /////// /////// //// /// ** //// //// //// /// ** ////// //// ////// ** //// //// //// /// ** /////// // /////// // //// /// // ** ** M a r c h 5 t h , 2 0 0 1 ** --------------------------------------------------------- ** ** CHG JMB 05-14-2003 Added RF13-15 ** CHG SCK 01-09-2004 Added code to disconnect existing session ** if device name is same, and coming from same ip addr. ** (only activated for RF terms for now) ** CHG SCK 09-10-2006 Clean up code, convert to /FREE ** ** This prorgram is run by OS/400 as an "exit program". It ** is used to figure out which device names to assign to incoming ** TELNET clients. (People connecting via TCP/IP) ** ** To Compile: ** CRTBNDRPG ISOTELIR4 SRCFILE(xxx/QRPGLESRC) DBGVIEW(*LIST) ** ** To Install: ** ** ONLY DO THIS IF ITS NOT ALREADY INSTALLED! ** ** ** USE WRKREGINF TO FOR THIS EXITPNT TO SEE. ** ** ADDEXITPGM EXITPNT(QIBM_QTG_DEVINIT) FORMAT(INIT0100) ** PGMNBR(*LOW) PGM(xxx/ISOTELIR4) ** ** WARNING: Make sure that only trusted users have the ability ** to change/recompile this program! A user with the ability ** to change this program can make it possible to log on as any ** other user without a password! ** H OPTION(*SRCSTMT) DFTACTGRP(*NO) ACTGRP(*NEW) USRPRF(*OWNER) ** ** This works like *ENTRY PLIST ** D ISOTELIR4 PR ExtPgm('ISOTELIR4') D peUser likeds(UserDescription_t) D peDev likeds(DevDescription_t) D peConn likeds(ConnDescription_t) D peEnvOpt 32767A options(*varsize) D peEnvLen 10I 0 D peAllowConn 1A D peAutoSignOn 1A D ISOTELIR4 PI D peUser likeds(UserDescription_t) D peDev likeds(DevDescription_t) D peConn likeds(ConnDescription_t) D peEnvOpt 32767A options(*varsize) D peEnvLen 10I 0 D peAllowConn 1A D peAutoSignOn 1A ** API to convert binary IP address to "dotted" D AF_INET C 2 D inet_ntoa PR * ExtProc('inet_ntoa') D ulong_addr 10U 0 VALUE D inet_addr PR 10U 0 ExtProc('inet_addr') D dotted * value options(*string) ** Execute Command API D QCMDEXC PR ExtPgm('QCMDEXC') D Command 32702A const options(*varsize) D Length 15P 5 const ** Check if device is active D IsActiveDevice PR 1N D peObject 10A const ** Kill active session D KillActive PR D peDevd 10A const D peAddr 15A const D UserDescription_t... D ds qualified D based(Template) D Len 10I 0 D Profile 10A D Curlib 10A D Program 10A D Menu 10A D DevDescription_t... D ds qualified D based(Template) D Name 10A D Format 8A D 2A D AttrOff 10I 0 D AttrLen 10I 0 D ConnDescription_t... D ds qualified D based(Template) D Len 10I 0 D Addr 20A D ValidPW 1A D WrkStnType 12A D SSLConn 1A D ServerIP 20A D ClientAuth 1A D 3A D CrtRC 10I 0 D CrtOff 10I 0 D CrtLen 10I 0 D DispAttr DS qualified D based(p_DispAttr) D KeyboardID 3A D 1A D CodePage 10I 0 D CharSet 10I 0 D IP ds based(p_IP) D qualified D Len 3I 0 D Family 3I 0 D Port 5U 0 D Addr 10U 0 D wkConnIP S 16A D wkLowRF s 10U 0 D wkHighRF s 10U 0 D wkRFNo s 2S 0 D wkDevNo s 4S 0 /free // ************************************************** // Make sure the parameters have sane values. // ************************************************** peAllowConn = *ON; peAutoSignOn = *OFF; if ( %parms < 7 ); *inlr = *on; return; endif; if (peConn.Len < 24); *inlr = *on; return; endif; p_DispAttr = %addr(peDev) + peDev.AttrOff; p_IP = %addr(peConn.Addr); if ( IP.Len < 8); *inlr = *on; return; endif; // FIXME: This should be upgraded to handle both // IPv4 and IPv6. if ( IP.Family <> AF_INET ); *inlr = *on; return; endif; // ************************************************** // If the 5250 emulator supports "auto-signon" // it can submit the userid/password as variables // during the connection process. // // Notes: // - This is for "auto-signon" only. The normal // green-screen signon screen has not yet // been displayed to the user. // // - peConn.ValidPW relates to whether i5/OS // thinks the submitted password was valid // // - Our company does not allow profiles that start // with Q to auto-signon because all of the // IBM profiles (QSYSOPR, QSECOFR, QUSER, etc) // start with Q. // // WARNING: When peAutoSignOn is *ON, the system // does not validate the password! That // means that anyone who can change this // program to set peAutoSignOn to *ON // can log on under any account he likes // without a valid password! // ************************************************** if ( peUser.Len>39 and peUser.Profile<>*blanks ); if ( peConn.ValidPW='1' or peConn.ValidPW='2'); peAutoSignOn = *On; endif; if ( %subst(peUser.Profile:1:1) = 'Q' ); peAutoSignOn = *Off; endif; endif; // ************************************************** // Configure device names // // - Mike (who uses IP 192.168.5.66) should always // get device W6. // // - RF terminals should be given the name RFnn // if the same IP address is already connected, // kill the previous connection. // ************************************************** wkConnIP = %str(inet_ntoa(IP.Addr)); wkLowRF = inet_addr('192.168.5.193'); wkHighRF = inet_addr('192.168.5.239'); select; when ( wkConnIP = '192.168.5.66' ); peDev.Name = 'W6'; when ( IP.Addr>=wkLowRF and IP.Addr<=wkHighRF ); wkRFno = (IP.Addr - wkLowRF) + 1; peDev.Name = 'RF' + %char( (IP.Addr - wkLowRF) + 1 ); KillActive( peDev.Name : wkConnIP ); endsl; // ************************************************** // The Seagull JWalk clients that we use for the // TrustedLink EDI/400 and Kronos software always // use these attributes. // // KLUDGE ALERT: It's possible for ANY terminal // to use these parameters. If we buy one that // does, we'll have to change the way we detect // JWALK clients! // ************************************************** if ( peDev.Name = *blanks and DispAttr.KeyboardID = 'INB' and DispAttr.CodePage = 500 and DispAttr.CharSet = 697 and peConn.WrkStnType = 'IBM-3477-FC' ); peAllowConn = *off; for wkDevNo = 1 to 100; peDev.Name = 'JWALK' + %editc(wkDevNo:'X'); if (not IsActiveDevice(peDev.Name)); peAllowConn = *on; leave; endif; endfor; endif; // ************************************************** // Safety Net: If a device is already active // with the given name, fall back to *blanks // ( which results in a QPADEVxxxx name ) // ************************************************** if (peDev.Name <> *blanks); if (isActiveDevice(peDev.Name)); peDev.Name = *blanks; endif; endif; // ************************************************** // If a device named SCOTT logs on from Scott // Klement's PC, automatically sign it on under // the KLEMSCOT user profile // ************************************************** if ( wkConnIP='192.168.5.71' and peDev.Name='SCOTT' ); peUser.Profile = 'KLEMSCOT'; peAutoSignOn = *ON; endif; *inlr = *on; return; /end-free *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * Check to see if a device name is available for us to use. * Usually, if its unavailable its because the device is already * in use (thus the procedure name) * * Note that if an error occurs, we will return *OFF (device not * active). This will, essentially, cause the device to fall * back to a QPADEVxxxx device name, thanks to the "Safety Net" * coded above. *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ P IsActiveDevice B D IsActiveDevice PI 1N D peObject 10A const ** Create User Space API D QUSCRTUS PR ExtPgm('QUSCRTUS') D UsrSpc 20A CONST D ExtAttr 10A CONST D InitialSize 10I 0 CONST D InitialVal 1A CONST D PublicAuth 10A CONST D Text 50A CONST D Replace 10A CONST D ErrorCode 32767A options(*varsize) ** Retrieve Pointer to User Space API D QUSPTRUS PR ExtPgm('QUSPTRUS') D peUsrSpc 20A CONST D pePointer * ** API Error Code Structure D ErrorCode DS qualified D BytesProv 10I 0 INZ(%size(ErrorCode)) D BytesAvail 10I 0 INZ(0) ** List Configuration Descriptions API D QDCLCFGD PR ExtPgm('QDCLCFGD') D QualUsrSpc 20A const D Format 8A const D CfgDescType 10A const D ObjQualif 40A const D StatQualif 20A const D ErrorCode 32767A options(*varsize) ** (Generic) Structure for API List Headers D ListHdr DS BASED(p_ListHdr) D qualified D Offset 10I 0 overlay(ListHdr:125) D Count 10I 0 overlay(ListHdr:133) D Size 10I 0 overlay(ListHdr:137) ** List Entries for List Cfg Desc API D dsCfg DS based(p_Cfg) D qualified D Status 10I 0 D Name 10A D Category 10A D HRStat 20A D Text 50A D Job 10A d User 10A d JobNbr 6A D Passthru 10A D APIFmt 8A D CmdSuf 4A D wwEntry S 10I 0 D MY_USRSPC C 'ISOTELIR4 QTEMP' /free // ************************************************** // Create a 16k user space in QTEMP // ************************************************** QUSCRTUS( MY_USRSPC : 'ISOTELIR4' : 16 * 1024 : x'00' : '*ALL' : *blanks : '*YES' : ErrorCode ); if (ErrorCode.BytesAvail > 0); return *OFF; endif; // ************************************************** // List the configuration description to the // user space // ************************************************** QDCLCFGD( MY_USRSPC : 'CFGD0200' : '*DEVD' : peObject : '*GE *VARYOFF' : ErrorCode ); if (ErrorCode.BytesAvail > 0); return *OFF; endif; // ************************************************** // Make sure we found some existing devices // ************************************************** QUSPTRUS('ISOTELIR4 QTEMP': p_ListHdr ); if (ListHdr.Count < 1); return *OFF; endif; ListHdr.Count = ListHdr.Count - 1; // ************************************************** // Search the list for the given device // ************************************************** for wwEntry = 0 to ListHdr.Count; p_Cfg = p_ListHdr + ListHdr.Offset + (wwEntry * ListHdr.Size); if ( dsCfg.Name = peObject ); // Status: 0 = Varied Off // 20 = Vary On Pending // 30 = Varied On if ( dsCfg.Status <> 0 and dsCfg.Status <> 20 and dsCfg.Status <> 30 and dsCfg.Job <> *blanks ); return *ON; else; return *OFF; endif; endif; endfor; return *OFF; /end-free P E *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * This checks to see if there's already an active terminal with * the same name from the same IP address. * * If there is, it kills the existing terminal so that the new * session can use it's device name. *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ P KillActive B D KillActive PI D peDevd 10A const D peAddr 15A const ** Retrieve Device Info API: D QDCRDEVD PR ExtPgm('QDCRDEVD') D RcvVar 32767A options(*varsize) D RcvVarLen 10I 0 const D Format 8A const D Device 10A const D ErrorCode 32767A options(*varsize) ** API Error Code Structure D ErrorCode DS qualified D BytesProv 10I 0 INZ(%size(ErrorCode)) D BytesAvail 10I 0 INZ(0) D dsDev ds 937 qualified D 859A D Port 5U 0 D Addr 10U 0 D 12A D Dotted 15A D JobName 10A D User 10A D JobNbr 6A D wwCmd s 200A varying /free if IsActiveDevice( peDevd ) = *OFF; return; endif; QDCRDEVD( dsDev : %size(dsDev) : 'DEVD0600' : peDevd : ErrorCode ); if (ErrorCode.BytesAvail > 0); return; endif; if ( peAddr = dsDev.Dotted ); wwCmd = 'ENDTCPCNN PROTOCOL(*TCP) ' + 'LCLINTNETA(''192.168.5.4'') ' + 'LCLPORT(23) ' + 'RMTINTNETA(''' + %trim(dsDev.dotted) + ''') ' + 'RMTPORT(' + %char(dsDev.Port) + ')'; monitor; QCMDEXC( wwCmd: %len(wwCmd) ); on-error; return; endmon; endif; wwCmd = 'DLYJOB DLY(1)'; QCMDEXC(wwCmd: %len(wwCmd)); return; /end-free P E
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 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.