如何設定使用者於指定天數後一定要更改密碼?(Command: ANZPWDCHG)
設定使用者密碼的有效天數,有兩個地方可以設定:
1. 系統值 QPWDEXPITV ==> 針對全系統設定
2. 使用者設定檔(USRPRF)中參數 PWDEXPITV ==> 針對單一使用者設定
使用者設定檔(USRPRF)中參數 PWDEXPITV 預設值為 *SYSVAL,亦即參照系統值 QPWDEXPITV。
所以一般使用者都會使用系統值 QPWDEXPITV 設定使用者密碼的有效天數,但是由於系統會自動於使用者
簽入時檢核密碼是否即將於 7 天內到期,若是則會發出密碼即將於幾天候到期的通知於畫面上,常會造成
使用者往往會等到最後一天才更改密碼,這在原本 Client Access 5250 終端畫面下並不會產生問題,但
是在使用 WAS , Tomcat 或 IIS ASP.NET 的 Web 網路連接 AS/400 系統環境下,就有可能會發生一些問
題,所以為了讓系統不要發出 "密碼是否即將於 7 天內到期" 的訊息,有必要於系統發出該訊息前,就將
使用者設定為密碼過期,較好的方式是利用密碼更改日 + 密碼有效天數來檢核是否過期,若過期就將該使
用者設定為密碼過期,密碼有效天數的計算是透過系統值 QPWDEXPITV - 10 來取得。
為因應上述需求,我提供一個指令 ANZPWDCHG(Analyze User PwdChgDate)來設定使用者是否密碼過期。
File : QRPGLESRC
Member: ANZPWDCHG
Type : RPGLE
OS : V5R1 以後(因為是使用 free form)
**
** Program . . : ANZPWDCHG
** Description : Analyze user profiles expiration by pwd changed date
** and do action
** Author . . : Vengoal Chang
**
** Date . . : 2007/11/19
**
** Modified . : 2007/11/19
** Add Expired action
**
** Compile and setup instructions:
** CrtRpgMod Module( ANZPWDCHG )
** DbgView( *LIST )
**
** CrtPgm Pgm( ANZPWDCHG )
** Module( ANZPWDCHG )
** ActGrp( *NEW )
**
**
**-- Control specification: --------------------------------------------**
H Option( *SrcStmt: *NoDebugIo ) DftActGrp(*NO)
**-- Printer file:
FQSYSPRT O F 132 Printer InfDs( PrtLinInf ) OflInd( *InOf )
**-- Printer file information:
D PrtLinInf Ds Qualified
D OvfLin 5i 0 Overlay( PrtLinInf: 188 )
D CurLin 5i 0 Overlay( PrtLinInf: 367 )
D CurPag 5i 0 Overlay( PrtLinInf: 369 )
**-- System information:
D PgmSts SDs Qualified
D PgmNam *Proc
**-- API error data structure:
D ERRC0100 Ds Qualified
D BytPrv 10i 0 Inz( %Size( ERRC0100 ))
D BytAvl 10i 0
D MsgId 7a
D 1a
D MsgDta 128a
**-- Global variables:
D LstTim s 6s 0
D SysNam s 8a
D TrlTxt s 32a
D Workdate s d
D ChgWrkDate s d
D CmdStr S 1024 INZ
D CmdLen S 15P 5 INZ(1024)
**-- List record:
D LstRcd Ds Qualified
D UsrPrf 10a
D PrfSts 10a
D PwdExpI 4a
D PwdExpD 8a
D InvSgo 3i 0
D GrpPrf 10a
D PwdI 4a
D LmtCap 4a
D SpcAut 4a
D UsrCls 10a
D PrvSgoD 8a
D PwdChgD 8a
**-- List API parameters:
D LstApi Ds Qualified Inz
D RtnRcdNbr 10i 0
D GrpNam 10a
D SltCri 10a
**-- List information:
D LstInf Ds Qualified
D RcdNbrTot 10i 0
D RcdNbrRtn 10i 0
D Handle 4a
D RcdLen 10i 0
D InfSts 1a
D Dts 13a
D LstSts 1a
D 1a
D InfLen 10i 0
D Rcd1 10i 0
D 40a
**-- User information:
D AUTU0100 Ds Qualified
D UsrPrf 10a
D UsrGrpI 1a
D GrpMbrI 1a
**-- User information:
D USRI0300 Ds Qualified
D BytRtn 10i 0
D BytAvl 10i 0
D UsrPrf 10a
D PrvSgoDts 13a Overlay( USRI0300: 19 )
D PrvSgoDat 7a Overlay( USRI0300: 19 )
D PrvSgoTim 6a Overlay( USRI0300: 26 )
D InvSgo 10i 0 Overlay( USRI0300: 33 )
D PrfSts 10a Overlay( USRI0300: 37 )
D PwdChgDat 8a Overlay( USRI0300: 47 )
D NoPwdI 1a Overlay( USRI0300: 55 )
D PwdExpDat 8a Overlay( USRI0300: 61 )
D PwdExpI 1a Overlay( USRI0300: 73 )
D UsrCls 10a Overlay( USRI0300: 74 )
D SpcAut 15a Overlay( USRI0300: 84 )
D GrpPrf 10a Overlay( USRI0300: 99 )
D LmtCap 10a Overlay( USRI0300: 189 )
**-- Open list of authorized users:
D LstAutUsr Pr ExtPgm( 'QGYOLAUS' )
D LuRcvVar 65535a Options( *VarSize )
D LuRcvVarLen 10i 0 Const
D LuLstInf 80a
D LuNbrRcdRtn 10i 0 Const
D LuFmtNam 8a Const
D LuSltCri 10a Const
D LuGrpNam 10a Const
D LuError 1024a Options( *VarSize )
**-- Get list entry:
D GetLstEnt Pr ExtPgm( 'QGYGTLE' )
D GlRcvVar 65535a Options( *VarSize )
D GlRcvVarLen 10i 0 Const
D GlHandle 4a Const
D GlLstInf 80a
D GlNbrRcdRtn 10i 0 Const
D GlRtnRcdNbr 10i 0 Const
D GlError 1024a Options( *VarSize )
**-- Close list:
D CloseLst Pr ExtPgm( 'QGYCLST' )
D ClHandle 4a Const
D ClError 1024a Options( *VarSize )
**-- Send program message:
D SndPgmMsg Pr ExtPgm( 'QMHSNDPM' )
D SpMsgId 7a Const
D SpMsgFq 20a Const
D SpMsgDta 128a Const
D SpMsgDtaLen 10i 0 Const
D SpMsgTyp 10a Const
D SpCalStkE 10a Const Options( *VarSize )
D SpCalStkCtr 10i 0 Const
D SpMsgKey 4a
D SpError 32767a Options( *VarSize )
**-- Convert date & time:
D CvtDtf Pr ExtPgm( 'QWCCVTDT' )
D CdInpFmt 10a Const
D CdInpVar 17a Const Options( *VarSize )
D CdOutFmt 10a Const
D CdOutVar 17a Options( *VarSize )
D CdError 10i 0 Const
**-- Retrieve net attribute:
D RtvNetAtr Pr ExtPgm( 'QWCRNETA' )
D RnRcvVar 32767a Options( *VarSize )
D RnRcvVarLen 10i 0 Const
D RnNbrNetAtr 10i 0 Const
D RnNetAtr 10a Const Dim( 256 )
D Options( *VarSize )
D RnError 32767a Options( *VarSize )
**-- Retrieve user information:
D RtvUsrInf Pr ExtPgm( 'QSYRUSRI' )
D RuRcvVar 32767a Options( *VarSize )
D RuRcvVarLen 10i 0 Const
D RuFmtNam 10a Const
D RuUsrPrf 10a Const
D RuError 32767a Options( *VarSize )
**-- Retrieve object description:
D RtvObjD Pr ExtPgm( 'QUSROBJD' )
D RoRcvVar 32767a Options( *VarSize )
D RoRcvVarLen 10i 0 Const
D RoFmtNam 8a Const
D RoObjNamQ 20a Const
D RoObjTyp 10a Const
D RoError 32767a Options( *VarSize )
**-- Convert system DTS to date:
D CvtDtsDat Pr d
D PxSysDts 8a Value
**-- Get system name:
D GetSysNam Pr 8a Varying
**-- Get user creator:
D GetUsrCrt Pr 10a
D PxUsrPrf 10a Value
**-- Send completion message:
D SndCmpMsg Pr 10i 0
D PxMsgDta 512a Const Varying
**-- Write detail line:
D WrtDtlLin Pr
**-- Write list header:
D WrtLstHdr Pr
D PxOvrFlwRel 10i 0 Const Options( *NoPass )
**-- Write list trailer:
D WrtLstTrl Pr
D PxTrlTxt 32a Const
**-- Call system command:
D QCMDEXC PR ExtPgm('QCMDEXC')
D Cmd 500A options(*varsize) Const
D CmdLen 15P 5 Const
**-- Entry parameters:
D ANZPWDCHG Pr
D PxOverDays 5 0
D PxActOpt 10a
D PxSysPrf 4a
**
D ANZPWDCHG Pi
D PxOverDays 5 0
D PxActOpt 10a
D PxSysPrf 4a
/Free
CmdStr = 'ADDLIBLE QGY' ;
CmdLen = %len(%trim(CmdStr));
Monitor;
QCMDEXC(%trim(CmdStr) : CmdLen);
On-Error;
EndMon;
LstApi.RtnRcdNbr = 1;
LstApi.SltCri = '*ALL';
LstApi.GrpNam = '*NONE';
LstAutUsr( AUTU0100
: %Size( AUTU0100 )
: LstInf
: 1
: 'AUTU0100'
: LstApi.SltCri
: LstApi.GrpNam
: ERRC0100
);
If ERRC0100.BytAvl = *Zero;
DoW LstInf.LstSts <> '2' Or LstInf.RcdNbrTot >= LstApi.RtnRcdNbr;
ExSr GetPrfInf;
LstApi.RtnRcdNbr = LstApi.RtnRcdNbr + 1;
GetLstEnt( AUTU0100
: %Size( AUTU0100 )
: LstInf.Handle
: LstInf
: 1
: LstApi.RtnRcdNbr
: ERRC0100
);
If ERRC0100.BytAvl > *Zero;
Leave;
EndIf;
EndDo;
CloseLst( LstInf.Handle: ERRC0100 );
EndIf;
WrtLstTrl( '*** E N D O F L I S T ***' );
SndCmpMsg( 'List has been printed.' );
*InLr = *On;
Return;
BegSr GetPrfInf;
RtvUsrInf( USRI0300
: %Size( USRI0300 )
: 'USRI0300'
: AUTU0100.UsrPrf
: ERRC0100
);
If ERRC0100.BytAvl = *Zero;
ExSr GetChgWrkDate;
ExSr ChkPrfInf;
EndIf;
EndSr;
BegSr ChkPrfInf;
If PxSysPrf = '*YES' Or GetUsrCrt( USRI0300.UsrPrf ) <> '*IBM';
Select;
//When USRI0300.PwdExpI = 'Y';
//ExSr WrtPrfInf;
When ChgWrkDate < %Date();
If (PxActOpt = '*DISABLED') or (PxActOpt = '*EXPIRED' );
Select;
When PxActOpt = '*DISABLED';
CmdStr = 'CHGUSRPRF USRPRF(' + %trim(USRI0300.UsrPrf) +
') STATUS(*DISABLED)';
When PxActOpt = '*EXPIRED' ;
CmdStr = 'CHGUSRPRF USRPRF(' + %trim(USRI0300.UsrPrf) +
') PWDEXP(*YES)' ;
EndSl;
CmdLen = %len(%trim(CmdStr));
QCMDEXC(%trim(CmdStr) : CmdLen);
ExSr WrtPrfInf;
Else;
ExSr WrtPrfInf;
EndIf;
EndSl;
EndIf;
EndSr;
BegSr WrtPrfInf;
LstRcd.UsrPrf = USRI0300.UsrPrf;
LstRcd.PrfSts = USRI0300.PrfSts;
LstRcd.InvSgo = USRI0300.InvSgo;
LstRcd.GrpPrf = USRI0300.GrpPrf;
LstRcd.LmtCap = USRI0300.LmtCap;
LstRcd.UsrCls = USRI0300.UsrCls;
If USRI0300.PwdExpDat = *Blanks;
LstRcd.PwdExpD = '*NONE';
Else;
LstRcd.PwdExpD = %Char( CvtDtsDat( USRI0300.PwdExpDat ): *JOBRUN );
EndIf;
If USRI0300.PwdChgDat = *Blanks;
LstRcd.PwdChgD = '*NONE';
Else;
LstRcd.PwdChgD = %Char( CvtDtsDat( USRI0300.PwdChgDat ): *JOBRUN );
EndIf;
If USRI0300.PrvSgoDts = *Blanks;
LstRcd.PrvSgoD = '*NONE';
Else;
LstRcd.PrvSgoD = %Char( %Date( USRI0300.PrvSgoDat: *CYMD0 )
: *JOBRUN
);
EndIf;
If USRI0300.PwdExpI = 'Y';
LstRcd.PwdExpI = '*YES';
Else;
LstRcd.PwdExpI = '*NO';
EndIf;
If USRI0300.NoPwdI = 'Y';
LstRcd.PwdI = '*NO';
Else;
LstRcd.PwdI = '*YES';
EndIf;
If USRI0300.SpcAut = 'NNNNNNNN';
LstRcd.SpcAut = '*NO';
Else;
LstRcd.SpcAut = '*YES';
EndIf;
WrtDtlLin();
EndSr;
BegSr *InzSr;
LstTim = %Int( %Char( %Time(): *ISO0));
SysNam = GetSysNam();
WrtLstHdr();
EndSr;
/End-Free
C GetChgWrkDate BegSr
C If USRI0300.PwdChgDat <> *Blanks
C eval ChgWrkDate =
C CvtDtsDat( USRI0300.PwdChgDat )
C ADDDUR PxOverDays:*D ChgWrkDate
C Else
C eval ChgWrkDate = %Date()
C EndIf
C EndSr
**-- Printer file definition: ------------------------------------------**
OQSYSPRT EF Header 2 2
O UDATE Y 8
O LstTim 18 ' : : '
O 36 'System:'
O SysNam 45
O 82 'User profile exceptions'
O 107 'Program:'
O PgmSts.PgmNam 118
O 126 'Page:'
O PAGE + 1
**
OQSYSPRT EF LstHdr 1
O 4 'User'
O 17 'Class'
O 29 'Group'
O 42 'Status'
O 53 'Limit'
O 65 'Spc.aut.'
O 75 'Inv.sign.'
O 84 'Password'
O 94 'Pwd.exp.'
O 104 'Exp.date'
O 114 'Sign-on'
O 129 'Pwd. changed'
**
OQSYSPRT EF DtlLin 1
O LstRcd.UsrPrf 10
O LstRcd.UsrCls 22
O LstRcd.GrpPrf 34
O LstRcd.PrfSts 46
O LstRcd.LmtCap 52
O LstRcd.SpcAut 62
O LstRcd.InvSgo Z 70
O LstRcd.PwdI 81
O LstRcd.PwdExpI 92
O LstRcd.PwdExpD 104
O LstRcd.PrvSgoD 115
O LstRcd.PwdChgD 126
**
OQSYSPRT EF LstTrl 1
O TrlTxt 34
**-- Write detail line: ------------------------------------------------**
P WrtDtlLin B
D Pi
/Free
WrtLstHdr( 3 );
Except DtlLin;
/End-Free
P WrtDtlLin E
**-- Write list header: ------------------------------------------------**
P WrtLstHdr B
D Pi
D PxOvrFlwRel 10i 0 Const Options( *NoPass )
/Free
If %Parms = *Zero;
Except Header;
Except LstHdr;
Else;
If PrtLinInf.CurLin > PrtLinInf.OvfLin - PxOvrFlwRel;
Except Header;
Except LstHdr;
EndIf;
EndIf;
/End-Free
P WrtLstHdr E
**-- Write list trailer: -----------------------------------------------**
P WrtLstTrl B
D Pi
D PxTrlTxt 32a Const
/Free
TrlTxt = PxTrlTxt;
Except LstTrl;
/End-Free
P WrtLstTrl E
**-- Convert system DTS to date: ---------------------------------------**
P CvtDtsDat B
D Pi d
D PxSysDts 8a Value
D MI_DTS s 20a
/Free
CvtDtf( '*DTS': PxSysDts: '*YYMD': MI_DTS: *Zero );
Return %Date( %Timestamp( MI_DTS: *ISO0 ));
/End-Free
P CvtDtsDat E
**-- Get system name: --------------------------------------------------**
P GetSysNam B
D Pi 8a Varying
**
**-- Local variables:
D Idx s 10i 0
D SysNam s 8a Varying
**
D RtnAtrLen s 10i 0
D NetAtrNbr s 10i 0 Inz( %Elem( NetAtr ))
D NetAtr s 10a Dim( 1 )
**
D RtnVar Ds Qualified
D RtnVarNbr 10i 0
D RtnVarOfs 10i 0 Dim( %Elem( NetAtr ))
D RtnVarDta 1024a
D RtnAtr Ds Qualified Based( RtnValPtr )
D AtrNam 10a
D DtaTyp 1a
D InfSts 1a
D AtrLen 10i 0
D Atr 1008a
/Free
RtnAtrLen = %Elem( NetAtr ) * 24 + ( %Size( SysNam )) + 4;
NetAtr(1) = 'SYSNAME';
RtvNetAtr( RtnVar
: RtnAtrLen
: NetAtrNbr
: NetAtr
: ERRC0100
);
If ERRC0100.BytAvl > *Zero;
SysNam = '';
Else;
For Idx = 1 to RtnVar.RtnVarNbr;
RtnValPtr = %Addr( RtnVar ) + RtnVar.RtnVarOfs(Idx);
If RtnAtr.AtrNam = 'SYSNAME';
SysNam = %SubSt( RtnAtr.Atr: 1: RtnAtr.AtrLen );
EndIf;
EndFor;
EndIf;
Return SysNam;
/End-Free
P GetSysNam E
**-- Get user creator: -------------------------------------------------**
P GetUsrCrt B Export
D Pi 10a
D PxUsrPrf 10a Value
**
D OBJD0300 Ds Qualified
D BytRtn 10i 0
D BytAvl 10i 0
D ObjCrt 10a Overlay( OBJD0300: 220 )
/Free
RtvObjD( OBJD0300
: %Size( OBJD0300 )
: 'OBJD0300'
: PxUsrPrf + 'QSYS'
: '*USRPRF'
: ERRC0100
);
If ERRC0100.BytAvl > *Zero;
Return *Blanks;
Else;
Return OBJD0300.ObjCrt;
EndIf;
/End-Free
P GetUsrCrt E
**-- Send completion message: ------------------------------------------**
P SndCmpMsg B
D Pi 10i 0
D PxMsgDta 512a Const Varying
**
D MsgKey s 4a
/Free
SndPgmMsg( 'CPF9897'
: 'QCPFMSG *LIBL'
: PxMsgDta
: %Len( PxMsgDta )
: '*COMP'
: '*PGMBDY'
: 1
: MsgKey
: ERRC0100
);
If ERRC0100.BytAvl > *Zero;
Return -1;
Else;
Return 0;
EndIf;
/End-Free
**
P SndCmpMsg E
File : QCMDSRC
Member: ANZPWDCHG
Type : CMD
/*-------------------------------------------------------------------*/
/* */
/* Compile options: */
/* */
/* CrtCmd Cmd( ANZPWDCHG ) */
/* Pgm( ANZPWDCHG ) */
/* SrcMbr( ANZPWDCHG ) */
/* */
/*-------------------------------------------------------------------*/
Cmd Prompt( 'Analyze User PwdChgDate')
PARM KWD(CHGDAYS) TYPE(*DEC) LEN(5 0) MIN(1) +
EXPR(*YES) PROMPT('Over user password change date')
PARM KWD(EXPACT) TYPE(*CHAR) LEN(10) RSTD(*YES) +
DFT(*PRINT) VALUES(*PRINT *DISABLED +
*EXPIRED) EXPR(*YES) PROMPT('Action for +
over change days')
Parm SYSPRF *Char 4 +
Dft( *NO ) +
Rstd( *YES ) +
SpcVal(( *YES ) +
( *NO )) +
Expr( *YES ) +
Prompt( 'Include system profiles' )
File : QCLSRC
Member: ANZPWDCHGC
Type : CLP
Usage : CRTCLPGM ANZPWDCHGC
此程式範例為全系統使用系統值 QPWDEXPITV - 10 當作密碼有效期限,並列印出報表供檢覈。
若符合使用需求才修改下列原始碼編譯後再執行 ANZPWDCHG CHGDAYS( &PWDEXPITVN ) EXPACT(*EXPIRED) 設定密碼過期。
請小心使用本範例。
亦可直接執行指令 ANZPWDCHG CHGDAYS( 80 ) EXPACT(*PRINT) 產生報表。
PGM
DCL &PWDEXPITV *CHAR 6
DCL &PWDEXPITVN *DEC 5
RTVSYSVAL SYSVAL(QPWDEXPITV) RTNVAR(&PWDEXPITV)
IF (&PWDEXPITV *EQ '*NOMAX') GOTO END
CHGVAR &PWDEXPITVN &PWDEXPITV
CHGVAR &PWDEXPITVN (&PWDEXPITVN - 10)
/* 設定過期 */
/* ANZPWDCHG CHGDAYS(&PWDEXPITVN) EXPACT(*EXPIRED) */
/* 印報表 */
ANZPWDCHG CHGDAYS(&PWDEXPITVN) EXPACT(*PRINT)
MONMSG CPF0000
END:
ENDPGM
A blog about IBM i (AS/400), MQ and other things developers or Admins need to know.
星期三, 11月 08, 2023
2007-11-30 如何設定使用者於指定天數後一定要更改密碼?(Command: ANZPWDCHG)
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言