; Simultaneous change of password in MultiUser and UserGroup environments
; (c) 1994 Martin Mares, MJSoft System Software

;DEBUG	equ	1
SYSI	equ	1
_GlobVec	equ	1

	include	"ssmac.h"
	include	"misc/usergroup.i"

	clistart

	moveq	#0,d0
	call	multiuser,muGetTaskOwner
	dtl	<No one logged in>,a0
	move.l	d0,d7				; D7=userid
	bne.s	OK1
ExitErr	jump	ss,ExitError

InsMem	jump	ss,ReportError

OK1	call	muAllocUserInfo
	put.l	d0,userinfo
	beq.s	InsMem
	move.l	d0,a3				; A3=UserInfo
	dv.l	userinfo

	move.l	d0,a0
	move.l	d7,muui_uid(a0)
	moveq	#muKeyType_uid,d0
	call	muGetUserInfo
	dtl	<Cannot determine who is logged in>,a0
	tst.l	d0
	beq.s	ExitErr

	move.l	a3,a1
	call	usergroup,getpwnam
	dtl	<User not present in usergroup passwd file>,a0
	tst.l	d0
	beq.s	ExitErr
	move.l	d0,a4			; A4=usergroup passwd record

	moveq	#1,d2
	bsr	setconmode
	dtl	<Unable to set console raw mode>,a0
	tst.l	d0
ExitErr1eq	beq.s	ExitErr

	dtl	<Enter old>,a0
	dbuf	passw1,32
	geta	passw1,a2
	clr.l	-(sp)
	push	a2
	pea	muT_Password
	bsr	Password
	move.l	sp,a0
	call	multiuser,muCheckPasswd
	lea	12(sp),sp
	dtl	<Incorrect password>,a0
	tst.l	d0
ExitErr2eq	beq.s	ExitErr1eq

	dtl	<Enter new>,a0
	dbuf	passw2,32
	geta	passw2,a2
	bsr	Password
	dtl	<Retype new>,a0
	dbuf	passw3,32
	geta	passw3,a2
	bsr	Password

	geta	passw2,a6
	geta	passw3,a1
	dtl	<Passwords don''t match>,a0
cmpit	cmp.b	(a6)+,(a1)+
ExitErr1ne	bne	ExitErr
	tst.b	-1(a6)
	bne.s	cmpit

	dtl	<Passwords must be at least six characters long>,a0
	cmp.b	#6,d4
	bcs.s	ExitErr1ne
	geta	passw2,a0
	moveq	#0,d1
	moveq	#0,d2
test1	move.b	(a0)+,d0
	beq.s	test2
	cmp.b	#'A',d0
	bcs.s	testok
	cmp.b	#'Z'+1,d0
	bcs.s	testup
	cmp.b	#'a',d0
	bcs.s	testok
	cmp.b	#'z'+1,d0
	bcc.s	testok
	moveq	#-1,d1
	bra.s	test1
testup	moveq	#-1,d2
	bra.s	test1
test2	dtl	<Passwords must contain mixed case or at least one non-alpha character>,a0
	and.l	d1,d2
ExitErr3eq	beq.s	ExitErr2eq

testok	geta	passw1,a0
	geta	passw2,a1
	call	multiuser,muPasswd
	dtl	<Password change failed>,a0
	tst.l	d0
	beq.s	ExitErr3eq

blabla	move.l	a4,a0
	geta	passw3,a1
	moveq	#16,d0
	call	usergroup,ug_GetSalt
	dtl	<ug_GetSalt failed>,a0
	tst.l	d0
	beq.s	ExitErr3eq

	geta	passw2,a0
	geta	passw3,a1
	call	crypt
	move.l	d0,pw_passwd(a4)

	dtl	<netinfo.device>,a0
	sub.l	a1,a1
	sub.l	a2,a2
	moveq	#0,d0
	moveq	#0,d1
	call	ss,TrackDevice
	move.l	a1,a3
	move.l	d1,d4
	move.w	#CMD_WRITE,IO_COMMAND(a1)
	move.l	a4,IO_DATA(a1)
	dtl	<Netinfo.device CMD_WRITE failed>,a0
	move.l	d4,a1
	call	ChkDoIO
	move.w	#CMD_UPDATE,IO_COMMAND(a3)
	dtl	<Netinfo.device CMD_UPDATE failed>,a0
	move.l	d4,a1
	call	ChkDoIO

	moveq	#0,d2
	bsr.s	setconmode
	dtl	<Password changed.>,a0
	jump	PutsNL

setconmode	get.l	stdin,d1
	jump	dos,SetMode

cleanup	moveq	#0,d2
	bsr.s	setconmode
	get.l	userinfo,a0
	jump	multiuser,muFreeUserInfo

Password	call	ss,Puts
	dtl	< password: >,a0
	call	Puts
	get.l	stdout,d1
	call	dos,Flush

	moveq	#0,d4
Passw1	get.l	stdin,d1
	move.l	a2,d2
	moveq	#1,d3
	call	Read
	dtl	<Stdin EOF>,a0
	tst.l	d0
	ble	ExitErr
	move.b	(a2),d0
	cmp.b	#13,d0
	beq.s	Passwe
	cmp.b	#10,d0
	beq.s	Passwe
	cmp.b	#8,d0
	beq.s	Passwdel
	cmp.b	#127,d0
	beq.s	Passwdel
	cmp.b	#31,d4
	beq.s	Passw1
	addq.l	#1,a2
	addq.l	#1,d4
	dtl.c	<*>,a0
	moveq	#1,d3
Passwp	move.l	a0,d2
	get.l	stdout,d1
	call	Write
	bra.s	Passw1

Passwdel	tst.w	d4
	beq.s	Passw1
	subq.w	#1,d4
	subq.l	#1,a2
	dtl.c	<',8,' ',8,'>,a0
	moveq	#3,d3
	bra.s	Passwp

Passwe	clr.b	(a2)
	dtl	<',13,'>,a0
	jump	ss,PutsNL

	dc.b	'$VER: XPasswd 1.0 (12.12.94) '
	dc.b	'© 1994 Martin Mares, MJSoft System Software',0

	tags
	library	multiuser,39
	dv.l	usergroupbase

	dc.w	sst_library
	dc.b	'AmiTCP:libs/usergroup.library',0
	even
	dc.w	4,usergroupbase

	exitrout cleanup
	finish
	end
