/*
15.5/EBF 17340 SMP/P/x86_64/Enterprise Linux/ase155/2391/64-bit/OPT/Mon Nov  9 14:15:35 2009

Confidential property of Sybase, Inc.
Copyright 1987, 2009
Sybase, Inc.  All rights reserved.
Unpublished rights reserved under U.S. copyright laws.

This software contains confidential and trade secret information of Sybase,
Inc.   Use,  duplication or disclosure of the software and documentation by
the  U.S.  Government  is  subject  to  restrictions set forth in a license
agreement  between  the  Government  and  Sybase,  Inc.  or  other  written
agreement  specifying  the  Government's rights to use the software and any
applicable FAR provisions, for example, FAR 52.227-19.
Sybase, Inc. One Sybase Drive, Dublin, CA 94568, USA
*/

declare @retval int
exec @retval = sp_version 'installhasvss', NULL, '15.5/EBF 17340 SMP/P/x86_64/Enterprise Linux/ase155/2391/64-bit/OPT/Mon Nov  9 14:15:35 2009', 'start'
if (@retval != 0) select syb_quit()
go

declare @script_versnum int
select @script_versnum = 15500
if (@@version_number < @script_versnum)
begin
	print "'installhasvss' is being run on an older ASE installation. ASE version '%1!', install scripts version '%2!'.",
		@@version_number, @script_versnum
	select syb_quit()
end
go

declare @do_quit int
select @do_quit = 0
if (check_db_upgrade('master') = 0)
begin
	print "'installhasvss' cannot continue, because 'master' database is not upgraded to correct version."
	select @do_quit = 1
end
if (check_db_upgrade('tempdb') = 0)
begin
	print "'installhasvss' cannot continue, because 'tempdb' database is not upgraded to correct version."
	select @do_quit = 1
end
if (check_db_upgrade('model') = 0)
begin
	print "'installhasvss' cannot continue, because 'model' database is not upgraded to correct version."
	select @do_quit = 1
end
if (check_db_upgrade('sybsystemprocs') = 0)
begin
	print "'installhasvss' cannot continue, because 'sybsystemprocs' database is not upgraded to correct version."
	select @do_quit = 1
end
if (check_db_upgrade('sybsecurity') = 0)
begin
	print "'installhasvss' cannot continue, because 'sybsecurity' database is not upgraded to correct version."
	select @do_quit = 1
end
if (@do_quit = 1)
	select syb_quit()
go

use master
go
set flushmessage on
go
if not exists (select 1 
		from sysservers where srvid = 0 ) 
begin
	print 'Please add the local server name, reboot and try again.'
	select syb_quit()
end
if (@@cmpstate < 0)
begin
	print 'HA Services are not enabled. Please enable HA Services.'
	print 'reboot and and try again.'
	select syb_quit()
end
go
if (@@cmpstate > 0)
begin
	print 'Server is not in single server mode.'
	print 'Please run dbcc ha_admin("","state_machine","halt") and try again.'
	print ' '
	select syb_quit()
end
go
dbcc ha_admin('','state_machine')
go
if (@@error = -1)
begin
	declare @servernetname varchar(255)
	declare @sqlbuf varchar(255)
	if not exists (select 1
		from tempdb.dbo.sysobjects
			where name = 'ha__syb_hacmp')
	begin
		select @servernetname=srvnetname from sysservers
			where srvname = 'SYB_HACMP'
		exec ("create table tempdb.dbo.ha__syb_hacmp(srvnetname varchar(32))")
		select @sqlbuf = "insert into tempdb.dbo.ha__syb_hacmp values("
		+ '"' + @servernetname + '"' + ")"
		exec (@sqlbuf)
	end
end
go
if exists (select 1
        from sysobjects
                where name = 'sp_configure')
begin
        execute sp_configure "allow updates", 1
end
reconfigure with override
go
declare @srvnetname varchar(255)
declare @dflt_status smallint 
declare @newclass smallint 
select @srvnetname = srvnetname from sysservers where srvid = 0
if exists (select 1 from sysservers where srvname like 'SYB_HACMP')
begin
	if exists (select 1
        	from sysobjects
                	where name = 'sp_addserver')
	begin
		exec sp_addserver 'SYB_HACMP', 'ASEnterprise', @srvnetname
	end
	else
	begin
		update sysservers
		set srvnetname = @srvnetname where srvname like 'SYB_HACMP'
		dbcc cis ('srvdes', 999) 
	end
end
else
begin
	if exists (select 1
        	from sysobjects
                	where name = 'sp_addserver')
	begin
		exec sp_addserver 'SYB_HACMP', 'ASEnterprise', @srvnetname
	end
	else
	begin
		select @dflt_status = number from master.dbo.spt_values   
			where type = "A" and 
				name = "rpc security model A"
		select  @newclass = number from  master.dbo.spt_values
			where  type = 'X' and 
				lower(name) = lower('ASEnterprise')
		insert into master.dbo.sysservers
                	(srvid, srvstatus, srvname, srvnetname ,srvclass)
				values (999, @dflt_status, 'SYB_HACMP', 
						@srvnetname, @newclass)
	end
end
go
use sybsystemprocs
go
exec sp_drop_object 'sp_ha_crtbladvisory', 'procedure'
go

exec sp_drop_object 'sp_ha_crtbladvisory_attrs', 'procedure'
go

exec sp_drop_object 'sp_hadummyfunc', 'procedure'
go

exec sp_drop_object 'sp_ha_displayadvisory_help', 'procedure'
go

exec sp_drop_object 'sp_ha_initadvisory_attrs', 'procedure'
go

exec sp_drop_object 'sp_ha_getattrib_grpname', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_ha_getattribs', 'procedure'
go

exec sp_drop_object 'sp_ha_logadvisory_rec', 'procedure'
go

exec sp_drop_object 'sp_ha_initadvisory_rec', 'procedure'
go

exec sp_drop_object 'sp_ha_initadvisory', 'procedure'
go

exec sp_drop_object 'sp_ha_displayadvisory', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_ha_validateadvisory', 'procedure'
go

exec sp_drop_object 'sp_ha_getadvisory', 'procedure'
go

exec sp_drop_object 'sp_hacmpadvisory', 'procedure'
go

exec sp_drop_object 'sp_locktable', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_halocksptables', 'procedure'
go

exec sp_drop_object 'sp_halockclustertables', 'procedure'
go

exec sp_drop_object 'sp_ha_verification', 'procedure'
go

exec sp_drop_object 'sp_addserver', 'procedure'
go

exec sp_drop_object 'sp_addlanguage', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_droplanguage', 'procedure'
go

exec sp_drop_object 'sp_add_resource_limit', 'procedure'
go

exec sp_drop_object 'sp_drop_resource_limit', 'procedure'
go

exec sp_drop_object 'sp_modify_resource_limit', 'procedure'
go

exec sp_drop_object 'sp_setlangalias', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_locklogin', 'procedure'
go

exec sp_drop_object 'sp_set_password', 'procedure'
go

exec sp_drop_object 'sp_password', 'procedure'
go

exec sp_drop_object 'sp_addlogin', 'procedure'
go

exec sp_drop_object 'sp_droplogin', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_defaultdb', 'procedure'
go

exec sp_drop_object 'sp_defaultlanguage', 'procedure'
go

exec sp_drop_object 'sp_logintrigger', 'procedure'
go

exec sp_drop_object 'sp_modifylogin', 'procedure'
go

exec sp_drop_object 'sp_addremotelogin', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_dropremotelogin', 'procedure'
go

exec sp_drop_object 'sp_addexternlogin', 'procedure'
go

exec sp_drop_object 'sp_dropexternlogin', 'procedure'
go

exec sp_drop_object 'sp_addalias', 'procedure'
go

exec sp_drop_object 'sp_dropalias', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_dropserver', 'procedure'
go

exec sp_drop_object 'sp_addgroup', 'procedure'
go

exec sp_drop_object 'sp_dropgroup', 'procedure'
go

exec sp_drop_object 'sp_changegroup', 'procedure'
go

exec sp_drop_object 'sp_adduser', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_dropuser', 'procedure'
go

exec sp_drop_object 'sp_remoteoption', 'procedure'
go

exec sp_drop_object 'sp_serveroption', 'procedure'
go

exec sp_drop_object 'sp_changedbowner', 'procedure'
go

exec sp_drop_object 'sp_renamedb', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_addtype', 'procedure'
go

exec sp_drop_object 'sp_droptype', 'procedure'
go

exec sp_drop_object 'sp_add_time_range', 'procedure'
go

exec sp_drop_object 'sp_drop_time_range', 'procedure'
go

exec sp_drop_object 'sp_modify_time_range', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_maplogin', 'procedure'
go

exec sp_drop_object 'sp_update_authmech_value', 'procedure'
go

exec sp_drop_object 'sp_attrib_notify', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_rmt_adhoc_update', 'procedure'
go

exec sp_drop_object 'sp_hacmpvalidatecfg', 'procedure'
go

exec sp_drop_object 'sp_hacmpcheckcfg', 'procedure'
go

exec sp_drop_object 'sp_haproxydbspace', 'procedure'
go

exec sp_drop_object 'sp_ha_numrows_usedpgs', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_hatabspace', 'procedure'
go

exec sp_drop_object 'sp_hamasterspace', 'procedure'
go

exec sp_drop_object 'sp_haspacereqd', 'procedure'
go

exec sp_drop_object 'sp_havrfyargs', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_havrfy', 'procedure'
go

exec sp_drop_object 'sp_ha_gensguid', 'procedure'
go

exec sp_drop_object 'sp_haupdcatalogs', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_haupdsuid', 'procedure'
go

exec sp_drop_object 'sp_hasyncsysattrs', 'procedure'
go

exec sp_drop_object 'sp_hasynclogins', 'procedure'
go

exec sp_drop_object 'sp_hasyncgrouproles', 'procedure'
go

exec sp_drop_object 'sp_hasyncssn', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_hasyncsrvroles', 'procedure'
go

exec sp_drop_object 'sp_hasyncloginroles', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_hasyncrmtlogins', 'procedure'
go

exec sp_drop_object 'sp_hasyncpermissions', 'procedure'
go

exec sp_drop_object 'sp_hasyncapps', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_haupdproxydbstate', 'procedure'
go

exec sp_drop_object 'sp_haproxydb', 'procedure'
go

exec sp_drop_object 'sp_ha_admin', 'procedure'
go

exec sp_drop_object 'sp_hasyncuserinfo', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_loglocalstate', 'procedure'
go

exec sp_drop_object 'sp_logremotestate', 'procedure'
go

exec sp_drop_object 'sp_hacmpcfgvrfy', 'procedure'
go

exec sp_drop_object 'sp_hacmpcheckdevices', 'procedure'
go

exec sp_drop_object 'sp_hacmpcheckdatabase', 'procedure'
go

exec sp_drop_object 'sp_havalidatelogin', 'procedure'
go

exec sp_drop_object 'sp_havalidatealias', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_havalidatermtlogins', 'procedure'
go

exec sp_drop_object 'sp_hacmpchecklogins', 'procedure'
go

exec sp_drop_object 'sp_hacmpcheckroles', 'procedure'
go

exec sp_drop_object 'sp_hacmpcheckappres', 'procedure'
go

exec sp_drop_object 'sp_hacmpcheckapps', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_hacmpchecksysattribs', 'procedure'
go

exec sp_drop_object 'sp_hacmpaccessvrfy', 'procedure'
go

exec sp_drop_object 'sp_hacluster', 'procedure'
go

if ((select db_name()) = "master") 
	dump tran master with truncate_only
else
    if ((select db_name()) = "sybsystemprocs") 
	dump tran sybsystemprocs with truncate_only
    else
        if ((select db_name()) = "dbccdb") 
	    dump tran dbccdb with truncate_only
        else
            if ((select db_name()) = "dbccalt") 
	        dump tran dbccalt with truncate_only
go

exec sp_drop_object 'sp_companion', 'procedure'
go

use master
go
/* Sccsid = "@(#) generic/sproc/src/server_install 84.1 6/23/93" */
/*	4.8	1.1	06/14/90	sproc/src/server_sun */
/*
**  This file contains the necessary modifications to be made for
**  various DataServer host machines.
**  It sets the DataServer host environment to be linux.
**  spt_values.low is the number of bytes in a DataServer page.
*/
use master
go

delete spt_values
	where type = "E" and number > 0
go
/* data page size for linux */
insert into spt_values (name, number, type, low)
	values ("linux", 1, "E", @@maxpagesize)

/* Value to set and clear the high bit for int datatypes for linux. */
insert into spt_values (name, number, type, low)
	values ("int high bit", 2, "E", 0x00000080)

/* Value which gives the byte position of the high byte for int datatypes for linux. */
insert into spt_values (name, number, type, low)
	values ("int high byte", 3, "E", 4)
go

/*
** Make minimum allowable memory setting equal to value which
** would allow for successful operation of the server on a linux.
*/
update spt_values
	set low = 3850
		from spt_values
	where number = 104 
		and type = "C"
go

/*
** Value indicates the support of direct i/o on this port
*/

insert into spt_values (name, number, type, low)
        values ("directio", 0, "io", 1)

/* command to fix up freeoff on page 24 in all databases */
dbcc dbrepair (master, fixsysindex)

go

dump transaction master to diskdump with truncate_only
go
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_crtbladvisory')
begin
	drop procedure sp_ha_crtbladvisory
end
go
print "Installing sp_ha_crtbladvisory"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_crtbladvisory_attrs')
begin
	drop procedure sp_ha_crtbladvisory_attrs
end
go
print "Installing sp_ha_crtbladvisory_attrs"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
**  crthatables
**
**  This procedure creates the tables necessary for HA services.
**  We just need the schema from the catalogs.
*/
/*
** raiserror Messages for crthatables [Total 1]
**
** 19529, "Cannot open database '%1!'. Check the availability of this database and retry the installation."
*/
use master
go

/* **************************************************************************** ** ***************** MASTER ONLY CATALOGS NEEDING SYNCHRONIZATION *************
*/

/* Do not create indexes for proxies */
dbcc traceon(11223)
go

/*
** Schema for SYSCONFIGURES
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysconfigures')
begin
	drop table rmt_ha_sysconfigures
end
go
if exists (select * from sysattributes where 
	object_cinfo like 'rmt_ha_sysconfigures' 
	and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_sysconfigures'
end
go
create proxy_table rmt_ha_sysconfigures at "SYB_HACMP.master.dbo.sysconfigures"
go
grant all on rmt_ha_sysconfigures to public
go

/*
** Schema for SYSLOGINS
*/
if exists (select * from sysindexes where name like 'rmt_ha_syslogins')
begin
	drop table rmt_ha_syslogins
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_syslogins'
        and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_syslogins'
end
go
create proxy_table rmt_ha_syslogins at "SYB_HACMP.master.dbo.syslogins"
go
grant all on rmt_ha_syslogins to public
go

/*
** Schema for SYSSERVERS
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysservers')
begin
	drop table rmt_ha_sysservers
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysservers'
        and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_sysservers'
end
go
create proxy_table rmt_ha_sysservers at "SYB_HACMP.master.dbo.sysservers"
go
grant all on rmt_ha_sysservers to public
go

/*
** Schema for SYSREMOTELOGINS 
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysremotelogins')
begin
        drop table rmt_ha_sysremotelogins
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysremotelogins'
        and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_sysremotelogins'
end
go
create proxy_table rmt_ha_sysremotelogins at "SYB_HACMP.master.dbo.sysremotelogins"
go
grant all on rmt_ha_sysremotelogins to public
go

/*
** Schema for SYSLOGINROLES
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysloginroles')
begin
        drop table rmt_ha_sysloginroles
end
go

if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysloginroles'
        and class = 9 and attribute = 1 )

	exec sp_dropobjectdef 'rmt_ha_sysloginroles'
go

create proxy_table rmt_ha_sysloginroles at "SYB_HACMP.master.dbo.sysloginroles"
go
grant all on rmt_ha_sysloginroles to public
go

/*
** Schema for SYSSRVROLES
*/
if exists (select * from sysindexes where name like 'rmt_ha_syssrvroles')
begin
	drop table rmt_ha_syssrvroles
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_syssrvroles'
        and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_syssrvroles'
end
go
create proxy_table rmt_ha_syssrvroles at "SYB_HACMP.master.dbo.syssrvroles"
go
grant all on rmt_ha_syssrvroles to public
go

/*
** Schema for SYSRESOURCELIMITS
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysresourcelimits')
begin
        drop table rmt_ha_sysresourcelimits
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysresourcelimits'
        and class = 9 and attribute = 1 )
begin
        exec sp_dropobjectdef 'rmt_ha_sysresourcelimits'
end
go
create proxy_table rmt_ha_sysresourcelimits at "SYB_HACMP.master.dbo.sysresourcelimits"
go
grant all on rmt_ha_sysresourcelimits to public
go

/*
** Schema for SYSLANGUAGES
*/
if exists (select * from sysindexes where name like 'rmt_ha_syslanguages')
begin
        drop table rmt_ha_syslanguages
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_syslanguages'
        and class = 9 and attribute = 1 )
begin
        exec sp_dropobjectdef 'rmt_ha_syslanguages'
end
go
create proxy_table rmt_ha_syslanguages at "SYB_HACMP.master.dbo.syslanguages"
go
grant all on rmt_ha_syslanguages to public
go

/*
** Schema for SYSCHARSETS
*/
if exists (select * from sysindexes where name like 'rmt_ha_syscharsets')
begin
        drop table rmt_ha_syscharsets
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_syscharsets'
        and class = 9 and attribute = 1 )
begin
        exec sp_dropobjectdef 'rmt_ha_syscharsets'
end
go
create proxy_table rmt_ha_syscharsets at "SYB_HACMP.master.dbo.syscharsets"
go
grant all on rmt_ha_syscharsets to public
go

/*
** Schema for SYSDEVICES
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysdevices')
begin
        drop table rmt_ha_sysdevices
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysdevices'
        and class = 9 and attribute = 1 )
begin
        exec sp_dropobjectdef 'rmt_ha_sysdevices'
end
go
create proxy_table rmt_ha_sysdevices at "SYB_HACMP.master.dbo.sysdevices"
go
grant all on rmt_ha_sysdevices to public
go

/*
** Schema for SYSOBJECTS
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysobjects')
begin
        drop table rmt_ha_sysobjects
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysobjects'
        and class = 9 and attribute = 1 )
begin
        exec sp_dropobjectdef 'rmt_ha_sysojbects'
end
go
create proxy_table rmt_ha_sysobjects at "SYB_HACMP.master.dbo.sysobjects"
go
grant all on rmt_ha_sysobjects to public
go

/*
** Schema for SYSTYPES
*/
if exists (select * from sysindexes where name like 'rmt_ha_systypes')
begin
        drop table rmt_ha_systypes
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_systypes'
        and class = 9 and attribute = 1 )
begin
        exec sp_dropobjectdef 'rmt_ha_systypes'
end
go
create proxy_table rmt_ha_systypes at "SYB_HACMP.master.dbo.systypes"
go
grant all on rmt_ha_systypes to public
go

/*
** Schema for SYSTHRESHOLDS
*/
if exists (select * from sysindexes where name like 'rmt_ha_systhresholds')
begin
        drop table rmt_ha_systhresholds
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_systhresholds'
        and class = 9 and attribute = 1 )
begin
        exec sp_dropobjectdef 'rmt_ha_systhresholds'
end
go
create proxy_table rmt_ha_systhresholds at "SYB_HACMP.master.dbo.systhresholds"
go
grant all on rmt_ha_systhresholds to public
go

/*
** Schema for SYSSESSIONS
*/
if exists (select * from sysindexes where name like 'rmt_ha_syssessions')
begin
	drop table rmt_ha_syssessions
end
go
if exists (select * from sysattributes where 
	object_cinfo like 'rmt_ha_syssessions' 
	and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_syssessions'
end
go
create proxy_table rmt_ha_syssessions at "SYB_HACMP.master.dbo.syssessions"
go
grant all on rmt_ha_syssessions to public
go

/*
** Schema for SYSMESSAGES
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysmessages')
begin
	drop table rmt_ha_sysmessages
end
go
if exists (select * from sysattributes where
	object_cinfo like 'rmt_ha_sysmessages'
	and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_sysmessages'
end
go
create proxy_table rmt_ha_sysmessages at "SYB_HACMP.master.dbo.sysmessages"
go
grant all on rmt_ha_sysmessages to public
go

/*
** Schema for SYSTIMERANGES
*/
if exists (select * from sysindexes where name like 'rmt_ha_systimeranges')
begin
	drop table rmt_ha_systimeranges
end
go
if exists (select * from sysattributes where
	object_cinfo like 'rmt_ha_systimeranges'
	and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_systimeranges'
end
go
create proxy_table rmt_ha_systimeranges at "SYB_HACMP.master.dbo.systimeranges"
go
grant all on rmt_ha_systimeranges to public
go

/*
** Schema for SPT_LIMIT_TYPES
*/
if exists (select * from sysindexes where name like 'rmt_ha_spt_limit_types')
begin
	drop table rmt_ha_spt_limit_types
end
go
if exists (select * from sysattributes where
	object_cinfo like 'rmt_ha_spt_limit_types'
	and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_spt_limit_types'
end
go
create proxy_table rmt_ha_spt_limit_types at "SYB_HACMP.master.dbo.spt_limit_types"
go
grant all on rmt_ha_spt_limit_types to public
go

/*
** Schema for SYSCOLUMNS
*/
if exists (select * from sysindexes where name like 'rmt_ha_syscolumns')
begin
	drop table rmt_ha_syscolumns
end
go
if exists (select * from sysattributes where
	object_cinfo like 'rmt_ha_syscolumns'
	and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_syscolumns'
end
go
create proxy_table rmt_ha_syscolumns at "SYB_HACMP.master.dbo.syscolumns"
go
grant all on rmt_ha_syscolumns to public
go

/*
** Schema for SYSENCRYPTKEYS
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysencryptkeys')
begin
        drop table rmt_ha_sysencryptkeys
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysencryptkeys'
        and class = 9 and attribute = 1 )
begin
        exec sp_dropobjectdef 'rmt_ha_sysencryptkeys'
end
go
create proxy_table rmt_ha_sysencryptkeys at "SYB_HACMP.master.dbo.sysencryptkeys"
go
grant all on rmt_ha_sysencryptkeys to public
go

/*
******************************************************************************* *********** MASTER DATABASE CATLOGS NEEDING SYNCHRONIZARION *******************
*/

/*
** Schema for SYSALTERNATES 
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysalternates')
begin
        drop table rmt_ha_sysalternates
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysalternates'
        and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_sysalternates'
end
go
create proxy_table rmt_ha_sysalternates at "SYB_HACMP.master.dbo.sysalternates"
go
grant all on rmt_ha_sysalternates to public
go

/*
** Schema for SYSPROTECTS 
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysprotects')
begin
        drop table rmt_ha_sysprotects
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysprotects'
        and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_sysprotects'
end
go
create proxy_table rmt_ha_sysprotects at "SYB_HACMP.master.dbo.sysprotects"
go
grant all on rmt_ha_sysprotects to public
go

/*
** Schema for SYSUSERS
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysusers')
begin
	drop table rmt_ha_sysusers
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysusers'
        and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_sysusers'
end
go
create proxy_table rmt_ha_sysusers at "SYB_HACMP.master.dbo.sysusers"
go
grant all on rmt_ha_sysusers to public
go

/*
** Schema for SYSROLES
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysroles')
begin
	drop table rmt_ha_sysroles
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysroles'
        and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_sysroles'
end
go
create proxy_table rmt_ha_sysroles at "SYB_HACMP.master.dbo.sysroles"
go
grant all on rmt_ha_sysroles to public
go

/*
** Schema for SYSDATABASES
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysdatabases')
begin
	drop table rmt_ha_sysdatabases
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysdatabases'
        and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_sysdatabases'
end
go
create proxy_table rmt_ha_sysdatabases at "SYB_HACMP.master.dbo.sysdatabases"
go
grant all on rmt_ha_sysdatabases to public
go

/*
** Schema for SYSATTRIBUTES
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysattributes')
begin
	drop table rmt_ha_sysattributes
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysattributes'
        and class = 9 and attribute = 1 )
begin
	exec sp_dropobjectdef 'rmt_ha_sysattributes'
end
go
create proxy_table rmt_ha_sysattributes at "SYB_HACMP.master.dbo.sysattributes"
go
grant all on rmt_ha_sysattributes to public
go

/*
** Schema for SYSJARS
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysjars')
begin
        drop table rmt_ha_sysjars
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysjars'
        and class = 9 and attribute = 1 )
begin
        exec sp_dropobjectdef 'rmt_ha_sysjars'
end
go
create proxy_table rmt_ha_sysjars at "SYB_HACMP.master.dbo.sysjars"
go
grant all on rmt_ha_sysjars to public
go

/*
** Schema for SYSXTYPES
*/
if exists (select * from sysindexes where name like 'rmt_ha_sysxtypes')
begin
        drop table rmt_ha_sysxtypes
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_sysxtypes'
        and class = 9 and attribute = 1 )
begin
        exec sp_dropobjectdef 'rmt_ha_sysxtypes'
end
go
create proxy_table rmt_ha_sysxtypes at "SYB_HACMP.master.dbo.sysxtypes"
go
grant all on rmt_ha_sysxtypes to public
go

/*
** Schema for SYSCOORDINATIONS
*/
if exists (select * from sysindexes where name like 'rmt_ha_syscoordinations')
begin
        drop table rmt_ha_syscoordinations
end
go
if exists (select * from sysattributes where
        object_cinfo like 'rmt_ha_syscoordinations'
        and class = 9 and attribute = 1 )
begin
        exec sp_dropobjectdef 'rmt_ha_syscoordinations'
end
go
create proxy_table rmt_ha_syscoordinations at 
		"SYB_HACMP.sybsystemdb.dbo.syscoordinations"
go
grant all on rmt_ha_syscoordinations to public
go

dbcc traceoff(11223)
go

dump tran master with truncate_only
go

/*
** Procedures to create HA_ADVISORY and HA_ADVISORY_ATTRS tables in TEMPDB
*/
use sybsystemprocs
go

if (db_name() != "sybsystemprocs")
begin
	/*
	** 19529, "Cannot open database '%1!'. Check the availability of this database and retry the installation."
	*/
	raiserror 19529, "sybsystemprocs"
	select syb_quit()
end
go

if exists (select *
        from sysobjects
                where sysstat & 7 = 4
                        and name = 'sp_ha_crtbladvisory')
begin
        print "Dropping sp_ha_crtbladvisory"
        drop procedure sp_ha_crtbladvisory
end
go

if exists (select *
        from sysobjects
                where sysstat & 7 = 4
                        and name = 'sp_ha_crtbladvisory_attrs')
begin
        print "Dropping sp_ha_crtbladvisory_attrs"
        drop procedure sp_ha_crtbladvisory_attrs
end
go

if (exists (select 1 from tempdb.dbo.sysobjects 
	where name = 'ha_advisory' and type = 'U'))
		drop table tempdb.dbo.ha_advisory
go

/* Schema for HA_ADVISORY */
create procedure sp_ha_crtbladvisory as
begin
	create table tempdb.dbo.ha_advisory 
				(	
					attrib_name	varchar(32),
					attrib_type	varchar(32),
					attrib_id	int,
					lattrcharval	varchar(32) null,
					lattrintval	int null,
					rattrcharval	varchar(32) null,
					rattrintval	int null,
					advisory	int,
					attrib_func	varchar(128) null,
					comments	varchar(32) null
				) lock allpages
	if @@error != 0
		return(1)
end
go

if (exists (select 1 from tempdb.dbo.sysobjects where 
	name = 'ha_advisory_attrs' and type = 'U'))
		drop table tempdb.dbo.ha_advisory_attrs
go

/*
** Schema for HA_ADVISORY_ATTRS
*/
create procedure sp_ha_crtbladvisory_attrs as
begin


	create table tempdb.dbo.ha_advisory_attrs 
				(
					attrib_grpname  varchar(32),
					attrib_type     varchar(32),
					attrib_id       int,
					attrib_func	varchar(128) null,
					comments        varchar(32) null
				) lock allpages
	if @@error != 0
		return(1)

end
go

/* Create the HA specific tables */
exec sp_ha_crtbladvisory
go

exec sp_ha_crtbladvisory_attrs
go

set nocount off
go

/* 
** Creating temporary table ha_temp_install in tempdb to 
** remember the fact that installhasvss is in progress 
*/
if (exists (select 1 from tempdb.dbo.sysobjects where 
	name = 'ha_temp_install' and type = 'U'))
		drop table tempdb.dbo.ha_temp_install
go
create table tempdb.dbo.ha_temp_install (install_in_progress tinyint) 
					lock allpages
go

dump tran sybsystemprocs with truncate_only
go

dump tran tempdb with truncate_only
go

/*
** If assigned temporary database is different than system tempdb, 
** then dump that as well.
*/
declare @tempdbname varchar(30)
select @tempdbname = db_name(@@tempdbid)
if (@tempdbname != "tempdb")
begin
	dump tran @tempdbname with truncate_only
end
go

go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hadummyfunc')
begin
	drop procedure sp_hadummyfunc
end
go
print "Installing sp_hadummyfunc"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_displayadvisory_help')
begin
	drop procedure sp_ha_displayadvisory_help
end
go
print "Installing sp_ha_displayadvisory_help"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_initadvisory_attrs')
begin
	drop procedure sp_ha_initadvisory_attrs
end
go
print "Installing sp_ha_initadvisory_attrs"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_getattrib_grpname')
begin
	drop procedure sp_ha_getattrib_grpname
end
go
print "Installing sp_ha_getattrib_grpname"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_getattribs')
begin
	drop procedure sp_ha_getattribs
end
go
print "Installing sp_ha_getattribs"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_logadvisory_rec')
begin
	drop procedure sp_ha_logadvisory_rec
end
go
print "Installing sp_ha_logadvisory_rec"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_initadvisory_rec')
begin
	drop procedure sp_ha_initadvisory_rec
end
go
print "Installing sp_ha_initadvisory_rec"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_initadvisory')
begin
	drop procedure sp_ha_initadvisory
end
go
print "Installing sp_ha_initadvisory"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_displayadvisory')
begin
	drop procedure sp_ha_displayadvisory
end
go
print "Installing sp_ha_displayadvisory"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_validateadvisory')
begin
	drop procedure sp_ha_validateadvisory
end
go
print "Installing sp_ha_validateadvisory"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_getadvisory')
begin
	drop procedure sp_ha_getadvisory
end
go
print "Installing sp_ha_getadvisory"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpadvisory')
begin
	drop procedure sp_hacmpadvisory
end
go
print "Installing sp_hacmpadvisory"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
** Error Messages for sp_haadvisory
**
** 18877, "Usage: sp_companion <srvr_name>, do_advisory, <option> [,action] 
** <option> can be either 'all', 'help', <Group|Base attrib> 
** <action> can either be <'display'|'compute'> 
** 'compute' is the default."
** 18878, "Internal Error: Unprocessed Base Attributes exists."
** 18879, "Internal Error: Attributes other than Base Attributes exist. 
** Attrib_name: '%1!', Attrib_type:'%2!', Attrib_ID: '%3!', Attrib_Func:'%4!'."
*/
/*
** SP_HAADVISORY:
**
** README FIRST:
**
** WARNING: WARNING: WARNING: WARNING: WARNING: WARNING: WARNING: WARNING:
**
** Please Consult the HA Team/Dbaccess for Any changes to this file
** Any changes not approved by the above Team may cause unforseen
** errors in HA Companion Compatibility.  
**
** If you are adding/modifying a new attribute group or attribute type, please
** Read the HOWTO section followed by the Diagnostics Section as how to debug
** if you encounter problems, if any. 
** 
** Description:
**
** 	This File contains the Main modules required to implement the 
** ha advisory function. HA Advisory is a feature callable from SP_COMPANION 
** interface to determine the companion compatibility between the Local server
** and the proposed Remote server.
**
** Assumption:
**
**	This has to be called from SP_COMPANION, where the SYB_HACMP has
** already been setup to make proxy tables point to the proposed secondary.
** Since SP_COMPANION has already obtained a CLUSTER LOCK, there is no
** danger that parallel execution of the same or other CLUSTER COMMANDs
** from the same server or any other server are not going to corrupt the
** SYB_HACMP or the data.
**
** Design:
**
** 	This Design is based on an extensible, configurable Attribute
** management system. All the companion compatibility has been seggregated
** into Attributes, say we call it Base Attributes. A Set of Base attributes
** are grouped in to a Group Attribute. In order that two servers be able
** to configure, all the instances of Base Attributes should be compatible.
**
** Ex: Server Configuration  (configuration parameters) has been divided
** into different subsets. So There is a Group called 'Config Group' with
** a Base set of Attributes ( sub sets ), like 'CIS' - all Component 
** Integration Related Config Params, Languages- All Languages, sortorder
** and charsets related config parameters etc..
**
** An instance for ex: 'cis rpc handling' config parameter is an attribute
** of base type 'CIS' of the Group 'Config Group'.
**
** All of the Base Attributes have an attribute ID (attrib_id) > 999
**
** All of the Group Attributes have an attribute ID (attrib_id) < 999
** 
** The Goal of the feature is to evaluate each instance of the attribute
** value in local server and companion server and based on known HA CLUSTER
** design decide whether they are compatible or not. The compatibility can
** be of three types.
** 
** FULLY COMPATIBLE: No further action is required from user.
**
** SOFT INCOMPATIBLE: Ideally it would require that user may need to
**		      to make amendments to this attribute, but this is
**		      not serious enough to declare that servers are 
**		      incompatible
**
** HARD INCOMPATIBLE: The attributes have to be made compatible for succssful
**		      HA companionship, failure can result in HA failure at
**		      and hence not advisable to procede  
**
** An attribute Manager has been implemented where we can define/extend/change
** Groups and Base Attributes. Every Base Attribute has an associated 
** Validation function which works on the instance of the Base attribute to 
** validate. All these definitions are automatically instantiated in a tempdb 
** only table called HA_ADVISORY_ATTRS.
**
** Attribute Manager here is auto driven to extract the Validation Function
** associated with the Base attribute for each instance to work on it. The
** Results of the Validation are logged into a Master Only Table called
** HA_ADVISORY. These results are properly formatted to fit the Display
** and reported to user.
** 
** The following are the LIST OF MAIN PROCEDURE ENTRIES.
** 
** Attribute Manager Provides the Following Functions:
** ___________________________________________________________
**
** sp_ha_initadvisory_attrs: To initialize the Advisory Attributes.
**
** sp_ha_getattrib_grpname: To get a group name based on base attrib type
**
** sp_ha_getattribs: This function gets the attributes related to a Base
**			attribute, like id, type, attribute function.
**
** sp_ha_initadvisory: This initializes the Advisory attributes in ha_advisory
**
** sp_ha_initadvisory_rec: This initializes the advisory record for logging
**
** sp_ha_getadvisory: This function invokes the Advisory validation function 
**		     for given Base attribute attrib_func()
** sp_ha_logadvisory_rec: This is a single interface to log an advisory record
**
** sp_ha_displayadvisory: This Displays the Computed Advisory
**
** sp_ha_validateadvisory: This function validates the rows in ha_advisory
** 			   
** sp_hacmpadvisory: Main entry point for invoking the Advisory command.
**
** sp_hadummyfunc: A dummy function added to Provide Diagnostic Support.
**
**
** HOWTO: Add a new Group, Attribute and Validation functions.
** ___________________________________________________________
**
**	  Simply add the Name of the Group, Base attribute Name as shown
**	  in the function, sp_ha_initadvisory_attrs.  Make sure that validation
**	  function ( stored procedure ) is added to Base attribute.
**		
**	  In the Validation Function do the Attribute specific work and log
**	  an advisory record using the standard stored procedure, 
**	  sp_ha_logadvisory_rec. THATS IT.
**
**	  See EX: for Config Group:CIS attribute. 
**		  Advisory Function: sp_hacmpcheckcfg
**
** Daignostic:
**
** 	  Use dbcc Traceon 2202 to log advisory record for every attribute
**	  it examines. See sp_hacmpcheckcfg for details on how to use it.
**
**	  Use dbcc Traceon 2226 to run Attribute Manager exerciser. It simply
**	  invoke all the functions for all groups and Base attributes and
**	  excutes a dummy function sp_hadummyfunc. If you do not see any
**	  errors during the execution, it should be fine. Simply turn on the
**	  trace flag 2226 and call advisory command with "all" option.
**
**	  User Traceon 2227 to print Diagnostic information to Trace any
**	  problems.
*/

/*
** SP_HADUMMYFUNC:
**
** Description:
**	This procedure is primarily used for diagnostics (Trace 2226) and 
** during the exerciser run of HA Attribute Manager. This procedure simply
** return after Printing the Arguments passed in.
*/
create procedure sp_hadummyfunc
@servername varchar(32),
@skip_error int,
@check_only int,
@attrib_id int,
@option	   int
as
begin
	/* Print Only if the exerciser option is on */
	dbcc istraceon(2226)
	if @@error != -1
	begin	
		print "Executed Diagnostic Dummy Func"	
		print "Arguments:"
		print "         Server Name:'%1!'", @servername	
		print "         Skip flag  :'%1!'", @skip_error	
		print "         Check flag :'%1!'", @check_only	
		print "         Atrrib id  :'%1!'", @attrib_id	
		print "         option 	   :'%1!'", @option	
	end
	else
	begin
		/* Do nothing */
		dbcc istraceon(9999)
	end
return (0)
end
go

/*
**
**  SP_HA_DISPLAYADVISORY_HELP:
**
**  Description:
**	This functions displays the usage information for the advisory
** function. All group Attributes are below 999 Id and Base Attribute
** types are > 999
**
** Description:
**	This procedure is primarily responsible for Displaying the results
** of Computed Advisory information from the Table HA_ADVISORY, based on the
** Advisory option passed in.
**
**
*/
create procedure sp_ha_displayadvisory_help
as
begin
declare @msg varchar(1024)

	set nocount on
	/*
	** 18877,  "Usage: sp_companion <srvr_name>, do_advisory, <option> 
	** [,action] 
	** <option> can be either 'all', 'help', <Group|Base attrib> 
	** <action> can either be <'display'|'compute'> 
	** 'compute' is the default."
	*/
	exec sp_getmessage 18877, @msg output
	print @msg
        print ""
        select "Group Attributes" = attrib_grpname, 
		"Base Attribute Types" = attrib_type 
			from tempdb.dbo.ha_advisory_attrs
			where attrib_id > 999
				group by attrib_grpname, attrib_type
	set nocount off
end
go

/*
**
** SP_HA_INITADVISORY_ATTRS:
**
** Description:
**	This procedure basically is responsible for defining and initializing 
** all the HA advisory attributes. All these attributes are defined ( inserted)
** into HA_ADVISORY_ATTRS table.
**
** Assumptions:
**	This function should ideally be called only once at the time of HA
** services installation.
**
** Design:
**	Every attribute, Group or Base Attribute has an unique name, ID.
** All Base Attributes must have an associated attribute valid function. 
** It is illegal to define it for a group attribute. New Attributes can
** be defined by simply yankig the lines for adding Group and Base attributes
** as in below.
**
** Impact:
**	The ha_advisory_attrs table is in tempdb and so logging hapens there.  
**	This table is created/initialized only at startup time or after a 
**	server reboot.
**
** NOTE:
** 	Be sure to define Group Attribute with ID < 999 and Base Attribute 
**  type with ID > 999. The attribute function will allways be invoked with
**  the following parameters.
**
**  attrib_func:
**		#param1:	@servername varchar (32) -- "SYB_HACMP"
**		#param2:	@skip_error int		 -- 1 (enabled)
**		#param3:	@check_only int		 -- 1 (enabled)
**		#param4:	@attrib_id  int		 -- ID of the attribute
**		#param5:	@option     int		 -- options. 
**
**		servername: name of the server, usually "SYB_HACMP"
**
**		skip_error: This generally gives the ability to continue
**		or skip an error condition in a stored procedure.
**
**		check only: This gives the ability to control to either
**		actually perform the  action or just check and continue.
**
**		attribute Id: This gives a much finer control on which
**		attributes ( examined in the stored procedure ) be validated.
**		A single function can be used to validate more than one type
**		of Base attributes.
**
**		See Example of: Config Group:CIS:sp_hacmpcfgcheck function for
**		usage of these functions.
**		
*/
create procedure sp_ha_initadvisory_attrs
as
begin
	set nocount on

	/*
	** At this point, ha_advisory_attrs is guaranteed to exist in tempdb.
	** In order to Define an Advisory Group select a group Id that
	** is one greater than the current highest and use the following
	** insert statement to add a new group.
	**
	** Current HA advisory Groups are:
	** "Config Group"	Id	= 100
	** "Space Group"	Id	= 110
	** "Logins Group"	Id	= 120
	** "Devices Group"	Id	= 130
	** "Role Group"		Id	= 140
	** "Database Group"	Id	= 160
	** "Application Group"  Id      = 170
	** "Sysattrib group"    Id      = 180
	**
	** <Add any thing more>
	*/
	/* GROUP NAME	 ATTRIBUTE NAME  ATTRID   FUNC    COMMENTS */
	/* --------------  ---------------  ------   ---- 	  -------- */
	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group",  "Config Group",    100,    NULL,  NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Space Group",   "Space Group",     110,    NULL,  NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Logins Group",  "Logins Group",    120,    NULL,  NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Roles Group",   "Roles Group",     130,    NULL,  NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Devices Group", "Devices Group",   140,    NULL,  NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Database Group",  "Database Group",160,    NULL,  NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Application Group",  "Application Group",170,    NULL,  NULL)

           insert into tempdb.dbo.ha_advisory_attrs values
           ("Sysattrib group",  "Sysattrib group", 180,  NULL,  NULL)

	/*
	** Define the Members of the Group: Members of the Group Define
	** the Base attributes. Base attributes are the ones that have
	** an associated functions ( stored procedures, builtins etc..)
	** that defines the advisory behaviour.
	**
	** All Base attributes have  attribute Ids >= 1000 and have a 
	** Parent Group associated with it. Base attributes can not
	** have multiple parents. All Base attributes have a function
	** associated with it.
	*/

	/*
	**  Define base attributes for config group
	**
	**  GROUP NAME	    ATTRIBUTE NAME   ATTRID   FUNC        COMMENTS 
	**  --------------  ---------------  ------   ---- 	  -------- 
	*/

	/* Server Space Related Base Attributes */

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Space Group", "Proxydb Space",  3100, "sp_haspacereqd", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Space Group", "Master Space",  3200, "sp_haspacereqd", NULL)

	/* Server Login Related Base Attributes */

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Logins Group", "Logins",  2100, "sp_hacmpchecklogins", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Roles Group", "Roles ",2200, "sp_hacmpcheckroles", NULL)


	/* Server Configuration Related Base Attributes */

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "CIS", 1100, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "General Config", 1110, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "Disk i/o", 1120, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "Languages", 1130, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "Errorlog", 1140, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "ESP", 1150, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "Java", 1160, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "DTM", 1170, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "Q Diag", 1180, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "Network", 1190, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "Parallel", 1200, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "Security", 1210, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "Unicode", 1220, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "Physical Memory", 1230, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "Processors", 1240, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "SQL Server admin", 1250, "sp_hacmpcheckcfg", NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Config Group", "User environment", 1260, "sp_hacmpcheckcfg", NULL)

	/* Devices related Base attributes */

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Devices Group", "Devnames", 1400, "sp_hacmpcheckdevices", NULL)

	/* Database related Base attributes */

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Database Group", "Unique Dbid", 1600, "sp_hacmpcheckdatabase",NULL)

           insert into tempdb.dbo.ha_advisory_attrs values
	   ("Database Group", "Database options", 1610,"sp_hacmpcheckdatabase",NULL)

	/* Application related Base attributes */

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Application Group", "Remote servers", 1700, "sp_hacmpcheckappres",NULL)
	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Application Group", "Languages ", 1710, "sp_hacmpcheckappres",NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Application Group", "Charsets ", 1720, "sp_hacmpcheckappres",NULL)

	   insert into tempdb.dbo.ha_advisory_attrs values
	   ("Application Group", "Sort order", 1730, "sp_hacmpcheckappres",NULL)

           insert into tempdb.dbo.ha_advisory_attrs values
           ("Application Group", "User Types", 1740, "sp_hacmpcheckapps", NULL)

           insert into tempdb.dbo.ha_advisory_attrs values
           ("Application Group", "Time Ranges",1750, "sp_hacmpcheckapps", NULL)

           insert into tempdb.dbo.ha_advisory_attrs values
           ("Application Group", "Java Archives", 1760, "sp_hacmpcheckapps",
                NULL)

         /* Sysattributes related Base attributes */

           insert into tempdb.dbo.ha_advisory_attrs values
           ("Sysattributes Group", "allow password downgrade", 1800,
		"sp_hacmpchecksysattribs", NULL)

	set nocount off
end
go


/*
** SP_HA_GETATTRIB_GRPNAME:
** 
** Description:
** 	This procedure gets the attribute's group name for a given attribute
** type. If there is no exisitng group attribute associated with it then it 
** raises an error. If the attribute type is a group attribute it simply 
** returns the same as the attribute type.
**
** Parameters:
**		@attrib_name: varchar(32)	-- Input
**		@attrib_grpname: varchar(32)	-- Output
** Returns:
**		(0) if successful, (1) other wise.
**
** Error messages:
** 	18808:Invalid attribute Id(%1!). Attribute Id should be greater than
**	%2! for Attribute '%3!'.
*/
create procedure sp_ha_getattrib_grpname
@attrib_name varchar(32),
@attrib_grpname varchar(32) output
as
begin
declare @attrib_id int

	/* See if it is one of the group attribute */
	select @attrib_id = 0
	select @attrib_id = attrib_id, @attrib_grpname = attrib_grpname from 
					tempdb.dbo.ha_advisory_attrs where 
					attrib_type = @attrib_name 
	
	/* If Trace 2227 is on Print the Parameters Passed in */
	dbcc istraceon(2227)
	if @@error != -1
	begin
		print "Func:'%1!' ", "sp_ha_getattrib_grpname"
		print "        Attrib_name:'%1!'", @attrib_name
		print "        Attrib GR Id:'%1!'", @attrib_id
		print "        Attrib GR Name:'%1!'", @attrib_grpname
	end

	/* Attribute id of the attribute type should be greater than 999 */
	if @attrib_id = 0 
	begin
		raiserror 18808, @attrib_id, 999, @attrib_name
		select @attrib_grpname = NULL
		return(1)
	end

	return(0)	
end
go

/*
** SP_HA_GETATTRIBS:
**
** Description:
**	This procedure gets the attribute validation function and the
** attribute Id for a given base attribute type, belonging to a group.
** It does all the required validation before returning success.
**
** NOTE: Please note that group attribute types have the same name as that 
** of the group name.
**
** Parameters:
**		@attrib_grpname:	Group name:	-- Input
**		@attrib_type   :	Base Attribute  -- Input
**		@attrib_id     :	Attribute Id    -- Output
**		@attrib_func   :        Attr. Function  -- Output 
**	
** Returns:
**              (0) if successful, (1) other wise.
**
** Error Messages:
**
**	18809:Invalid Attribute Name or Id. Attribute '%1!' is an invalid name 
**            for a Group or Base type; or has invalid attribute id '%2!' for 
**	      the attribute type.
**
**	18810:Internal Error: Invalid Base attribute '%1!' for the Group 
**	      attribute '%2!'".
**
*/
create procedure sp_ha_getattribs
@attrib_grpname varchar(32),
@attrib_type varchar(32),
@attrib_id int output,
@attrib_func varchar(128) output
as
declare @id  int
begin
	select @id = 0

	dbcc istraceon(2227)
        if @@error != -1
        begin
                print "Function : '%1!'", "sp_ha_getattribs"
                print "Arguments:"
                print "         Attr Grp Name:'%1!'", @attrib_grpname
                print "         Attr Type:'%1!'", @attrib_type
        end
	
	/* Check for valid group attribute, else it is an error */
	if not exists (select 1 from tempdb.dbo.ha_advisory_attrs
				where attrib_grpname = @attrib_grpname )
	begin
		/* Invalid Group name */
		raiserror 18809, @attrib_grpname, @attrib_id
		return(1)
	end

	/* Get the attrib Id associated with the Group attribute */
	select @id = @attrib_id from tempdb.dbo.ha_advisory_attrs
				where attrib_grpname = @attrib_grpname

	if @id > 999 or @id <= 0 
	begin
		/* Invalid Group Id */
		raiserror 18809, @attrib_grpname, @id
		return(1)
	end
	
	/* Check if a Base attribute exists for the given Group Attribute */
	if not exists ( select 1 from tempdb.dbo.ha_advisory_attrs where
				attrib_grpname = @attrib_grpname and
				attrib_type = @attrib_type)
	begin
		/* Invalid  Base attribute for the Group */
		raiserror 18810, @attrib_grpname, @attrib_type
		return(1)
	end

	/* Make sure that Base attributes ID is > 999 */
	select @id = attrib_id from tempdb.dbo.ha_advisory_attrs where
				attrib_grpname = @attrib_grpname and
				attrib_type = @attrib_type 

	if @id < 1000  or @id <= 0
	begin
		/* Invalid Base attribute Id */
		raiserror 18809, @attrib_type, @id
		return(1)
	end

	/* Now load all the attribute pertaining to a Base attribute */
	select @attrib_func = attrib_func, @attrib_id = attrib_id 
				from tempdb.dbo.ha_advisory_attrs where 
				attrib_id = @id and 
				    attrib_type = @attrib_type and
					attrib_grpname = @attrib_grpname
	dbcc istraceon(2227)
        if @@error != -1
        begin
                print "         Attr Id:'%1!'", @attrib_id
                print "         Attr Func:'%1!'", @attrib_func
        end
	return(0)
end
go

/*
**
** SP_HA_LOGADVISORY_REC
**
** Description:
**	This procedure inserts into HA_ADVISORY Table a log record
** formed using the parameters passed in.
**
** Parameters:
**		@attrib_name	: Name of the Attribute
**		@attrib_type    : Base Type of the Attribute, it belongs to
**		@attrib_id	: Id of the Base Attribute
**		@advisory_func  : Validation function associated
**					Only Attribute_name that are of
**					Base Attribute Type will have a
**					Valid Value.
**		@lcharvalue	: Local value of type string/char
**		@lintvalue	: Local value of type integer
**		@rcharvalue	: Remote value of type string/char
**		@rintvalue	: Remote value of type integer
**		@advisory	: Advisory associated with this record.
**		@comments	: Comments, if any.
**		@option		: option < NOT USED >
**
** Returns:
**              (0) if successful, (1) other wise.
*/
create procedure sp_ha_logadvisory_rec
@attrib_name varchar(32),
@attrib_type varchar(32),
@attrib_id int,
@advisory_func varchar(128) = null,
@lcharvalue varchar(32) = "NA",
@lintvalue int = 0,
@rcharvalue varchar(32) = "NA",
@rintvalue int = 0,
@advisory int = 100,
@comments varchar(32) = null,
@option int = null
as
	set nocount on
	insert into tempdb.dbo.ha_advisory values (
				@attrib_name,
				@attrib_type,
				@attrib_id,
				@lcharvalue,
				@lintvalue,
				@rcharvalue,
				@rintvalue,
				@advisory,
				@advisory_func,
				@comments	)
	set nocount off
go


/*
** SP_HA_INITADVISORY_REC:
**
** This procedure initializes all the necessary rows required
** for working to establish the companion compatibility.
** Based on the advisory option, HA_ADVISORY table is initialized
** with the required attribute types to work with.  Care is taken to
** ensure that no duplicates rows are inserted.
**
** Parameters:
**		@attrib_type   :	Base Attribute  -- Input
**	
** Returns:
**              (0) if successful, (1) other wise.
*/
create procedure sp_ha_initadvisory_rec 
@attrib_type varchar(32)
as
declare @attrib_grpname varchar(32)
declare @attrib_name varchar(32)
declare @attrib_func varchar(128)
declare @attrib_id int
declare @retstat int
begin
	select @retstat = 0

	/*
	** For a given attrib_name get the group it represents.
	** If there is any error, simply return as callee has
	** already reported the error.
	*/
	exec @retstat = sp_ha_getattrib_grpname @attrib_type, 
				@attrib_grpname output
	if @retstat != 0
		return(1)
	
	/*
	** Now get the  attrib id corresponding to attribute type.
	*/
	exec @retstat = sp_ha_getattribs @attrib_grpname, @attrib_type, 
					@attrib_id output, @attrib_func output
	if @retstat != 0
		return(1)

	/*
	** Now we have the attributes necessary to initialize the rows
	** If the attribute is not present in ha_advisory, do insert the row.
	*/
	if (not exists (select 1 from tempdb.dbo.ha_advisory where 
			attrib_type = @attrib_type))
	exec @retstat = sp_ha_logadvisory_rec @attrib_grpname, @attrib_type,
						@attrib_id, @attrib_func 
	if @retstat != 0
		return(1)
end
go

/*
**
** SP_HA_INITADVISORY:
**
** Description:
**	Based on the Advisory option requested by the user this functions
** initializes the required attribute types in the HA_ADVISORY Table. 	
**
** Parameters:
**		@advisory_option:	User supplied option. -- Input
**		@action		: 	<NOT USED>
**
** Returns:
**              (0) if successful, (1) other wise.
*/
create procedure sp_ha_initadvisory 
@advisory_option varchar(32),
@action varchar(20)
as
DECLARE @retstat int,
	@rowcnt  int,
	@attrib_grpname varchar(32),
	@attrib_type varchar(32)
begin 
	select @retstat = 0
	select @rowcnt = 0

	/*
	** ha_advisory table is guaranteed to exist and we will refresh
	** only those attributes specified in the advisory option.  The other
	** attributes will be left as it is.
	*/
	select @rowcnt = count(*) from tempdb.dbo.ha_advisory

	/* Initialize all the required attributes */
	if @advisory_option = "all"
	begin
		/* Delete all Base attribute instances as they might be stale */
		if (@rowcnt != 0)
		begin
			set nocount on
			delete tempdb.dbo.ha_advisory 
				where attrib_id > 999 and attrib_func is NULL
			set nocount off
		end
				
		/* Declare cursor to get all Base attributes */
		declare attr_curs_all cursor for 
			select attrib_type from tempdb.dbo.ha_advisory_attrs
				where attrib_id > 999
		open attr_curs_all
		fetch attr_curs_all into @attrib_type
		
		while (@@sqlstatus = 0)
		begin
			/* Prepare the Attribute Record */
			exec @retstat = 
				sp_ha_initadvisory_rec @attrib_type
			if @retstat != 0
				break
			fetch attr_curs_all into @attrib_type
		end		
		
		if (@@sqlstatus = 1)
			select @retstat = 1
		close attr_curs_all
		deallocate cursor attr_curs_all
		return(@retstat)
	end
	else
	begin
		/* Find the Group  name of the Advisory option */
		exec @retstat = sp_ha_getattrib_grpname 
					@advisory_option, 
					@attrib_grpname output
		if @retstat != 0
		begin
			/* Invalid advisory option */
			return(1)
		end

		/* 
		** If the Advisory option and its Group name are same
		** Then generate Base attributes pertaining to this group
		*/
		if (@advisory_option = @attrib_grpname)
		begin
			/* Initialize Base attributes pertaining to the group */
			declare attr_curs_group cursor for 
				select attrib_type from 
					tempdb.dbo.ha_advisory_attrs where 	
					attrib_grpname = @advisory_option and
					attrib_id > 999
					
			open attr_curs_group
			fetch attr_curs_group into @attrib_type
		
			while (@@sqlstatus = 0)
			begin
				/* 
				** Delete all Base attribute instances 
				** corresponding to the Base attributes of the
				** option, as they might be stale 
				*/
				if (@rowcnt != 0)
				begin
					set nocount on
					delete tempdb.dbo.ha_advisory where
					attrib_type = @attrib_type and
					attrib_id > 999 and attrib_func is NULL
					set nocount off
				end

				/* Prepare the Attribute Record */
				exec @retstat = 
				sp_ha_initadvisory_rec @attrib_type
				if @retstat != 0
					break
				fetch attr_curs_group into @attrib_type
			end		
		
			if (@@sqlstatus = 1)
				select @retstat = 1
			close attr_curs_group
			deallocate cursor attr_curs_group
			return(@retstat)
		end
		else
		begin
			/* 
			** Delete all Base attribute instances corresponding to
			** the advisory option, as they might be stale 
			*/
			if (@rowcnt != 0)
			begin
				set nocount on
				delete tempdb.dbo.ha_advisory
					where attrib_id > 999
					and attrib_func is NULL
					and attrib_type = @advisory_option
			end

			/* Initialize the Base attribute Record */
			exec @retstat = sp_ha_initadvisory_rec @advisory_option
			return(@retstat)
		end

	end
end
go

/*
** SP_HA_DISPLAYADVISORY:
**
** Description	:
**
** This Procedure Displays the advisory information generated for
** user specified attribute. 
**
** Parameter(s)	: 
**			@advisory_option	- Input
**			@action			- Input
** Assumptions	:
**
** Design	:
**
** Error Msgs	:
**
** Return Value :
**			0 - successful
**			1 - failed 
*/
create procedure sp_ha_displayadvisory 
@advisory_option varchar(32),
@action	varchar(20)
as
begin
	declare @attrib_grpname varchar(32),
		@retstat int

	select @retstat = 0
	/*
	** Advisory options are already validated and corresponding
	** to an advisory the rows in the advisory table is populated
	** so simply display everything from the table. 
	*/
	set nocount on
	if ((@action = "display") or (@action = "compute"))
	begin
		/* Display Based on the Advisory Option that was invoked */
		if @advisory_option = "all"	
		begin
			/* Select only the Base attributes definition */
		      select  "Attribute Name" = convert(char(20), attrib_name),
			"Attrib Type" = convert(char(15), attrib_type),
                	"Local Value" = convert(char(15),space(15-char_length(
			isnull(lattrcharval, convert(char(32), lattrintval))))+
			isnull(lattrcharval, convert(char(32), lattrintval))),
			"Remote Value" = convert(char(15),space(15-char_length(
			isnull(rattrcharval, convert(char(32), rattrintval))))+
			isnull(rattrcharval, convert(char(32), rattrintval))),
			"Advisory"= convert(char(8), space(8-char_length(
				convert(varchar(8), advisory)))+
				convert(varchar(8), advisory))
                	from tempdb.dbo.ha_advisory where
				attrib_func is NULL order by attrib_id
		end 
		else
		begin
			/* Find the Group  name of the Advisory option */
			exec @retstat = sp_ha_getattrib_grpname 
						@advisory_option, 
						@attrib_grpname output
			if @retstat != 0
			begin
				/* Invalid advisory option */
				return(1)
			end

			/* 
			** If the Advisory option and its Group are same, then
			** display instances of all the Base attributes for this			** group
			*/
			if (@advisory_option = @attrib_grpname)
			begin
				/* Get Base attributes for this group */
			      	select "Attribute Name" = 
					convert(char(20), attrib_name),
					"Attrib Type" = 
					convert(char(15), attrib_type),
					"Local Value" = 
				convert(char(15),space(15-char_length(
				isnull(lattrcharval, convert(char(32), 
					lattrintval))))+
				isnull(lattrcharval, convert(char(32), 
					lattrintval))),
				"Remote Value" = 
					convert(char(15),space(15-char_length(
				isnull(rattrcharval, convert(char(32), 
					rattrintval))))+
				isnull(rattrcharval, convert(char(32), 
					rattrintval))),
				"Advisory"= 
					convert(char(8), space(8-char_length(
					convert(varchar(8), advisory)))+
					convert(varchar(8), advisory))
				from tempdb.dbo.ha_advisory where
				attrib_func is NULL and
				attrib_type in 
					(select attrib_type from 
						tempdb.dbo.ha_advisory_attrs 
						where attrib_grpname = 
							@advisory_option 
						and attrib_id > 999)
				order by attrib_id
			end
			else
			begin
				/* Get Base attributes for this group */
			      	select "Attribute Name" = 
					convert(char(20), attrib_name),
					"Attrib Type" = 
					convert(char(15), attrib_type),
					"Local Value" = 
				convert(char(15),space(15-char_length(
				isnull(lattrcharval, convert(char(32), 
					lattrintval))))+
				isnull(lattrcharval, convert(char(32), 
					lattrintval))),
				"Remote Value" = 
					convert(char(15),space(15-char_length(
				isnull(rattrcharval, convert(char(32), 
					rattrintval))))+
				isnull(rattrcharval, convert(char(32), 
					rattrintval))),
				"Advisory"= 
					convert(char(8), space(8-char_length(
					convert(varchar(8), advisory)))+
					convert(varchar(8), advisory))
				from tempdb.dbo.ha_advisory where
				attrib_func is NULL and
				attrib_type = @advisory_option 
				order by attrib_id
				
			end
		end
	end
	set nocount off
	return(0)
end
go

/*
** SP_HA_VALIDATE_ADVISORY:
**
** Description	:
** 	This Procedure Validates the advisory information generated for
** user specified attribute. 
**
** Parameter(s)	: 
**			@advisory_option	- Input
**			@action			- Input
**			@advisory		- Output
** Assumptions	:
**
** Design	:
**	Validation of Advisory is simply looking into the result of the
** Advisory information generated and based on the Advisory set for
** each attribute making a decission.
**
**	Advisory option indicates the following information.
**
**		Advisory = 100
**			Attribute has just been inititlized for generating
**			an advisory info. This is generally an error. The
**
**		Advisory = 0
**			Attribute has the required compatibility with the
**			companion.
**
**		Advisory = 1
**			Attributes are soft incompatible. Meaning for the time
**			being it will be OK. But advised to make it some
**			changes as in comments.
**
**		Advisory = 2
**			Attribute is hard incompatible with its companion. User
**			Must ensure steps to make it compatible.
**
**	All attributes are examined and highest adviory information is returned
**	as the return value.
**	
** Error Msgs	:
**
** Return Value :
**			See above Advisory information.
*/
create procedure sp_ha_validateadvisory 
@advisory_option varchar(32),
@action	varchar(20),
@advisory int output
as
begin
	/* Initialize the compatibility */
	select @advisory = 0

	/*
	** If action is "display", there is no need to validate
	** the advisory information.
	*/
	if ((@action = "display") or (@action = "compute"))
		return(@advisory)
	else
	begin
		/* Find the highest Advisory that is available in the result */
		select @advisory = max(advisory) from tempdb.dbo.ha_advisory
		if @advisory != 0
		begin
			/*
			** If there are any attributes which are uninitialized
			** It is an internal error. report and exit.
			*/
			if @advisory = 100
			begin
				/* There are Attributes still uninitialized */
				/*
				** 18878, "Internal Error: Unprocessed Base 
				** Attributes exists."
				*/
				raiserror 18878
				return (1)
			end

			/*
			** Check if there are any soft/hard incompatibilities
			**
			** If exists start Logging to errro log the
			** incompatibilities.
			*/
			if exists (select 1 from tempdb.dbo.ha_advisory
						where advisory >= 1 and
						attrib_id > 999)
			begin
				/* 
				** HA_RESOLVE: Declare cursor and 
				** and process the rows to log.
				*/
				return(0)
			end
		end

		return(0)
	end
end
go


/*
** SP_HA_GETADVISORY:
**
** Description	:
**
** This Procedure gets the advisory information requested for
** user specified attribute. 
**
** Parameter(s)	: 
**			@advisory_option	- Input
**			@action			- Input
** Assumptions	:
**		Prior to callig this function all the required Base attributes
** have been entered into  HA_ADVISORY Table.
**
** Design	:
** Do the validation for all attribute Types in the HA_ADVISORY table for 
** proper Id, Group Name and non-null Attribute Functions. For each of the 
** attribute invoke the validation function associated with it.
**
** Error Msgs	:
**
** Return Value :
**			0 - successful
**			1 - failed 
*/
create procedure sp_ha_getadvisory 
@advisory_option varchar(32),
@action	varchar(20)
as
DECLARE
	@attrib_name	varchar(32),	/* attributes name */
	@attrib_type	varchar(32),	/* attribute type */
	@attrib_id	int,		/* attribute id */
	@attrib_grpname varchar(32),	/* attributes group name */
	@attrib_func	varchar(128),	/* attributes advisory func */
	@skip_error	int,		/* Skip on error */
	@check_only	int,		/* Check only */
	@option		int,		/* option */
	@retstat	int,		/* return status */
	@max_advisory	int,		/* Current Max advisory */
	@clean_cursor   int,       	/* Clean up all the cursors */
	@sql varchar(255),		/* SQL to execute */
	@error_save	int
begin
	/* All of advisory is run for Check only and skip error */
	select @skip_error = 1, @check_only = 1, @retstat = 0, @option = 0

	/* create the schema for the temp. table first */
	select * into #ha_advisory from tempdb.dbo.ha_advisory where 1 = 2

	/* insert only base attributes of a given type or a given group */
	set nocount on
	if (@advisory_option = "all")
	begin
		insert #ha_advisory select * from tempdb.dbo.ha_advisory
			where attrib_id > 999 and attrib_func is not null
	end
	else
	begin
		insert #ha_advisory select * from  tempdb.dbo.ha_advisory
			where attrib_id > 999 and attrib_func is not null
			and (@advisory_option = attrib_type or 
				@advisory_option = attrib_name)
	end
	set nocount off

	/*
	** If the action that was passed was internal check then we need to 
	** basically run checks for very  essential attributes only. Set 
	** option to 1
	*/
	if @action = "intcheck"
		select @option = 1

	/* Open a cursor on the #ha_advisory table */
	declare advisory_curs cursor for
		select attrib_name, attrib_type, attrib_id, attrib_func from
		#ha_advisory
	open advisory_curs
	fetch advisory_curs into @attrib_name, @attrib_type, 
					@attrib_id, @attrib_func

	/* Check for Validity of every base attribute */
	while (@@sqlstatus = 0)
	begin
		/* 
		** Check to make sure that there are no group attributes 
		** and the attribute id is a valid Base attribute ID and
		** the base attribute has the valid non-null func. 
		*/
		if @attrib_name = @attrib_type or @attrib_id !> 999 or
					@attrib_func is null
		begin
			/*
			** 18879, "Internal Error: Attributes other than 
			** Base Attributes exist. Attrib_name: '%1!', 
			** Attrib_type:'%2!', Attrib_ID: '%3!', 
			** Attrib_Func:'%4!'."
			*/
			raiserror 18879, @attrib_name, @attrib_type,
					@attrib_id, @attrib_func
			select @retstat = 1
		end

		/* Get the next attribute */
		fetch advisory_curs into @attrib_name, 
					@attrib_type, @attrib_id, @attrib_func
	end

	/*
	** fetch would return 1, if any error  occured. 0 for success
	** and 2 for issuing fetch again on the last row
	*/
	if (@@sqlstatus = 1)
		select @retstat = 1
	close advisory_curs
	if @retstat != 0
	begin
		deallocate cursor advisory_curs
		return (1)
	end

	/*
	** OK At this stage we have verified that all entries in the
	** ha_advisory are valid and now for each  base attribute we
	** need to just call the corresponding stored procedure to
	** log the haadvisory info.
	*/
	open advisory_curs
	fetch advisory_curs into @attrib_name, @attrib_type, 
				@attrib_id, @attrib_func

	while (@@sqlstatus = 0)
	begin

		/* Prepare SQL to execute */

		/* 
		** Because Execution_Immediately cannot catch the return
		** status of the SQL buffer execution, we use a temporary
		** table to exchange the information between the contexts
		** in/out execute ()
		*/
		create table #retvalue ( retvalue int)
		insert #retvalue values(1)

		select @sql = "declare @retstat int select @retstat = 1 "
		
		dbcc istraceon(2226)
		if @@error != -1
		begin
			select @sql = @sql + "exec @retstat = sp_hadummyfunc " +
					" SYB_HACMP, " + 
					convert(char(1), @skip_error) +', '+ 
					convert(char(1), @check_only) + 
					', '+ convert(char(4), @attrib_id) +
					', '+ convert(char(4), @option)

		end
		else
		begin
			select @sql = @sql + "exec @retstat = "
			select @sql =  @sql + @attrib_func + " SYB_HACMP, " + 
					convert(char(1), @skip_error) +', '+ 
					convert(char(1), @check_only) + 
					', '+ convert(char(4), @attrib_id) +
					', '+ convert(char(4), @option) 
		end
		select @sql = @sql + " update #retvalue set retvalue = @retstat"

		set nocount on
		execute (@sql)
		select @error_save = @@error
		set nocount off

		select @retstat = retvalue from #retvalue
		drop table #retvalue

		if ((@error_save != 0) or (@retstat != 0))
			return (1)

		/* Update the Advisory Attribute From the ha_advisory */
		select @max_advisory = max(advisory)  from 
				tempdb.dbo.ha_advisory where
					attrib_name = @attrib_name and
					attrib_type = @attrib_type and
					attrib_func = @attrib_func and
					advisory != 100

		set nocount on
		/* If there are no attributes that have issue so set green */
		if @max_advisory is NULL
			select @max_advisory = 0
		update tempdb.dbo.ha_advisory 
		set advisory = @max_advisory where 
					attrib_name = @attrib_name and
					attrib_type = @attrib_type and
					attrib_func = @attrib_func 
		set nocount off

		/* Get the next attribute */
		fetch advisory_curs into @attrib_name, @attrib_type, 
				@attrib_id, @attrib_func
	end 

	/*
	** fetch would return 1, if any error  occured. 0 for success
	** and 2 for issuing fetch again on the last row
	*/
	if (@@sqlstatus = 1)
		select @retstat = 1
	close advisory_curs
	deallocate cursor advisory_curs
	return(@retstat)
end
go

/*
** SP_HACMPADVISORY
** 
** Description:
** 	This stored procedure takes the name of the companion server and
** runs a series of checks to test the HA companion configuration
** compatibility tests and reports the success and failures of the
** test. It is highly recomended that users run this stored procedure
** before they run the actual companion configuration. 
**
** Assumptions:
**
** 	At the time of running this stored procedure all accesses across the
** intended servers from either direction has been verified and servers
** are able to talk to one another and proxy_tables have been set
** correctly to retrieve the data.
**
** Error Messages:
**
*/
create procedure sp_hacmpadvisory
@servername varchar(30),  			/* companion server name */
@advisory_option varchar (32),			/* adivisory attribute */
@action varchar (20) = "compute",		/* desired advisory action */
@advisory int	= 0	output			/* Validated advisory */
as
DECLARE
	@retstat   int,				/* return value */
	@rowcnt	   int,				/* total count of rows */
	@cmpstate  int,				/* Companion state */
	@localservername varchar(30)		/* local server name */
begin

	/*
	** If advisory option is null or help, display supported
	** option and exit
	*/
	if @advisory_option is null or @advisory_option = "help"
	begin
		exec sp_ha_displayadvisory_help
		return(0)
	end

	/* 
	** If advisory option is "display", just display records for 
	** the base attributes of interest from ha_advisory 
	*/
	if @action = "display"
	begin
		exec @retstat = sp_ha_displayadvisory @advisory_option, @action
		if  @retstat != 0
			return(1)
		else
			return(0)
	end
	
	/* Initialize the defaults */
	select @retstat = 0, @cmpstate = @@cmpstate, 
			@localservername = @@servername

	/* Refresh the haadvisory Map for the given advisory option*/
	exec @retstat = sp_ha_initadvisory @advisory_option, @action
	if @retstat != 0
		return(1)

	/* Prepare Advisory Info from the Map */
	exec @retstat = sp_ha_getadvisory  @advisory_option, @action
	if @retstat != 0
		return(1)

	/* Display the Advisory Information, if requested. */
	exec @retstat = sp_ha_displayadvisory @advisory_option, @action
	if  @retstat != 0
		return(1)

	/* Validate Advisory Information */
	exec @retstat = sp_ha_validateadvisory @advisory_option, @action,
							@advisory output
	return (@retstat)
end	
go
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
**  hainitables
**
**  This procedure initializes the tables HA_ADVISORY_ATTRS and HA_ADVISORY
**  that are required for the HA advisory functions.
*/

/*
** Initialize the HA tables in tempdb. They would've got created in crthatables
*/

exec sp_ha_initadvisory_attrs
go

exec sp_ha_initadvisory "all", "display"
go

dump tran tempdb with truncate_only
go

/*
** If assigned temporary database is different than system tempdb, 
** then dump that as well.
*/
declare @tempdbname varchar(30)
select @tempdbname = db_name(@@tempdbid)
if (@tempdbname != "tempdb")
begin
	dump tran @tempdbname with truncate_only
end
go

go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_locktable')
begin
	drop procedure sp_locktable
end
go
print "Installing sp_locktable"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*      4.8     1.1     06/14/90        sproc/src/locktable */

/*
** Messages for "sp_locktable"
**
** 18811, "Cannot lock table '%1!'."
*/

/*
** SP_LOCKTABLE
**   This stored procedure is a wrapper of "lock table" command
** @table_name could be in format db.owner.tablename with 3 * 255 + 2
** length.
*/

create procedure sp_locktable
@table_name varchar(767),
@lock_timeout int
as

declare @sqlbuf varchar(830)
declare @error_save int
declare @msg varchar(1024)

set nocount on

select @sqlbuf = "lock table " + @table_name + " in exclusive mode wait " + 
		convert (varchar (20), @lock_timeout)
exec (@sqlbuf)
select @error_save = @@error

if (@error_save != 0)
begin
	/*
	** 18811, "Cannot lock table '%1!'."
	*/
	exec sp_getmessage 18811, @msg output
	print @msg, @table_name
	return (@error_save)
end

return (0)
go
exec sp_procxmode 'sp_locktable', 'anymode'
go
grant execute on sp_locktable to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_halocksptables')
begin
	drop procedure sp_halocksptables
end
go
print "Installing sp_halocksptables"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/halocksptables */

/*
** Messages for "sp_halocksptables"
**
** 18813, "HA Internal Error: Do not know how to lock system tables referred by stored procedure '%1!'."
*/

/* 
** SP_HALOCKSPTABLES:
**   Per stored procedure name passed in, sp_halocksptables acquires the locks 
**   on the tables that are updated by the stored procedure.
*/

create procedure sp_halocksptables
@spname varchar(255)	/* name of the stored procedures of which 
			** proxy tables to be locked 
			*/
as

declare @rtn_code int
declare @lock_timeout int
declare @sqlbuf varchar(255)
declare @msg varchar(1024)

set nocount on
select @rtn_code = 0

select @lock_timeout = value from master.dbo.sysconfigures
  where name like 'dtm lock timeout period'

/* the order of getting lock bases on the decrease of table id.
** sysresourcelimits 52
** systimeranges 51
** sysloginroles 49
** syslanguages 44
** sysremotelogins 41
** sysservers 40
** sysmessages 36
** syslogins 33
** sysattributes 21
*/
if (@spname = "sp_addlogin")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_syslogins", 
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back
	
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysattributes",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	select @rtn_code = 0
	goto return_back
end

if (@spname = "sp_droplogin")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysresourcelimits",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysloginroles",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysremotelogins",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_syslogins",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysattributes",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	select @rtn_code = 0
	goto return_back
end

if (@spname = "sp_modifylogin")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysloginroles",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_syslogins",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysattributes",
                                @lock_timeout
	if (@rtn_code != 0)
                goto return_back

        select @rtn_code = 0
        goto return_back
end

if (@spname = "sp_locklogin" or @spname = "sp_defaultlanguage" or 
	@spname = "sp_defaultdb" or @spname = "sp_update_authmech_value")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_syslogins",
				@lock_timeout
	if (@rtn_code != 0)
                goto return_back

        select @rtn_code = 0
        goto return_back
end

if (@spname = "sp_addremotelogin" or @spname = "sp_remoteoption")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysremotelogins",
                                @lock_timeout
        if (@rtn_code != 0)
                goto return_back

        select @rtn_code = 0
        goto return_back
end

if (@spname = "sp_dropremotelogin")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysremotelogins",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysservers",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	select @rtn_code = 0
	goto return_back
end

if (@spname in ("sp_addexternlogin", "sp_dropexternlogin", "sp_maplogin", 
		"sp_logintrigger")) 
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysattributes",
                                @lock_timeout
        if (@rtn_code != 0)
                goto return_back

        select @rtn_code = 0
        goto return_back
end

if (@spname = "sp_addserver" or @spname = "sp_serveroption")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysservers",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	select @rtn_code = 0
	goto return_back
end

if (@spname = "sp_dropserver")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysremotelogins",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysservers",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysattributes",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	select @rtn_code = 0
	goto return_back
end

if (@spname = "sp_addlanguage" or @spname = "sp_setlangalias")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_syslanguages",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	select @rtn_code = 0
	goto return_back
end

if (@spname = "sp_droplanguage")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_syslanguages",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back
	
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysmessages",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	select @rtn_code = 0
	goto return_back
end

if (@spname = "sp_add_resource_limit" or @spname = "sp_drop_resource_limit" or
	@spname = "sp_modify_resource_limit")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysresourcelimits",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	select @rtn_code = 0
	goto return_back
end

if (@spname = "sp_add_time_range" or @spname = "sp_drop_time_range" or
	@spname = "sp_modify_time_range")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_systimeranges",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	select @rtn_code = 0
	goto return_back
end

/*
** sysalternates 11
** sysusers 10
** sysprotects 9
*/

if (@spname = "sp_adduser" or @spname = "sp_addgroup" or 
	@spname = "sp_changegroup")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysusers",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	select @rtn_code = 0
	goto return_back
end

if (@spname = "sp_dropuser")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysattributes",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysalternates",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back
       
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysusers",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysprotects",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back


	select @rtn_code = 0
	goto return_back
end

if (@spname = "sp_dropgroup")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysusers",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysprotects",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

        select @rtn_code = 0
        goto return_back
end

if (@spname = "sp_addalias" or @spname = "sp_dropalias")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_sysalternates",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

	select @rtn_code = 0
	goto return_back
end

if (@spname = "sp_addtype" or @spname = "sp_droptype")
begin
	exec @rtn_code = sp_locktable "master.dbo.rmt_ha_systypes",
				@lock_timeout
	if (@rtn_code != 0)
		goto return_back

        select @rtn_code = 0
        goto return_back
end

/*
** 18813, "HA Internal Error: Do not know how to lock system tables 
** referred by stored procedure '%1!'."
*/
exec sp_getmessage 18813, @msg output
print @msg, @spname
select @rtn_code = 1

return_back:
	return (@rtn_code)
go
exec sp_procxmode 'sp_halocksptables', 'anymode'
go
grant execute on sp_halocksptables to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_halockclustertables')
begin
	drop procedure sp_halockclustertables
end
go
print "Installing sp_halockclustertables"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/halockclustertables */

/*
** Messages for "sp_halockclustertables"
**
** 18812, "HA Internal Error: Cannot acquire locks for stored procedure '%1!' on server '%2!'. Retry later.
*/

/* 
** SP_HALOCKCLUSTERTABLES:
**   Acquires locks on the local server first, then acquires locks
**   on the companion by remote SQL call.
*/
create procedure sp_halockclustertables
@spname varchar(255)	/* name of the stored procedures of which
			** proxy tables to be locked 
			*/
as
declare @rtn_code int
declare @sqlbuf varchar(275)
declare @msg varchar(1024)

select @rtn_code = 0
set nocount on

/* Get table locks on the local server */
exec @rtn_code = sp_halocksptables @spname
if ((@rtn_code != 0) or (@@error != 0) or (@@transtate = 3))
begin
	/*
	** 18812, "HA Internal Error: Cannot acquire locks for 
	** stored procedure '%1!' on server '%2!'. Retry later.
	*/
        exec sp_getmessage 18812, @msg output
        print @msg, @spname, @@servername
	select @rtn_code = 1
	return (@rtn_code)
end

select @sqlbuf = "sp_halocksptables " + @spname
exec @rtn_code = sp_remotesql "SYB_HACMP", @sqlbuf
if (@rtn_code != 0 or @@error != 0 or @@transtate = 3)
begin
	/*
	** 18812, "HA Internal Error: Cannot acquire locks for 
	** stored procedure '%1!' on server '%2!'. Retry later.
	*/
	exec sp_getmessage 18812, @msg output
	print @msg, @spname, @@hacmpservername
	select @rtn_code = 1
	return (@rtn_code)
end

return (0)
go
exec sp_procxmode 'sp_halockclustertables', 'anymode'
go
grant execute on sp_halockclustertables to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_verification')
begin
	drop procedure sp_ha_verification
end
go
print "Installing sp_ha_verification"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	10/15/99	sproc/src/ha_verification */

/* 
** SP_HA_VERIFICATION:
**   Some verification can not be done via proxy tables. We implement it
**   via remote execution of sp_ha_verification through remote rpc.
*/
create procedure sp_ha_verification
@spname varchar(30),	/* name of the stored procedures */
@loginame varchar(30)
as
declare @suid int               /* suid of @loginame */
declare @msg varchar(1024)

if (@spname = "sp_droplogin")
begin
	/* Check sysusers. */
	if valid_user(suser_id(@loginame)) = 1
	begin
		/*
		** 17509, "User exists or is an alias in at least 
		** one database. Drop use r/alias before dropping login."
		*/
		raiserror 17509
		return (1)
	end

	/* Get suid of @loginame */
	select @suid = suid
	  from master.dbo.syslogins
	  where name = @loginame
	if (@suid is NULL)
	begin
		/*
		** 17880, "No such account -- nothing changed."
		*/
		raiserror 17880
		return (1)
	end

	/*
	**  Disallow dropping an account who has already logged in.
	**  Note that it eliminates the race condition between two processes
	**  for checking the last remaining unlocked SSO account.
	*/
	if exists (select * from master.dbo.sysprocesses where suid = @suid)
	begin
		/* 17915, 
		** "Warning: the specified account is currently active."
		*/
		exec sp_getmessage 17915, @msg output
		print @msg
		/*
		** 17918, "Nothing changed."
		*/
		exec sp_getmessage 17918, @msg output
		print @msg

		return (1)
	end
end

return (0)
go
exec sp_procxmode 'sp_ha_verification', 'anymode'
go
grant execute on sp_ha_verification to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_addserver')
begin
	drop procedure sp_addserver
end
go
print "Installing sp_addserver"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/addserver */

/*
** Messages for "sp_addserver"          17290
**
** 17260, "Can't run %1! from within a transaction." 
** 17240, "'" + @lname + "' is not a valid name." 
** 17290, "There is already a server named '%1!', physical name '%2!'."
** 17291, "Usage: sp_addserver servername [, 'local | NULL'] [, physical_name]"
** 17292, "There is already a local server."
** 17293, "Server added."
** 17294, "Changing physical name of server '%1!' from '%2!' to '%3!'"
** 17295, "Adding server '%1!', physical name '%2!'"
** 17296, "Unknown server class '%1!'."
** 17297, "Changing server class of server '%1!' from '%2!' to '%3!'"
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18784, "HA warning:Server is currently configured. Any changes to SYB_HACMP or companion server can be serious."
** 18799, "Unable to find a server with name '%1!', id '%2!', and netname '%3!' in sysservers."
** 18800, "A server with name '%1!' and id '%2!' already exists in sysservers."
** 18820, "You cannot change the physical name of server %1! because it is configured as a node of HA cluster."
** 18881, "Unable to generate %1! for HA use. Please Refer to documentation for details."
** 18887, "Cannot have more than one physical or logical server entry for the 
** ASEJB class."
** 19971, "You cannot change the server class of existing server '%1!' from '%2!' to '%3!'."
** 19972, "Local server must use the cluster name as the server name."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_addserver
@lname	varchar(255),		/* server logical name */
@class	varchar(15) = "ASEnterprise",	/* server class */
@pname	varchar(255) = NULL	/* server physical name */

as
declare	@msg		varchar(1024),
	@netname	varchar(255),
	@dflt_status	smallint,
	@dflt_status2   unsigned int

declare @srvclass	smallint,
	@newclass	smallint,
	@srvid		smallint,
	@remotesrvid	smallint,
	@srvcost	smallint,
	@oldclass	varchar(255),
	@dupsrvclass	smallint,
	@outstr		varchar(255),	/* for SDC dbcc set_scope */
	@scope		varchar(16)	/* for SDC dbcc set_scope */

declare @maxlen		int
declare @end_code	int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int
declare @backupejbflag	int
declare @isrtds		int	/* server class is rtds */
declare @insysattributes int	/* There is row about the changed rtds server in sysattributes */
declare @leavertds	int 	/* server class is changed from rtds to non-rtds */

declare	@bs_name	varchar(255)	/* BS name to be checked in sysservers table */
declare	@bs_flag	int		/* Indicate BS entries in sysservers table */
select @HA_CERTIFIED = 0
select @backupejbflag = 0
select @isrtds = 0
select @insysattributes = 0
select @leavertds = 0


/* Dynamic synchronization related variables declaration and initialization */
declare @str_srvid	varchar(6)
declare @sqlbuf 	varchar(255)
declare @status 	int
declare @nHARSTClass	int
declare @rtn_code	int

select @nHARSTClass = ha_getrestrictionclass("sp_addserver")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_addserver', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_addserver"
	return (1)
end
else
begin
	set chained off
end
set transaction isolation level 1

/* check if user has sso role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/
if (proc_role("sso_role") = 0)
	return (1)


/*
**  Check to see that the @lname is valid.
*/
if (@lname is not null)
begin
	select @maxlen = length from master.dbo.syscolumns
	where id = object_id("master.dbo.sysservers") and name = "srvname"

	if valid_name(@lname, @maxlen) = 0
	begin
		/*
		** 17240, "'" + @lname + "' is not a valid name." 
		*/
		raiserror 17240, @lname
		return (1)
	end
end

/*
**  Check to see that the @lname is valid name.
*/
if (@lname is not null)
begin
	if (@lname = "cluster" or @lname = "CLUSTER")
	begin
		/*
		** 17240, "'" + @lname + "' is not a valid name." 
		*/
		raiserror 17240, @lname
		return (1)
	end
end

/*
** OMNI: See if we have a valid server class. If null, default to 'sql_server'.
*/
if @class is null
	select @class = "ASEnterprise"

select	@newclass = number
from	master.dbo.spt_values
where	type = 'X' and lower(name) = lower(@class)
if @@rowcount = 0
begin
	/*
        ** 17296, "Unknown server class '%1!'" 
        */
	raiserror 17296, @class
	return(1)
end

/*
** to check if the server is a rtds provider
*/
if @newclass in (12, 13, 14, 15)
	select @isrtds = 1
else
	select @isrtds = 0

/*
**  Check to see that the @pname is valid.
*/
if (@pname is NULL)
	select @pname = @lname
else
/*
** If the netname contains a colon, it's ok to use, as it may be in the form:
**
** 	"hostname.domain.com:12345"	or
**	"hostname:12345"		or
**	"255.255.255.255:12345"
**
** which is format for netname now supported by ctlib's CS_SERVERADDR connection 
** property. Note that Omni converts colon to space before calling ct_con_props().
**
** Note, IBM_MQ names (class == 13) don't have colons (:), but they have
** parenthesis (()), so bypass the valid name check.
*/

select @maxlen = length from master.dbo.syscolumns
	where id = object_id("master.dbo.sysservers") and name = "srvnetname"

/*
** If the name is SYB_BACKUP and netname is $dedicated or $roundrobin which is
** Backup server policy to enable Multiple Backup server feature,
** check for all Backup server entries in sysservers table.
*/
if ((@lname = "SYB_BACKUP") and ((lower(@pname) = "$dedicated") or (lower(@pname) = "$roundrobin")))
begin	
	select @bs_flag = 0
	
	declare instancenames cursor for
	select srvname from master..sysservers where srvstatus2 = 4

	open instancenames

	fetch instancenames into @bs_name
	
	while (@@sqlstatus = 0)
	begin
		select @bs_name = @bs_name + "_BS"
		if not exists(select * from master..sysservers where srvname = @bs_name)
		begin
			/*
			** 19968, "Backup Server '%1!' is not configured in sysservers."
			*/
			raiserror 19968, @bs_name
			select @bs_flag = 1
		end	
		fetch instancenames into @bs_name
	end
	close instancenames	

	if (@bs_flag = 1)
	begin
		/*
		** 19969, "Multiple Backup Server in Cluster can not be enabled."
		*/
		raiserror 19969
		return(1)
	end	
end

/*
** If the name is SYB_BACKUP and netname is $dedicated or $roundrobin which is
** Backup server policy to enable Multiple Backup server feature,
** allow the netname as specified keywords skipping valid_name() check.
*/
if (not ((@lname = "SYB_BACKUP") and ((lower(@pname) = "$dedicated") or (lower(@pname) = "$roundrobin"))))
begin	
if charindex(":", @pname) = 0 and valid_name(@pname, @maxlen) = 0 and @newclass != 13
begin
	/*
	** 17240, "'" + @pname + "' is not a valid name." 
	*/
	raiserror 17240, @pname
	return (1)
end
end

/*
** If the server is rtds provider, check if it is registered in sysattributes
*/
if (@isrtds = 1)
	and (exists (select * from master.dbo.sysattributes
			where class = 21 and attribute = 10
				and object_type = 'PR'
				and object_cinfo = @lname))
	select @insysattributes = 1
else
	select @insysattributes = 0

/*
**  Server names must be unique so check.  If a server already exists with
**  this logical _and_ physical name, the server already exists, so there's
**  no work to do.  However, if the logical name exists but the physical
**  names differ, this will be an update to the table to change the physical
**  name.
*/
if exists (select *
		from master.dbo.sysservers
			where srvname = @lname)
begin
	if (@isrtds = 0) or (@insysattributes = 0)
	begin
	 select @srvclass = srvclass,
		@srvid = srvid,
	 	@netname = isnull(srvnetname, @lname)
		from master.dbo.sysservers
			where srvname = @lname
	end
	else
	begin
		select 	@srvclass = int_value,
			@srvid = object,
			@netname = isnull(char_value, @lname)
			from master.dbo.sysattributes
			where class = 21 and attribute = 10
				and object_type = 'PR'
				and object_cinfo = @lname
	end
		
	/*
	** 17290, "There is already a server named '%1!', physical name '%2!'."
	*/
	if (@netname = @pname AND @srvclass = @newclass)
	begin
		raiserror 17290, @lname, @pname
		return (1)
	end

	if (@isrtds = 0) and (@srvclass in (12, 13, 14, 15))
	 	select @leavertds = 1
	else
		select @leavertds = 0


	/*
	** If we are dealing with the DEFAULT servers and the
	** state is > 0, just deal with it locally, else there
	** is no way SA can set NODE specific server attribute
	*/
	if ((@lname = "SYB_BACKUP" or @lname = @@servername or
		@lname = "local" or @lname = @@hacmpservername or
		@lname = "SYB_HACMP" or @class = "ASEJB") and (@@cmpstate > 0))
	select @nHARSTClass = 0

	/*
	** When a HA cluster is not in SSM, the change to network
	** name is disallowed.
	*/
	if ((@lname = "SYB_HACMP" or @lname = @@hacmpservername) and 
		@pname != @netname and @@cmpstate > 0)
	begin
		/*
		** 18820, "You cannot change the physical name of 
		** server %1! because it is configured as a node of HA cluster."
		*/
		exec sp_getmessage 18820, @msg output
		print @msg, @lname
		return (1)
	end	

	if (@nHARSTClass = 1)
	begin
		/* HA consistency checking:
		** We must make sure there is also a server with
		** this name, server id and the same srvnetname on the 
	 	** companion server. 
		*/
		if (not exists (select 1
			from master.dbo.rmt_ha_sysservers where 
				srvname = @lname and
				srvid = @srvid and
				srvnetname = @netname))
			or ((@insysattributes = 1)
				and (not exists (select 1
					from master.dbo.rmt_ha_sysattributes
					where class = 21 and attribute = 10
						and object_type = 'PR'
						and object_cinfo = @lname
						and object = @srvid
						and char_value = @netname)))
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in '%1!' on
			** the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_addserver", @@hacmpservername

			/*
			** 18799, "Unable to find a server with name '%1!',
			** id '%2!', and netname '%3!' in sysservers."
			*/
			exec sp_getmessage 18799, @msg output
			print @msg, @lname, @srvid, @netname
			
			return(1)
		end

		begin tran ha_dynsyn
		exec @rtn_code = sp_halockclustertables "sp_addserver"
		if (@rtn_code != 0)
			goto clean_all
	end


	if (@isrtds = 1) or (@leavertds = 1)
		begin tran rtds_dyn

	if (@leavertds = 1)
	begin
		delete from master.dbo.sysattributes
		where class = 21 and attribute = 10
			and object_type = 'PR' and object_cinfo = @lname
		if (@@error != 0)
			goto clean_all
	end

	if (@isrtds = 1)
	begin
		if (@insysattributes = 1)
			update master.dbo.sysattributes
			set char_value = @pname, int_value = @newclass 
			where class = 21 and attribute = 10
				and object_type = 'PR'
				and object_cinfo = @lname
                else
			insert master.dbo.sysattributes
			(class, attribute, object_type, object_cinfo,
				object, int_value, char_value)
			values (21, 10, 'PR', @lname, @srvid, @newclass,
				@pname)
		if (@@error != 0)
			goto clean_all
	end


	if (@nHARSTClass = 1)
	begin
		if (@leavertds = 1)
		begin
			delete from master.dbo.rmt_ha_sysattributes
			where class = 21 and attribute = 10
				and object_type = 'PR'
				and object_cinfo = @lname
			if (@@error != 0)
				goto clean_all
		end

		if (@isrtds = 1)
		begin
			if (@insysattributes = 1)
				update master.dbo.rmt_ha_sysattributes
				set char_value = @pname, int_value = @newclass 
				where class = 21 and attribute = 10
					and object_type = 'PR'
					and object_cinfo = @lname
			else
				insert into master.dbo.rmt_ha_sysattributes
				(class, attribute, object_type,
					object_cinfo, object,
					int_value, char_value)
				values (21, 10, 'PR', @lname, @srvid,
					@newclass, @pname)
			if (@@error != 0)
				goto clean_all
		end
	end


	/*
	** 17294, "Changing physical name of server '%1!' from '%2!' to '%3!'"
	*/
	if (@netname != @pname)
	begin
		update master.dbo.sysservers
		set srvnetname = @pname
		where srvname = @lname

		if (@@error != 0) 
		begin
			if (@isrtds = 1) or (@leavertds = 1)
				goto clean_all

			goto clean_all

		end


		if (@nHARSTClass = 1)
		begin
			update master.dbo.rmt_ha_sysservers
			set srvnetname = @pname where srvname = @lname
			if (@@error != 0)
				goto clean_all
		end


		/* Suppress the Msg only for SYB_HACMP changes for netname */
		if @lname != "SYB_HACMP"
		begin	
			exec sp_getmessage 17294, @msg output
			print @msg, @lname, @netname, @pname
		end
	end

	/*
	** 17297, Changing server class of server '%1!' from '%2!' to '%3!'
	*/
	if (@srvclass != @newclass)
	begin
		select	@oldclass = name
		from	master.dbo.spt_values
		where	type = 'X' and number = @srvclass
		if @@rowcount = 0
		begin
			select @oldclass = "unknown"
		end

		if lower(@class) = "local"
		begin
			/*
			** 19971, "You cannot change the server class of
			** existing server '%1!' from '%2!' to '%3!'."
			*/
			raiserror 19971, @lname, @oldclass, @class
			return (1)
		end

		update master.dbo.sysservers
			set srvclass = @newclass
			where srvname = @lname

		if (@@error != 0)
		begin
			if (@isrtds = 1) or (@leavertds = 1)
				goto clean_all

			goto clean_all

		end


		if (@nHARSTClass = 1)
		begin
	                update master.dbo.rmt_ha_sysservers
                        set srvclass = @newclass where srvname = @lname
			if (@@error != 0)
				goto clean_all
		end

                exec sp_getmessage 17297, @msg output
		print @msg, @lname, @oldclass, @class
	end

	if (@isrtds = 1) or (@leavertds = 1)
		commit tran rtds_dyn
	/*
	** For SDC, update cluster-wide in-memory SRVDES with data from
	** just-updated SYSSERVERS table. Before dbcc cis, the dbcc
	** command scope needs to be set to cluster.
	*/
	if (@@clustermode = "shared disk cluster")
	begin
		select @scope = NULL
		select @outstr = "dbcc set_scope_in_cluster('scope')"
		if (charindex("instance", @outstr) != 0)
		begin
			/* save the scope to be restored later */
			select @scope = "instance"
			dbcc set_scope_in_cluster('cluster')
		end
	end
	
	dbcc cis ("srvdes", @srvid)

	/* restore dbcc command scope */
	if (@@clustermode = "shared disk cluster")
	begin
		if (@scope = "instance")
		begin
			dbcc set_scope_in_cluster('instance')
		end
	end


	if (@nHARSTClass = 1)
	begin
		/*
		** If this final dbcc cis fails in the remote all 
		** transactions are rolled back; We need not have to
		** redo the local dbcc cis as it merely marked it
		** unusable, so next usage will flush it out.
		*/
		select @str_srvid = convert(char(10), @srvid)
		select @sqlbuf = "dbcc cis ('srvdes', " + @str_srvid + ")"
		exec @status = sp_remotesql "SYB_HACMP", @sqlbuf

		commit tran ha_dynsyn
	end


	return(0)
end

/*
** Check to see that the server class is unique for the EJB class
*/
select @dupsrvclass = srvclass
from   master.dbo.sysservers
where srvclass = 10 and @class = "ASEJB"

if @@rowcount >= 1
begin
	/*
	** 18887, "Cannot have more than one physical or logical server 
	** entry for the ASEJB class."
	*/
	raiserror 18887
        return(1)
end

/* 
** If the server is of the class ASEJB, set the default status to 1024 which
** indicates that the 'external engine auto start option would be enabled
** for such class of servers
*/
if @class = "ASEJB"
begin
	select @dflt_status = number from master.dbo.spt_values
	where type = "A" and name = "external engine auto start"
	select @dflt_status = @dflt_status + number from master.dbo.spt_values
		where type = "A" and name = "no timeouts"
end
else
begin
	/*
	** retrieve the value of the default security setting, namely
	** RPC security model A
	*/
	select @dflt_status = number from master.dbo.spt_values
		where type = "A" and name = "rpc security model A"

	select @dflt_status = @dflt_status + number from master.dbo.spt_values
		where type = "A" and name = "no timeouts"
end

/*
** Default is for non-relocateable joins
*/
select @dflt_status2 = 0

/*
** Default values for srvstatus2 
**
**		OPTION			VALUE	BIT
**		~~~~~~			~~~~~	~~~
**	enable login redirection	ON	0x00000002
**	cluster instance 		OFF	0x00000004
*/
select @dflt_status2 = 2

/*
**  If this is not the local server, then its srvid = max(srvid) + 1.
*/
if lower(@class) != "local"
begin	

	/*
	** 17295, "Adding server '%1!', physical name '%2!'"
	*/
	exec sp_getmessage 17295, @msg output
	print @msg, @lname, @pname




	select @srvid = isnull(max(srvid), 0) + 1
	from master.dbo.sysservers where srvid != 999

	/*
	** Set the default cost for remote servers
	*/
	select @srvcost = 1000
	

	/* HA consistency checking */
	if (@nHARSTClass = 1)
	begin /* { */
		/* 
		** This is a new server entry being added. Make sure that 
		** there are no server entry(s) with same name or srvid 
		** exist on the companion server.
		**
		** Special case for SYB_BACKUP and EJB server. If the remote
		** server already has SYB_BACUP server installed, then try to
		** make sure we can use the same server id. For EJB server, only
		** one EJB server can exist on any installation, so make sure
		** the local installation can use the same ejb server id of
		** the remote installation.
		*/
		if (@class = "ASEJB" OR @lname = "SYB_BACKUP")
		begin
			select @remotesrvid = 0

			/*
			** For EJB server, get the EJB server(srvclass = 10) id
			** from the remote, otherwise, get the server id for
			** this logical name.
			*/
			if (@class = "ASEJB")
			begin
				select @remotesrvid = srvid from
					master.dbo.rmt_ha_sysservers 
					where srvclass = 10
			end
			else 
			begin
				select @remotesrvid = srvid from
					master.dbo.rmt_ha_sysservers 
					where srvname = @lname
			end

			/*
			** Verify in the local server if the server id
			** @remotesrvid obtained from the remote server
			** is available.
			*/
			if ((@remotesrvid != 0) AND
				(exists (select 1 from master.dbo.sysservers
				where srvid = @remotesrvid)))
			begin
				/*
				** 18773, "HA_LOG: HA consistency check 
				** failure in '%1!' on the companion 
				** server '%2!'" because Server id is 
				** not available
				*/
				raiserror 18773, "sp_addserver", @@hacmpservername

				/*
				** RESOLVE: New message.
				** 18882, There is already a server 
				** named '%1!' in sysservers. 
				*/
				exec sp_getmessage 18882, @msg output
				print @msg, @lname

				return(1)
			end 

			/*
			** If we found a remote server id, use it for local
			** installation.
			*/
			if (@remotesrvid != 0)
				select @backupejbflag = 1
		end

		else if (exists (select 1 from master.dbo.rmt_ha_sysservers
			where srvname = @lname))
			or ((@isrtds = 1)
				and (@insysattributes = 1)
				and (exists (select 1
					from master.dbo.rmt_ha_sysattributes
					where class = 21 and attribute = 10
					and object_type = 'PR'
					and object_cinfo = @lname)))
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in 
			** '%1!' on the companion server '%2!'"
			*/
			raiserror 18773, "sp_addserver", @@hacmpservername

			/*
			** 18882, There is already a server named '%1!' in 
			** sysservers.                        
			*/
			exec sp_getmessage 18882, @msg output
			print @msg, @lname

			return(1)
		end

		/* Server ID generation at a cluster level */
		if exists (select 1 from master.dbo.rmt_ha_sysservers 
				where srvid = @srvid)
		begin
			select @srvid = isnull(max(srvid), 0) + 1
			  from master.dbo.rmt_ha_sysservers 
			  where srvid != 999

			if exists (select 1 from master.dbo.sysservers
				where srvid = @srvid)
			begin
				/* 
				** 18881, "Unable to generate %1! for HA use. 
				** Please Refer to documentation for details."
				*/
				raiserror 18881, "server id"
				return (1)
			end
		end

		begin tran ha_dynsyn
		exec @rtn_code = sp_halockclustertables "sp_addserver"
		if (@rtn_code != 0)
			goto clean_all
	end /* } */

if (@isrtds = 1)
	begin tran rtds_dyn
if (@backupejbflag = 1)
begin
	insert into master.dbo.sysservers 
		(srvid, srvstatus, srvname, srvnetname ,srvclass, srvcost, srvstatus2)
		values (@remotesrvid, @dflt_status, @lname, @pname, @newclass, @srvcost, @dflt_status2)
end
else
begin
	insert into master.dbo.sysservers 
		(srvid, srvstatus, srvname, srvnetname ,srvclass, srvcost, srvstatus2)
		values (@srvid, @dflt_status, @lname, @pname, @newclass, @srvcost, @dflt_status2)
	if (@@error != 0)
		goto clean_all
	if (@isrtds = 1)
	begin
		if (@insysattributes = 1)
		begin
			update master.dbo.sysattributes
			set int_value = @newclass, char_value = @pname, 
				object = @srvid
			where class = 21 and attribute = 10
				and object_type = 'PR'
				and object_cinfo = @lname
		end
		else
		begin
			insert master.dbo.sysattributes
			(class, attribute, object_type, object_cinfo,
				object, int_value, char_value)
			values (21, 10, 'PR', @lname, @srvid, @newclass, @pname)
		end
		if (@@error !=0 )
			goto clean_all
		commit tran rtds_dyn
	end
end


	if (@@error !=0 )
		goto clean_all

	if (@nHARSTClass = 1)
	begin
		if (@backupejbflag = 1)
		begin
			if not exists (select 1 from 
					master.dbo.rmt_ha_sysservers 
					where srvid = @remotesrvid)
			begin
				insert into master.dbo.rmt_ha_sysservers
				(srvid, srvstatus, srvname, srvnetname, srvclass, srvcost, srvstatus2)
				values (@remotesrvid, @dflt_status, @lname, 
						@pname, @newclass, @srvcost, @dflt_status2)
			end
		end
		else
		begin
			insert into master.dbo.rmt_ha_sysservers
			(srvid, srvstatus, srvname, srvnetname, srvclass, srvcost, srvstatus2)
			values (@srvid, @dflt_status, @lname, @pname, @newclass, 
						@srvcost, @dflt_status2)
			if (@isrtds = 1)
			begin
				if (@@error != 0)
					goto clean_all
				if (@insysattributes = 1)
				begin
					update master.dbo.sysattributes
					set int_value = @newclass,
						char_value = @pname,
						object = @srvid
					where class = 21 and attribute = 10
						and object_type = 'PR'
						and object_cinfo = @lname
				end
				else
				begin
					insert master.dbo.rmt_ha_sysattributes
					(class, attribute, object_type, 
						object_cinfo, object, int_value,
						char_value)
					values (21, 10, 'PR', @lname, @srvid,
						@newclass, @pname)
					
				end
			end
		end

		if (@@error != 0)
			goto clean_all

		commit tran ha_dynsyn
        end

	

end

/*
**  If @class = "local" then this is the local server and it's
**  srvid = 0.

**  We don't need to do synchronisation for "local" server,
**  because we suppose that it has already been added before 
**  HA configuration

*/
else
begin
	if lower(@class) != "local"
	begin
		/*
		** 17291, "Usage: sp_addserver servername [, 'local | NULL'],
		**	   [, physical_name]"
		*/
		raiserror 17291
		return (1)
	end

	if exists (select *
			from master.dbo.sysservers
				where srvid = 0)
	begin
		/*
		** 17292, "There is already a local server."
		*/
		raiserror 17292
		return (1)
	end

	if (@@clustermode = "shared disk cluster")
	begin
		if @lname != @@clustername
		begin
			/*
			** 19972, "Local server must use the cluster name as the server name."
			*/
			raiserror 19972
			return (1)
		end
	end

	/*
	** 17295, "Adding server '%1!', physical name '%2!'"
	*/
	exec sp_getmessage 17295, @msg output
	print @msg, @lname, @pname



	insert into master.dbo.sysservers 
		(srvid, srvstatus, srvname, srvnetname, srvclass, srvcost, srvstatus2)
			values (0, @dflt_status, @lname, @pname, 0, 0, @dflt_status2)

end

/*
** 17293, "Server added."
*/
exec sp_getmessage 17293, @msg output
print @msg
return (0)


clean_all:
	if (@isrtds = 1) or (@leavertds = 1)
		rollback tran rtds_dyn

	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn

	return(1)
go
exec sp_procxmode 'sp_addserver', 'anymode'
go
grant execute on sp_addserver to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_addlanguage')
begin
	drop procedure sp_addlanguage
end
go
print "Installing sp_addlanguage"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/addlanguage */

/*
** Messages for "sp_addlanguage"        17250
**
** 17240, "'%1!' is not a valid name."
** 17250, "'%1!' already exists in Syslanguages."
** 17251, "'%1!' is not a valid date order."
** 17252, "'%1!' is not a valid first day."
** 17253, "'%1!' alias already exists in Syslanguages."
** 17254, "Language not inserted."
** 17255, "New language inserted."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18774, "Languange name '%1!', alias '%2!', and/or language id '% 3!' already exists in Syslanguages."
** 18881, "Unable to generate %1! for HA use. Please Refer to documentation for details."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_addlanguage 
@language varchar(255),
@alias varchar(255) = NULL,
@months varchar(251),
@shortmons varchar(119),
@days varchar(216),
@datefmt char(3),
@datefirst tinyint
as

declare @msg varchar(1024)
declare @nextlangid smallint
declare @returncode	int 
declare @convdate char(3)
declare @maxlen int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @rtn_code int

select @nHARSTClass = ha_getrestrictionclass("sp_addlanguage")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_addlanguage', @HA_CERTIFIED
if (@retstat != 0)
        return (1)


/*
** NOTE:
** We should check here to see if we're in a transaction, and return
** with a 17260 error ("Can't run %1! from within a transaction.") if
** we are in a transaction.  However, the langinstall utility currently
** calls sp_addlanguage from within a transaction.  Until this behavior
** is changed we'll allow ourselves to be called from within a xact.
*/

/* 
** check if user has sa role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/

if (proc_role("sa_role") = 0)
	return (1)


/* Check to see if the language name is valid */
if (@language is not null)
begin
	select @maxlen = length from master.dbo.syscolumns
	where id = object_id("master.dbo.syslanguages") and name = "name"

	if (char_length(@language) > @maxlen) 
	begin
		/*
		** 17240, "'%1!' is not a valid name."
		*/
		raiserror 17240, @language
		return 1
	end
end

/*  Check to see if the language exists. */
select @returncode = 0
execute @returncode = sp_validlang @language
if @returncode = 0
begin
	/*
	**  17250, "'%1!' already exists in Syslanguages."
	*/
	raiserror 17250, @language
	return 1
end

/* Check to see that the list of full month names is valid. */
execute @returncode = sp_chklangparam @months, "full month", 12, 20
if @returncode != 0
	return 1

/* Check to see that the list of short month names is valid. */
execute @returncode = sp_chklangparam @shortmons, "short month", 12, 9
if @returncode != 0
	return 1

/* Check to see that the list of day names is valid. */
execute @returncode = sp_chklangparam @days, "day", 7, 30
if @returncode != 0
	return 1

/* Check to see that the @datefmt is valid. */
if (@datefmt != 'mdy' and @datefmt != 'dmy' and @datefmt != 'ymd' and @datefmt != 'ydm'
	and @datefmt != 'myd' and @datefmt != 'dym')
begin
	/*
	** 17251, "'%1!' is not a valid date order."
	*/
	raiserror 17251, @datefmt
	return 1
end

/*
**  Check to see that the @datefirst is valid.
*/
if (@datefirst < 1 or @datefirst > 7)
begin
	/*
	** 17252, "'%1!' is not a valid first day."
	*/
	select @convdate = convert(char(3), @datefirst)
	raiserror 17252, @convdate
	return 1
end

/* Check if @alias is valid */
if (@alias is not null)
begin
	select @maxlen = length from master.dbo.syscolumns
	where id = object_id("master.dbo.syslanguages") and name = "alias"

	if (char_length(@alias) > @maxlen) 
	begin
		/*
		** 17240, "'%1!' is not a valid name."
		*/
		raiserror 17240, @alias
		return 1
	end
end

/*
**  If the user didn't specify the alias name, the alias name is same as 
**  the official name.
*/
if @alias is null
begin
	select @alias =  @language
end

		
		
/*  Check to see if the alias exists. */
select @returncode = 0
execute @returncode = sp_validaltlang @alias
if @returncode = 0
begin

	/*
	** 17253, "'%1!' alias already exists in Syslanguages."
	*/
	raiserror 17253, @alias
	return 1
end

if @language = 'us_english'
begin
	

	if (@nHARSTClass = 1)
	begin
		/* HA consistency checking */

		/* Make sure there is no entry in syslanguages on the 
		** companion server which has same name, id, or alias
		*/
		if exists (select 1 from master.dbo.rmt_ha_syslanguages
			where name = @language OR alias = @alias OR langid = 0)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in 
			** stored procedure '%1!' on the companion 
			** server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_addlanguage", @@hacmpservername

			/*
			** 18774, "Languange name '%1!', alias '%2!', or 
			** language id '% 3!' already exists in syslanguages."
			*/
			exec sp_getmessage 18774, @language, @alias, 0

			return (1)
		end

		begin tran ha_dynsyn
		exec @rtn_code = sp_halockclustertables "sp_addlanguage"
		if (@rtn_code != 0)
			goto clean_all

	end



	/*  The language id of us_english is 0. */
	insert master.dbo.syslanguages (langid, dateformat, datefirst, upgrade, 
		name, alias, months, shortmonths, days)
	select 0, @datefmt, @datefirst, 0, 
		@language, @alias, @months, @shortmons, @days
end
else
begin
	/* 
	** Attention:
	** 	if this ID generating algorithm is changed, please 
	**	change the corresponding part in HA section too.
	*/
	if (select max(langid) from master.dbo.syslanguages) is null
	begin
		select @nextlangid = 1
	end
	else
	begin
		select @nextlangid = (select max(langid)+1 
		from master.dbo.syslanguages)
	end



	if (@nHARSTClass = 1)
	begin
		/* HA consistency checking */

		/* Make sure there is no entry in syslanguages on the 
		** companion server which has same name, id, or alias
		*/
		if exists (select 1 from master.dbo.rmt_ha_syslanguages
			where name = @language OR alias = @alias)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in 
			** stored procedure '%1!' on the companion server '%2!'"
			*/
			raiserror 18773, "sp_addlanguage", @@hacmpservername

			/*
			** 18774, "Languange name '%1!' or alias '%2!' 
			** already exists in Syslanguages."
			*/
			exec sp_getmessage 18774, @msg
			print @msg, @language, @alias
			
			return (1)
		end

		/* Calculate an ID which both servers agree on */
		if exists (select 1 from master.dbo.rmt_ha_syslanguages
				where langid = @nextlangid)
		begin
			if (select max(langid) 
				from master.dbo.rmt_ha_syslanguages) is null
			begin
				select @nextlangid = 1
			end
			else
			begin
				select @nextlangid = (select max(langid)+1
					from master.dbo.rmt_ha_syslanguages)
			end
			if exists (select 1 from master.dbo.syslanguages
					where langid = @nextlangid)
			begin
				/* 
				** 18881, "Unable to generate %1! for HA use. 
				** Please Refer to documentation for details."
				*/
				raiserror 18881, "language id"
				return (1)
			end
		end	


		begin tran ha_dynsyn
                exec @rtn_code = sp_halockclustertables "sp_addlanguage"
                if (@rtn_code != 0)
                        goto clean_all
	end


	insert master.dbo.syslanguages (langid, dateformat, datefirst, upgrade, 
		name, alias, months, shortmonths, days)
	     select @nextlangid, @datefmt, @datefirst, 0, 
		@language, @alias, @months, @shortmons, @days
end


/* If the insert failed, say so. */
if @@error != 0
begin
	/*
	** 17254, "Language not inserted."
	*/
	raiserror 17254
	goto clean_all
end


if (@nHARSTClass = 1)
begin
	if @language = 'us_english'
	begin
		/*  The language id of us_english is 0. */
		insert master.dbo.rmt_ha_syslanguages (langid, dateformat, 
			datefirst, upgrade, name, alias, months, 
			shortmonths, days)
		     select 0, @datefmt, @datefirst, 0, 
			@language, @alias, @months, @shortmons, @days
	end
	else
	begin
		insert master.dbo.rmt_ha_syslanguages (
			langid, dateformat, datefirst, upgrade, 
			name, alias, months, shortmonths, days)
		     select @nextlangid, @datefmt, @datefirst, 0, 
			@language, @alias, @months, @shortmons, @days
	end

	if (@@error != 0)
		goto clean_all

	commit tran ha_dynsyn
end


/*
** 17255, "New language inserted."
*/
exec sp_getmessage 17255, @msg output
print @msg
return (0)

clean_all:


	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn


	return (1)
    
go
exec sp_procxmode 'sp_addlanguage', 'anymode'
go
grant execute on sp_addlanguage to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_droplanguage')
begin
	drop procedure sp_droplanguage
end
go
print "Installing sp_droplanguage"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/defaultlanguage */

/*
** Messages for "sp_droplanguage"       17505
**
** 17201, "'%1!' is not an official language name from Syslanguages." 
** 17260, "Can't run %1! from within a transaction."
** 17505, "Can't drop '%1!' because there are associated entries in master.dbo.sysmessages.  Run sp_droplanguage with the 'dropmessages' flag."
** 17506, "The only legal value for @dropmessages is 'dropmessages'."
** 17507, "Language deleted."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '% 1!' on the companion server '%2!'"
** 18775, "Unable to find a language entry with language name '%1!' and language id '%2!'"
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_droplanguage 
@language varchar(30),
@dropmessages varchar(30) = NULL
as

declare @msg varchar(1024)
declare @langid smallint
declare @dropmsgs int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @error_save int
declare @rtn_code int

select @rtn_code = 0
select @error_save = 0
select @nHARSTClass = ha_getrestrictionclass("sp_droplanguage")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_droplanguage', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
begin
	/* 17260, "Can't run %1! from within a transaction." */
	raiserror 17260, "sp_locklogin"
	return (1)
end
else
begin
	set chained off
end

set transaction isolation level 1

/* check if user has sa role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/

if (proc_role("sa_role") = 0)
	return (1)

/*  Check to see if the language exists. */
declare @returncode	int 
select @returncode = 0
execute @returncode = sp_validlang @language
if @returncode != 0
begin
	/*
	** 17201, "'%1!' is not an official language name from Syslanguages." 
	*/
	raiserror 17201, @language
	return 1
end

/* Get language id from syslanguages. */
select @langid = (select langid 
			from master.dbo.syslanguages 
				where name = @language)

/*  Check to see if "dropmessages" is requested. */
select @dropmsgs = 0
if @dropmessages is null
begin
	if exists (select * from master.dbo.sysmessages 
			where langid = @langid)
	begin
		/* 
		**  Cannot drop a language if the language has associated
		**  entries in the master.dbo.sysmessages.
		*/

		/*
		** 17505, "Can't drop '%1!' because there are associated entries in master.dbo.sysmessages.  Run sp_droplanguage with the 'dropmessages' flag."
		*/
		raiserror 17505, @language
		return 1
	end
end
else
begin
	if @dropmessages != "dropmessages"
	begin
		/*
		** 17506, "The only legal value for @dropmessages is 'dropmessages'."
		*/
		raiserror 17506
		return 1
	end

	select @dropmsgs = 1
end


if (@nHARSTClass = 1)
begin
	/* 
	** HA consistency checking 
	*/
	/* Verify the mapping of langid and langname on the remote server. */
	if not exists (select 1 from master.dbo.rmt_ha_syslanguages
		where langid = @langid and name = @language)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in 
		** stored procedure '%1!' on the companion server '%2!'"
		*/
		raiserror 18773, "sp_droplanguage", @@hacmpservername

		/*
		** 18775, "Unable to find a language entry with 
		** language name '%1!' and language id '%2!'"
		*/
		exec sp_getmessage 18775, @msg output
		print @msg, @language, @langid

		return (1)
	end

	/*  Is "dropmessages" requested? */
	if (@dropmessages is null)
	begin
		if exists (select 1 from master.dbo.rmt_ha_sysmessages
			     where langid = @langid)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in
			** stored procedure '%1!' on the companion server '%2!'"
			*/
			raiserror 18773, "sp_droplanguage", @@hacmpservername

			/*
			** 17505, "Can't drop '%1!' because there are 
			** associated entries in master.dbo.sysmessages.  
			** Run sp_droplanguage with the 'dropmessages' flag."
			*/
			exec sp_getmessage 17505, @msg output
			print @msg, @language

			return (1)
		end
	end

	begin tran ha_dynsyn
	exec @rtn_code = sp_halockclustertables "sp_droplanguage"
	if (@rtn_code != 0)
		goto clean_all
end


/* 
**  Drop the language and delete messages from Sysmessages if there is any.
*/
if @dropmsgs = 1
begin
	delete master.dbo.sysmessages
		where langid = @langid


	if (@@error != 0)
		goto clean_all

	if (@nHARSTClass = 1)
	begin
		delete master.dbo.rmt_ha_sysmessages
			where langid = @langid
		if (@@error != 0)
			goto clean_all
	end


end

delete master.dbo.syslanguages 
	where langid = @langid


if (@@error != 0)
	goto clean_all

if (@nHARSTClass = 1)
begin
	delete master.dbo.rmt_ha_syslanguages
		where langid = @langid

	if (@@error != 0)
		goto clean_all

	commit tran ha_dynsyn
end


/*
** 17507, "Language deleted."
*/
exec sp_getmessage 17507, @msg output
print @msg
return (0)

clean_all:


if (@nHARSTClass = 1)
	rollback tran ha_dynsyn

	return (1)
go
exec sp_procxmode 'sp_droplanguage', 'anymode'
go
grant execute on sp_droplanguage to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_add_resource_limit')
begin
	drop procedure sp_add_resource_limit
end
go
print "Installing sp_add_resource_limit"
go

/* Sccsid = "%Z% generic/sproc/%M% %I% %G%" */

/*
** Messages for "sp_add_resource_limit"
**
** 17231, "No login with the specified name exists."
** 17240, "'%1!' is not a valid name."
** 17260, "Can't run %1! from within a transaction."
** 17261, "Only the System Administrator (SA) may execute this procedure."
** 18182, "Timerange name must be non-NULL."
** 18199, "Unknown time range name '%1!'."
** 18202, "At least one of the login or application name must be non-NULL."
** 18203, "Limit type must be non-NULL.
** 18204, "Unknown limit type '%1!'."
** 18205, "Limit value must be non-NULL."
** 18206, "Illegal limit value %1!. Value must be non-negative."
** 18207, "Illegal action %1!."
** 18208, "Illegal enforcement-time value %1! for this limit type."
** 18209, "Illegal scope value %1! for this limit type."
** 18210, "Unknown starting time value '%1!' found in systime ranges."
** 18211, "Unknown ending time value '%1!' found in systimeranges."
** 18212, "New limit would cause overlap with limits on range %1! for this user-application combination."
** 18213, "This user/application can have only one limit for each distinct combination of time range, limit type, enforcement time and scope."
** 18214, "New resource limit created."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on companion server '%2!'"
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins.
** 18779, "Unable to find the time range '%1!' with id '%2!' in systimeranges.
** 18781, "Unable to find a limit type with name '%1!' and id '%2!'."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_add_resource_limit
@name		varchar(255),	/* login to which limit applies */
@appname	varchar(255),	/* application to which limit applies */
@rangename	varchar(255),	/* timerange during limit applied */
@limittype	varchar(30),	/* what's being limited */
@limitvalue	int,		/* upper-bound value of limit */
@enforced	int = NULL,	/* before or during execution */
@action		int = 2,	/* what to do if limit is violated */
@scope		int = NULL	/* scope of limit */
as

declare	@limitid	smallint
declare	@rangeid	smallint
declare	@current_range	int
declare	@enforced_arg	int
declare	@action_arg	int
declare	@scope_arg	int
declare	@msg		varchar(1024)
declare	@start_dt	datetime
declare	@end_dt		datetime
declare	@cur_start_dt	datetime
declare	@cur_end_dt	datetime
declare	@startdaynum	int
declare	@enddaynum	int
declare	@cur_startdaynum	int
declare	@cur_enddaynum	int
declare @tmp_starttime	varchar(30)
declare @tmp_endtime	varchar(30)
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0


if (proc_role("sa_role") = 0)
begin
	/*
	** 17261, "Only the System Administrator (SA) may execute this procedure."
	*/
	raiserror 17261
	return (1)
end


/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @sqlbuf varchar(255)
declare @suid int
declare @rtn_code int

select @nHARSTClass = ha_getrestrictionclass("sp_add_resource_limit")
if (@nHARSTClass = -1) return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_add_resource_limit', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_add_resource_limit"
	return (1)
end

if ( (@name is null) and (@appname is null) )
begin
	/*
	** 18202, "At least one of the login or application name must be non-NULL."
	*/
	raiserror 18202
	return (1)
end

/* Is login valid? */
if ( (@name is not null) and not exists
	(select * from master.dbo.syslogins where name = @name) )
begin
	/*
	** 17231, "No login with the specified name exists."
	*/
	raiserror 17231
	return(1)
end

/* Has a legal range been specified? */

select @rangename = rtrim(@rangename)

if (@rangename is null)
begin
	/*
	** 18182, "Timerange name must be non-NULL."
	*/
	raiserror 18182
	return(1)
end
else if not exists
	(select * from master.dbo.systimeranges where name = @rangename)
begin
	/*
	** 18199, "Unknown time range name '%1!'."
	*/
	raiserror 18199, @rangename
	return(1)
end

/* Has a legal limit type been specified? */
if (@limittype is null)
begin
	/*
	** 18203, "Limit type must be non-NULL.
	*/
	raiserror 18203
	return(1)
end
else if not exists
	(select * from master.dbo.spt_limit_types where name = @limittype)
begin
	/*
	** 18204, "Unknown limit type '%1!'."
	*/
	raiserror 18204, @limittype
	return(1)
end

/* Has a limit value been specified? */
if (@limitvalue is null)
begin
	/*
	** 18205, "Limit value must be non-NULL."
	*/
	raiserror 18205
	return(1)
end
else if (@limitvalue <= 0)
begin
	/*
	** 18206, "Illegal limit value %1!. Value must be non-negative."
	*/
	raiserror 18206, @limitvalue
	return(1)
end

/* Has a legal action been specified? */
/* If NULL, the default (batch abort) is taken */
if (@action is null)
begin
	select @action_arg = 2
end
else if ( (@action < 1) or (@action > 4) )
begin
	/*
	** 18207, "Illegal action %1!."
	*/
	raiserror 18207, @action
	return(1)
end
else
begin
	select @action_arg = @action
end

/* Has a legal enforcement time been specified? */
if (@enforced is NULL)
begin
	select @enforced_arg = enforced from master.dbo.spt_limit_types where name = @limittype
end
else if (((@enforced & (select enforced from master.dbo.spt_limit_types where name = @limittype)) != @enforced) or (@enforced = 0))
begin
	/*
	** 18208, "Illegal enforcement-time value %1! for this limit type."
	*/
	raiserror 18208, @enforced
	return(1)
end
else
begin
	select @enforced_arg = @enforced
end

/* Has a legal scope been specified? */
if (@scope is NULL)
begin
	select @scope_arg = scope from master.dbo.spt_limit_types where name = @limittype
end
else if (((@scope & (select scope from master.dbo.spt_limit_types where name = @limittype)) != @scope) or (@scope = 0))
begin
	/*
	** 18209, "Illegal scope value %1! for this limit type."
	*/
	raiserror 18209, @scope
	return(1)
end
else
begin
	select @scope_arg = @scope
end

/* Get the id# corresponding to the limit */
select @limitid = id from master.dbo.spt_limit_types where name = @limittype

/* Get the id# corresponding to the timerange */
select @rangeid = id from master.dbo.systimeranges
	where name = @rangename

/* Get the starting time for the range used by this limit */
select @tmp_starttime = starttime from master.dbo.systimeranges
	where id = @rangeid

/* Get the ending time for the range used by this limit */
select @tmp_endtime = endtime from master.dbo.systimeranges
	where id = @rangeid

/* Get the starting day for the range used by this limit */
select @startdaynum = startday from master.dbo.systimeranges
	where name = @rangename

/* Get the ending day for the range used by this limit */
select @enddaynum = endday from master.dbo.systimeranges
	where name = @rangename

/* Convert the starting time to datetime so we can do arithmetic */
select @start_dt = convert(datetime, @tmp_starttime)
if (@start_dt is null)
begin
	/*
	** 18210, "Unknown starting time value '%1!' found in systimeranges."
	*/
	raiserror 18210, @tmp_starttime
	return(1)
end

/* Convert the ending time to datetime so we can do arithmetic */
select @end_dt = convert(datetime, @tmp_endtime)
if (@end_dt is null)
begin
	/*
	** 18211, "Unknown ending time value '%1!' found in systimeranges."
	*/
	raiserror 18211, @tmp_endtime
	return(1)
end

/* Cursor result: ranges associated with limits currently imposed 
** upon the given user/application
*/
declare c1 cursor for 
	select distinct rangeid from master.dbo.sysresourcelimits
	where ( (name = @name) and (appname = @appname) ) or 
	( (name = @name) and (@appname is null) ) or
	( (name = @name) and (appname is null) ) or 
	( (name is null) and (appname = @appname) ) or 
	( (@name is null) and (appname = @appname) )

open c1

fetch c1 into @current_range

/* We need to peruse the cursor results to see if this new
** limit overlaps with another limit for this user/application.
*/
while (@@sqlstatus != 2)
begin

	if (@current_range != @rangeid)
	begin

		/* Get the start and end days for current range */
		select @cur_startdaynum = startday from 
			master.dbo.systimeranges
			where id = @current_range
		select @cur_enddaynum = endday from 
			master.dbo.systimeranges
			where id = @current_range

		/* Get the start and end times for current range */
		select @tmp_starttime = starttime from 
			master.dbo.systimeranges
			where id = @current_range
		select @tmp_endtime = endtime from 
			master.dbo.systimeranges
			where id = @current_range
		select @cur_start_dt = convert(datetime, @tmp_starttime)
		select @cur_end_dt = convert(datetime, @tmp_endtime)

		/* See if the limit overlaps with any other
		** limit defined for this user/application
		** (excepting limits defined for the exact
		** same timerange).
		*/

		/* This is the non-wrapping case, for starttime.
		** If (the current range doesn't wrap around the
		** end of the week)
		** and
		** (the days of the new limit's range
		** overlap with the current range)
		** and 
		** (the starttime of the new limit's range is after
		** the starttime of the current range)
		** and 
		** (the endtime of the new limit's range is before
		** the endtime of the current range, with 00:00
		** being taken as midnight)
		** then we have an overlap, so raise an error
		** and return.
		*/
		if 
		(@cur_startdaynum <= @cur_enddaynum) 
		and 
		(((@startdaynum >= @cur_startdaynum) and
		  (@startdaynum <= @cur_enddaynum)) or
		 ((@enddaynum >= @cur_startdaynum) and
		  (@enddaynum <= @cur_enddaynum)) or
		 ((@startdaynum <= @cur_startdaynum) and
		  (@enddaynum >= @cur_enddaynum)))
		and
		(@start_dt >= @cur_start_dt) 
		and 
		((@start_dt < @cur_end_dt) or
		 ((datepart(hour, @cur_end_dt) = 0) and
		  (datepart(minute, @cur_end_dt) = 0) and
		  (datepart(second, @cur_end_dt) = 0)))
		begin
			/*
			** 18212, "New limit would cause overlap with limits on range %1! for this user-application combination."
			*/
			raiserror 18212, @current_range
			return(1)
		end

		/* This is the wrapping case, for starttime.
		*/
		if
		(@cur_startdaynum > @cur_enddaynum) 
		and
		((@startdaynum >= @cur_startdaynum) or
		 (@startdaynum <= @cur_enddaynum) or
		 (@enddaynum >= @cur_startdaynum) or
		 (@enddaynum <= @cur_enddaynum) or
		 ((@startdaynum > @enddaynum) and
		  (@startdaynum <= @cur_startdaynum) and
		  (@enddaynum >= @cur_enddaynum))) 
		and
		(@start_dt >= @cur_start_dt) 
		and 
		((@start_dt < @cur_end_dt) or
		 ((datepart(hour, @cur_end_dt) = 0) and
		  (datepart(minute, @cur_end_dt) = 0) and
		  (datepart(second, @cur_end_dt) = 0)))
		begin
			/*
			** 18212, "New limit would cause overlap with limits on range %1! for this user-application combination."
			*/
			raiserror 18212, @current_range
			return(1)
		end
			
		/* This is the non-wrapping case, for endtime.
		** If (the current range doesn't wrap around the
		** end of the week)
		** and
		** (the days of the new limit's range
		** overlap with the current range)
		** and 
		** (the endtime of the new limit's range is before
		** the endtime of the current range, with 00:00
		** being taken as midnight)
		** and 
		** (the endtime of the new limit's range is after
		** the starttime of the current range)
		** then we have an overlap, so raise an error
		** and return.
		*/
		if 
		(@cur_startdaynum <= @cur_enddaynum) 
		and 
		(((@startdaynum >= @cur_startdaynum) and
		  (@startdaynum <= @cur_enddaynum)) or
		 ((@enddaynum >= @cur_startdaynum) and
		  (@enddaynum <= @cur_enddaynum)) or
		 ((@startdaynum <= @cur_startdaynum) and
		  (@enddaynum >= @cur_enddaynum)))
		and
		((@end_dt <= @cur_end_dt) or 
		 ((datepart(hour, @cur_end_dt) = 0) and
		  (datepart(minute, @cur_end_dt) = 0) and
		  (datepart(second, @cur_end_dt) = 0)))
		and 
		(@end_dt > @cur_start_dt)
		begin
			/*
			** 18212, "New limit would cause overlap with limits on range %1! for this user-application combination."
			*/
			raiserror 18212, @current_range
			return(1)
		end

		/* This is the wrapping case, for endtime.
		*/
		if 
		(@cur_startdaynum > @cur_enddaynum) 
		and
		((@startdaynum >= @cur_startdaynum) or
		 (@startdaynum <= @cur_enddaynum) or
		 (@enddaynum >= @cur_startdaynum) or
		 (@enddaynum <= @cur_enddaynum) or
		 ((@startdaynum > @enddaynum) and
		  (@startdaynum <= @cur_startdaynum) and
		  (@enddaynum >= @cur_enddaynum))) 
		and
		((@end_dt <= @cur_end_dt) or 
		 ((datepart(hour, @cur_end_dt) = 0) and
		  (datepart(minute, @cur_end_dt) = 0) and
		  (datepart(second, @cur_end_dt) = 0)))
		and 
		(@end_dt > @cur_start_dt)
		begin
			/*
			** 18212, "New limit would cause overlap with limits on range %1! for this user-application combination."
			*/
			raiserror 18212, @current_range
			return(1)
		end

		/* This is the non-wrapping case, where
		** the limit's timerange completely
		** covers the current range.
		*/
		if
		(@cur_startdaynum <= @cur_enddaynum) 
		and
		(((@startdaynum >= @cur_startdaynum) and
		  (@startdaynum <= @cur_enddaynum)) or
		 ((@enddaynum >= @cur_startdaynum) and
		  (@enddaynum <= @cur_enddaynum)) or
		 ((@startdaynum <= @cur_startdaynum) and
		  (@enddaynum >= @cur_enddaynum)))
		and
		(@start_dt < @cur_start_dt) 
		and 
		( ((@end_dt > @cur_end_dt) and
		  ((datepart(hour, @cur_end_dt) != 0) or
		   (datepart(minute, @cur_end_dt) != 0) or
		   (datepart(second, @cur_end_dt) != 0)))
		  or
		  ((datepart(hour, @end_dt) = 0) and
		   (datepart(minute, @end_dt) = 0) and
		   (datepart(second, @end_dt) = 0)) )
		begin
			/*
			** 18212, "New limit would cause overlap with limits on range %1! for this user-application combination."
			*/
			raiserror 18212, @current_range
			return(1)
		end
			
		/* This is the wrapping case, where
		** the limit's timerange completely
		** covers the current range.
		*/
		if
		(@cur_startdaynum > @cur_enddaynum) 
		and
		((@startdaynum >= @cur_startdaynum) or
		 (@startdaynum <= @cur_enddaynum) or
		 (@enddaynum >= @cur_startdaynum) or
		 (@enddaynum <= @cur_enddaynum) or
		 ((@startdaynum > @enddaynum) and
		  (@startdaynum <= @cur_startdaynum) and
		  (@enddaynum >= @cur_enddaynum))) 
		and
		(@start_dt < @cur_start_dt) 
		and 
		( ((@end_dt > @cur_end_dt) and
		  ((datepart(hour, @cur_end_dt) != 0) or
		   (datepart(minute, @cur_end_dt) != 0) or
		   (datepart(second, @cur_end_dt) != 0)))
		  or
		  ((datepart(hour, @end_dt) = 0) and
		   (datepart(minute, @end_dt) = 0) and
		   (datepart(second, @end_dt) = 0)) )
		begin
			/*
			** 18212, "New limit would cause overlap with limits on range %1! for this user-application combination."
			*/
			raiserror 18212, @current_range
			return(1)
		end
			
	end

	fetch c1 into @current_range
end

/* Make sure we're not adding a duplicate */
if exists (select * from master.dbo.sysresourcelimits
	where 
	/*
	(
	   ((name = @name) and
	    (appname = @appname)) or
	   ((name = @name) and
	    (@appname is null)) or
	   ((@name is null) and
	    (appname = @appname))
	)
	*/
	name = @name
	and appname = @appname

	and rangeid = @rangeid 
	and limitid = @limitid
	and ((enforced & @enforced_arg) != 0)
	and ((scope & @scope_arg) != 0) )
begin
	/*
	** 18213, "This user/application can have only one limit for each distinct combination of time range, limit type, enforcement time and scope."
	*/
	raiserror 18213
	return(1)
end


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */

	/* Login name and id */
	if (@name is not null)
	begin  
		select @suid = suid from master.dbo.syslogins
		  where @name = name

		if not exists (select 1 from master.dbo.rmt_ha_syslogins 
				where name = @name and @suid = suid) 
		begin
		
			/*
			** 18773, "HA_LOG: HA consistency check failure in 
			** stored procedure '%1!' on companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_add_resource_limit", @@hacmpservername
			
			/*
			** 18778, "Unable to find login '%1!' with id '%2!'
			** in syslogins.
			*/
			exec sp_getmessage 18778, @msg output
			print @msg, @name, @suid

			return (1)
		end
	end

	/* Has a legal range been specified? */
	if not exists (select 1 from master.dbo.rmt_ha_systimeranges 
			where name = @rangename and id = @rangeid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check fail in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_add_resource_limit", @@hacmpservername
	
		/*
		** 18779, "Unable to find the time range '%1!' with id '%2!' 
		** in systimeranges.
		*/
		exec sp_getmessage 18779, @msg output
		print @msg, @rangename, @rangeid

		return(1)
	end

	/* Has a legal limit type been specified? */
	if not exists (select 1 from master.dbo.rmt_ha_spt_limit_types 
			where name = @limittype and id = @limitid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check fail in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_add_resource_limit", @@hacmpservername

		/*
		** 18781, "Unable to find a limit type with name '%1!' 
		** and id '%2!'."
		*/
		exec sp_getmessage 18781, @msg output
		print @msg, @limittype, @limitid

		return(1)
	end

	begin tran ha_dynsyn
	exec @rtn_code = sp_halockclustertables "sp_add_resource_limit"
	if (@rtn_code != 0)
		goto clean_all

end

/* Insert! */
insert master.dbo.sysresourcelimits values(@name, @appname, @rangeid, @limitid, @enforced_arg, @action_arg, @limitvalue, @scope_arg, 0)


if (@@error != 0) goto clean_all

if (@nHARSTClass = 1)
begin
	insert master.dbo.rmt_ha_sysresourcelimits 
		values(@name, @appname, @rangeid, @limitid, @enforced_arg, 
			@action_arg, @limitvalue, @scope_arg, 0)
	if (@@error != 0)
		goto clean_all

	select @sqlbuf = "dbcc recachelimits"
 	exec sp_remotesql "SYB_HACMP", @sqlbuf

	commit tran ha_dynsyn
end


dbcc recachelimits

/*
** 18214, "New resource limit created."
*/
exec sp_getmessage 18214, @msg output
print @msg

/*
** Okay, so we know that the limit has been added ...
** but are resource limits enabled?
*/

declare @rg_status int
select @rg_status = s.value from
	master.dbo.syscurconfigs s,
	master.dbo.sysconfigures sc
	where sc.config = s.config 
	and sc.name = "allow resource limits"
if (@rg_status = 0)
begin
/*
** 19373, "WARNING: This limit will not take effect until resource limits
** are enabled for this server. Use sp_configure 'allow resource limits', 1.
*/
	exec sp_getmessage 19373, @msg output
	print @msg
end

return(0)

clean_all:

	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn

        return (1)

go
exec sp_procxmode 'sp_add_resource_limit', 'anymode'
go
grant execute on sp_add_resource_limit to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_drop_resource_limit')
begin
	drop procedure sp_drop_resource_limit
end
go
print "Installing sp_drop_resource_limit"
go

/* Sccsid = "%Z% generic/sproc/%M% %I% %G%" */

/*
** Messages for "sp_drop_resource_limit"
**
** 17231, "No login with the specified name exists."
** 17260, "Can't run %1! from within a transaction."
** 17261, "Only the System Administrator (SA) may execute this procedure."
** 18199, "Unknown time range name '%1!'."
** 18202, "At least one of the login or application name must be non-NULL."
** 18204, "Unknown limit type '%1!'."
** 18207, "Illegal action %1!."
** 18209, "Illegal scope value %1! for this limit type."
** 18215, "Resource limit dropped."
** 18220, "No such limit found in sysresourcelimits."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on companion server '%2!'"
** 18776, "Please also run stored procedure '%1!' on the companion server '%2!'."
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins."
** 18779, "Unable to find the time range '%1!' with id '%2!' in systimeranges.
** 18781, "Unable to find a limit type with name '%1!' and id '%2!'."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_drop_resource_limit
@name		varchar(255),	/* login to which limit applies */
@appname	varchar(255),	/* application to which limit applies */
@rangename	varchar(255) = NULL,	/* timerange to which limit applies */
@limittype	varchar(255) = NULL,	/* what's being limited */
@enforced	int = NULL,		/* before or during execution */
@action		int = NULL,		/* what to do upon violation */
@scope		int = NULL		/* scope of limit */
as

declare	@limitid	smallint
declare	@rangeid	smallint
declare	@msg		varchar(1024)
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0


if (proc_role("sa_role") = 0)
begin
	/*
	** 17261, "Only the System Administrator (SA) may execute this procedure."
	*/
	raiserror 17261
	return (1)
end


/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @sqlbuf varchar(255)
declare @suid int
declare @rtn_code int

select @nHARSTClass = ha_getrestrictionclass("sp_drop_resource_limit")
if (@nHARSTClass = -1)
	return (1)
if (@nHARSTClass = 1)
begin
	/*
	** 18776, "Please also run stored procedure '%1!' on the 
	** companion server '%2!'.
	*/
	exec sp_getmessage 18776, @msg output
	print @msg, "sp_drop_resource_limit", @@hacmpservername
        select @nHARSTClass = 0
end
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_drop_resource_limit', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_drop_resource_limit"
	return (1)
end

if ( (@name is null) and (@appname is null) )
begin
	/*
	** 18202, "At least one of the login or application name must be non-NULL."
	*/
	raiserror 18202
	return (1)
end

/* If a user name was specified, make sure it's legal */
if ( (@name is not null) and not exists
	(select * from master.dbo.syslogins where name = @name) )
begin
	/*
	** 17231, "No login with the specified name exists."
	*/
	raiserror 17231
	return(1)
end

/* If a range name was specified, make sure it's legal */

select @rangename = rtrim(@rangename)

if ( (@rangename is not null) and not exists
	(select * from master.dbo.systimeranges where name = @rangename) )
begin
	/*
	** 18199, "Unknown time range name '%1!'."
	*/
	raiserror 18199, @rangename
	return(1)
end

/* If a limit type was specified, make sure it's legal */
if ( (@limittype is not null) and not exists
	(select * from master.dbo.spt_limit_types where name = @limittype) )
begin
	/*
	** 18204, "Unknown limit type '%1!'."
	*/
	raiserror 18204, @limittype
	return(1)
end

/* If an enforcement time was specified, make sure it's legal */
if ( (@enforced is not null) and (@limittype is not null) and 
     ((@enforced & (select enforced from master.dbo.spt_limit_types 
                    where name = @limittype)) != @enforced) )
begin
	/*
	** 18208, "Illegal enforcement-time value %1! for this limit type."
	*/
	raiserror 18208, @enforced
	return(1)
end

/* If an action was specified, make sure it's legal */
if ( (@action is not null) and ((@action < 1) or (@action > 4)) )
begin
	/*
	** 18207, "Illegal action %1!."
	*/
	raiserror 18207, @action
	return(1)
end

/* If a scope was specified, make sure it's legal */
if ( (@scope is not null) and (@limittype is not null) and 
     ((@scope & (select scope from master.dbo.spt_limit_types 
                 where name = @limittype)) != @scope) )
begin
	/*
	** 18209, "Illegal scope value %1! for this limit type."
	*/
	raiserror 18209, @scope
	return(1)
end

select @limitid = id from master.dbo.spt_limit_types where name = @limittype

select @rangeid = id from master.dbo.systimeranges where name = @rangename

/* Print a message (but still return successfully) if
** there was no such limit to drop.
*/
if ( (select count(*) from master.dbo.sysresourcelimits where
	( (((name = @name) and
	    (appname = @appname)) or
	   ((name = @name) and
	    (@appname is null)) or
	   ((@name is null) and
	    (appname = @appname))) and
	  ((@rangename is null) or (rangeid = @rangeid)) and 
	  ((@limittype is null) or (limitid = @limitid)) and 
	  ((@enforced is null) or ((enforced & @enforced) != 0)) and 
	  ((@action is null) or (action = @action)) and 
	  ((@scope is null) or ((scope & @scope) != 0)) )
     ) = 0 )
begin
	/*
	** 18220, "No such limit found in sysresourcelimits."
	*/
	exec sp_getmessage 18220, @msg output
	print @msg
	return(0)
end


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */

	/* Login name and id */
	if (@name is not null)
	begin  
		select @suid = suid from master.dbo.syslogins
		where @name = name

		if not exists (select 1 from master.dbo.rmt_ha_syslogins 
				where name = @name and @suid = suid) 
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure 
			** in stored procedure '%1!' on companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_drop_resource_limit", @@hacmpservername
			
			/*
			** 18778, "Unable to find login '%1!' with id '%2!' 
			** in syslogins."
			*/
			exec sp_getmessage 18778, @msg output
			print @msg, @name, @suid

			return (1)
		end
	end

	/* Has a legal range been specified? */
	if ((@rangename is not null) and 
		not exists (select * from master.dbo.rmt_ha_systimeranges 
			where name = @rangename and id = @rangeid))
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_drop_resource_limit", @@hacmpservername
	
		/*
		** 18779, "Unable to find the time range '%1!' with id '%2!' 
		** in systimeranges.
		*/
		exec sp_getmessage 18779, @msg output
		print @msg, @rangename, @rangeid

		return(1)
	end

	/* Has a legal limit type been specified? */
	if ((@limittype is not null) and
		not exists (select * from master.dbo.rmt_ha_spt_limit_types 
			where name = @limittype and id = @limitid))
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_drop_resource_limit", @@hacmpservername

		/*
		** 18781, "Unable to find a limit type with name '%1!' 
		** and id '%2!'."
		*/
		exec sp_getmessage 18781, @msg output
		print @msg, @limittype, @limitid

		return(1)
	end

	begin tran ha_dynsyn
	exec @rtn_code = sp_halockclustertables "sp_drop_resource_limit"
	if (@rtn_code != 0)
		goto clean_all
end


/* Delete! */
delete from  master.dbo.sysresourcelimits where
	( (((name = @name) and
	    (appname = @appname)) or
	   ((name = @name) and
	    (@appname is null)) or
	   ((@name is null) and
	    (appname = @appname))) and
	  ((@rangename is null) or (rangeid = @rangeid)) and 
	  ((@limittype is null) or (limitid = @limitid)) and 
	  ((@enforced is null) or ((enforced & @enforced) != 0)) and 
	  ((@action is null) or (action = @action)) and 
	  ((@scope is null) or ((scope & @scope) != 0)) )


if (@@error != 0)
	goto clean_all

if (@nHARSTClass = 1)
begin
	/* Delete! */
	delete from  master.dbo.rmt_ha_sysresourcelimits where
		( (((name = @name) and
		    (appname = @appname)) or
		   ((name = @name) and
		    (@appname is null)) or
		   ((@name is null) and
		    (appname = @appname))) and
		   ((@rangename is null) or (rangeid = @rangeid)) and
		   ((@limittype is null) or (limitid = @limitid)) and
		   ((@enforced is null) or ((enforced & @enforced) != 0)) and
		   ((@action is null) or (action = @action)) and
		   ((@scope is null) or ((scope & @scope) != 0)) )

	if (@@error != 0) 
		goto clean_all
		
	select @sqlbuf = "dbcc recachelimits"
	exec sp_remotesql "SYB_HACMP", @sqlbuf

	commit tran ha_dynsyn
end


dbcc recachelimits

/*
** 18215, "Resource limit dropped."
*/
exec sp_getmessage 18215, @msg output
print @msg

return(0)

clean_all:

        if (@nHARSTClass = 1)
		rollback tran ha_dynsyn

        return (1)
go
exec sp_procxmode 'sp_drop_resource_limit', 'anymode'
go
grant execute on sp_drop_resource_limit to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_modify_resource_limit')
begin
	drop procedure sp_modify_resource_limit
end
go
print "Installing sp_modify_resource_limit"
go

/* Sccsid = "%Z% generic/sproc/%M% %I% %G%" */

/*
** Messages for "sp_modify_resource_limit"
**
** 17231, "No login with the specified name exists."
** 17260, "Can't run %1! from within a transaction."
** 17261, "Only the System Administrator (SA) may execute this procedure."
** 18182, "Timerange name must be non-NULL."
** 18199, "Unknown time range name '%1!'."
** 18202, "At least one of the login or application name must be non-NULL."
** 18203, "Limit type must be non-NULL."
** 18204, "Unknown limit type '%1!'."
** 18206, "Illegal limit value %1!. Value must be non-negative."
** 18207, "Illegal action %1!."
** 18208, "Illegal enforcement-time value %1! for this limit type."
** 18209, "Illegal scope value %1! for this limit type."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18776, "Please also run stored procedure '%1!' on the companion server '%2!'."
** 18779, "Unable to find the time range '%1!' with id '%2!' in systimeranges."
** 18781, "Unable to find a limit type with name '%1!' and id '%2!'."
** 
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_modify_resource_limit
@name		varchar(255),	/* login to which limit applies */
@appname	varchar(255),	/* application to which limit applies */
@rangename	varchar(255),	/* range during which limit is enforced */
@limittype	varchar(30),	/* what's being limited */
@limitvalue	int = NULL,	/* upper-bound value for limit */
@enforced	int,		/* before or during execution */
@action		int = NULL,	/* what to do if limit is violated */
@scope		int		/* scope of limit */
as

declare	@limitid	smallint
declare	@rangeid	smallint
declare	@enforced_arg	int
declare	@scope_arg	int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @sqlbuf varchar(255)
declare @login_id int
declare @msg varchar(1024)
declare @rtn_code int


select @nHARSTClass = ha_getrestrictionclass("sp_modify_resource_limit")
if (@nHARSTClass = -1)
        return (1)
if (@nHARSTClass = 1)
begin
	/*
	** 18776, "Please also run stored procedure '%1!' on the 
	** companion server '%2!'.
	*/
	exec sp_getmessage 18776, @msg output
	print @msg, "sp_modify_resource_limit", @@hacmpservername
	select @nHARSTClass = 0
end
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_modify_resource_limit', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if (proc_role("sa_role") = 0)
begin
	/*
	** 17261, "Only the System Administrator (SA) may execute this procedure."
	*/
	raiserror 17261
	return (1)
end

if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_modify_resource_limit"
	return (1)
end

if ( (@name is null) and (@appname is null) )
begin
	/*
	** 18202, "At least one of the login or application name must be non-NULL."
	*/
	raiserror 18202
	return (1)
end

/* Was a valid user name specified? */
if ( (@name is not null) and not exists
	(select * from master.dbo.syslogins where name = @name) )
begin
	/*
	** 17231, "No login with the specified name exists."
	*/
	raiserror 17231
	return (1)
end

/* Was a valid range name specified? */

select @rangename = rtrim(@rangename)

if (@rangename is null)
begin
	/*
	** 18182, "Timerange name must be non-NULL."
	*/
	raiserror 18182
	return(1)
end
else if not exists
	(select * from master.dbo.systimeranges where name = @rangename)
begin
	/*
	** 18199, "Unknown time range name '%1!'."
	*/
	raiserror 18199, @rangename
	return(1)
end

/* Was a valid limit type specified? */
if (@limittype is null)
begin
	/*
	** 18203, "Limit type must be non-NULL."
	*/
	raiserror 18203
	return(1)
end
else if not exists
	(select * from master.dbo.spt_limit_types where name = @limittype)
begin
	/*
	** 18204, "Unknown limit type '%1!'."
	*/
	raiserror 18204, @limittype
	return(1)
end

/* Was a valid limit value specified? */
if ( (@limitvalue is not null) and (@limitvalue <= 0) )
begin
	/*
	** 18206, "Illegal limit value %1!. Value must be non-negative."
	*/
	raiserror 18206, @limitvalue
	return(1)
end

/* Was a valid action specified? */
if ( (@action is not null) and ((@action < 1) or (@action > 4)) )
begin
	/*
	** 18207, "Illegal action %1!."
	*/
	raiserror 18207, @action
	return(1)
end

/* Was a valid enforcement time specified? */
if (@enforced is null)
begin
	select @enforced_arg = enforced from master.dbo.spt_limit_types where name = @limittype
end
else if (((@enforced & (select enforced from master.dbo.spt_limit_types where name = @limittype)) != @enforced) or (@enforced = 0))
begin
	/*
	** 18208, "Illegal enforcement-time value %1! for this limit type."
	*/
	raiserror 18208, @enforced
	return(1)
end
else
	select @enforced_arg = @enforced

/* Was a valid scope specified? */
if (@scope is NULL)
begin
	select @scope_arg = scope from master.dbo.spt_limit_types where name = @limittype
end
else if (((@scope & (select scope from master.dbo.spt_limit_types where name = @limittype)) != @scope) or (@scope = 0))
begin
	/*
	** 18209, "Illegal scope value %1! for this limit type."
	*/
	raiserror 18209, @scope
	return(1)
end
else
	select @scope_arg = @scope

select @limitid = id from master.dbo.spt_limit_types where name = @limittype

select @rangeid = id from master.dbo.systimeranges where name = @rangename

if (select count(*) from master.dbo.sysresourcelimits
	where 
	( (((name = @name) and
	    (appname = @appname)) or
	   ((name = @name) and
	    (@appname is null)) or
	   ((@name is null) and
	    (appname = @appname))) and
	  (rangeid = @rangeid) and
	  (limitid = @limitid) and
	  (enforced = @enforced_arg) and
	  (scope = @scope_arg) )
    ) = 0
begin
	/*
	** 18220, "No such limit found in sysresourcelimits."
	*/
	raiserror 18220
	return(1)
end


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */

	/* Login name and id */
	if (@name is not null)
	begin  
		select @login_id = suid from master.dbo.syslogins
		where @name = name

		if not exists (select * from master.dbo.rmt_ha_syslogins 
		where name = @name and @login_id = suid) 
		begin
		
			/*
			** 18773, "HA_LOG: HA consistency check failure in stored
			** procedure '%1!' on companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_modify_resource_limit", @@hacmpservername
			
			/*
			** 18778, "Unable to find login '%1!' with id '%2!' 
			** in syslogins."
			*/
			exec sp_getmessage 18778, @msg output
			print @msg, @name, @login_id

			return (1)
		end
	end

	/* Has a legal range been specified? */
	if not exists (select * from master.dbo.rmt_ha_systimeranges 
			where name = @rangename and id = @rangeid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_modify_resource_limit", @@hacmpservername
	
		/*
		** 18779, "Unable to find the time range '%1!' with id '%2!' 
		** in systimeranges."
		*/
		exec sp_getmessage 18779, @msg output
		print @msg, @rangename, @rangeid

		return(1)
	end

	/* Has a legal limit type been specified? */
	if not exists (select * from master.dbo.rmt_ha_spt_limit_types 
			where name = @limittype and id = @limitid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_modify_resource_limit", @@hacmpservername

		/*
		** 18781, "Unable to find a limit type with name '%1!' and 
		** id '%2!'." 
		*/
		exec sp_getmessage 18781, @msg output
		print @msg, @limittype, @limitid

		return(1)
	end

	begin tran ha_dynsyn
	exec @rtn_code = sp_halockclustertables "sp_modify_resource_limit"
	if (@rtn_code != 0)
		goto clean_all
end


/* Modify the limit value */
if (@limitvalue is not null)
begin
update master.dbo.sysresourcelimits 
	set limitvalue = @limitvalue
		where 
		( (((name = @name) and
	   	    (appname = @appname)) or
	  	   ((name = @name) and
	  	    (@appname is null)) or
	   	   ((@name is null) and
	   	    (appname = @appname))) and
		  (rangeid = @rangeid) and
		  (limitid = @limitid) and
		  (enforced = @enforced_arg) and
		  (scope = @scope_arg) )

	if (@@error != 0)
		goto clean_all

	if (@nHARSTClass = 1)
	begin
		update master.dbo.rmt_ha_sysresourcelimits
		  set limitvalue = @limitvalue
                  where
                    ( (((name = @name) and
                      (appname = @appname)) or
                     ((name = @name) and
                      (@appname is null)) or
                     ((@name is null) and
                      (appname = @appname))) and
                    (rangeid = @rangeid) and
                    (limitid = @limitid) and
                    (enforced = @enforced_arg) and
                    (scope = @scope_arg) )

		if (@@error != 0)
			goto clean_all
	end


end

/* Modify the action */
if (@action is not null)
begin
update master.dbo.sysresourcelimits 
	set action = @action
		where 
		( (((name = @name) and
	   	    (appname = @appname)) or
	  	   ((name = @name) and
	  	    (@appname is null)) or
	   	   ((@name is null) and
	   	    (appname = @appname))) and
		  (rangeid = @rangeid) and
		  (limitid = @limitid) and
		  (enforced = @enforced_arg) and
		  (scope = @scope_arg) )

	if (@@error != 0)
		goto clean_all

	if (@nHARSTClass = 1)
	begin
		update master.dbo.rmt_ha_sysresourcelimits
		  set action = @action
                  where
                  ( (((name = @name) and
                    (appname = @appname)) or
                   ((name = @name) and
                    (@appname is null)) or
                   ((@name is null) and
                    (appname = @appname))) and
                  (rangeid = @rangeid) and
                  (limitid = @limitid) and
                  (enforced = @enforced_arg) and
                  (scope = @scope_arg) )

		if (@@error != 0)
			goto clean_all
	end


end

dbcc recachelimits


if (@nHARSTClass = 1)
begin
	select @sqlbuf = "dbcc recachelimits"
	exec sp_remotesql "SYB_HACMP", @sqlbuf

	commit tran ha_dynsyn
end


return(0)

clean_all:


	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn


	return (1)

go
exec sp_procxmode 'sp_modify_resource_limit', 'anymode'
go
grant execute on sp_modify_resource_limit to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_setlangalias')
begin
	drop procedure sp_setlangalias
end
go
print "Installing sp_setlangalias"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/serveroption */

/*
** Messages for "sp_setlangalias"       17810
**
** 17201, "'%1!' is not an official language name from Syslanguages."
** 17240, "'" + @alias + "' is not a valid name." 
** 17260, "Can't run %1! from within a transaction."
** 17253, "'%1!' alias already exists in Syslanguages."
** 17810, "Language alias not changed."
** 17811, "Language alias reset."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on companion server '%2!'"
** 18775, "Unable to find a language entry with language name '%1!' and language id '%2!'."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_setlangalias 
@language varchar(255),
@alias varchar(255)
as

declare @msg varchar(1024)

declare @returncode	int 
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int
declare @maxlen	  	int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @lang_id smallint
declare @rtn_code int

select @nHARSTClass = ha_getrestrictionclass("sp_setlangalias")
if (@nHARSTClass = -1)
        return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_setlangalias', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
**  Check to see that the @alias is valid.
*/
select @maxlen = length from syscolumns
	where id = object_id("syslanguages") and name = "alias"

if (char_length(@alias) > @maxlen)
begin
     	/*
        ** 17240, "'" + @alias + "' is not a valid name."
	*/
        raiserror 17240, @alias
	return (1)
end

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
begin
        /*
        ** 17260, "Can't run %1! from within a transaction."
        */
	raiserror 17260, "sp_setlangalias"
        return (1)
end
else
begin
	set chained off
end

set transaction isolation level 1

/* check if user has sa role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/

if (proc_role("sa_role") = 0)
	return (1)

/*  Check to see if the language exists. */
select @returncode = 0
execute @returncode = sp_validlang @language
if @returncode != 0
begin
	/*
	** 17201, "'%1!' is not an official language name from Syslanguages."
	*/
	raiserror 17201, @language
	return 1
end

/*  Check to see if the alias exists. */
select @returncode = 0
execute @returncode = sp_validaltlang @alias
if @returncode = 0
begin
	/*
	** 17253, "'%1!' alias already exists in Syslanguages."
	*/
	raiserror 17253, @alias
	return 1
end


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */

	/*  Check to see if the language exists. */
	select @lang_id = langid from master.dbo.syslanguages
	where name = @language
	if not exists (select 1 from master.dbo.rmt_ha_syslanguages
			where name = @language and langid = @lang_id)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_setlangalias", @@hacmpservername
	
		/*
	        ** 18775, "Unable to find a language entry with 
		** language name '%1!' and language id '%2!'."
		*/
		raiserror 18775, @language, @lang_id

		return 1
	end

	/*  Check to see if the alias exists. */
	if exists (select 1 from master.dbo.rmt_ha_syslanguages
			where alias = @alias)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_setlangalias", @@hacmpservername

		/*
		** 17253, "'%1!' alias already exists in Syslanguages."
		*/
		raiserror 17253, @alias

		return 1
	end

	begin tran ha_dynsyn
	exec @rtn_code = sp_halockclustertables "sp_setlangalias"
	if (@rtn_code != 0)
		goto clean_all
end


/* Reset the alternate language name. */
update master.dbo.syslanguages 
	set alias = @alias
		where name = @language

/* If the update failed, say so. */
if (@@error != 0)
begin
	/*
	** 17810, "Language alias not changed."
	*/
	raiserror 17810
	goto clean_all
end


if (@nHARSTClass = 1)
begin
	update master.dbo.rmt_ha_syslanguages
	set alias = @alias
	where name = @language
	
	if (@@error != 0)
		goto clean_all

	commit tran ha_dynsyn
end


/*
** 17811, "Language alias reset."
*/
exec sp_getmessage 17811, @msg output
print @msg
return (0)

clean_all:

	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn

	return (1)

go
exec sp_procxmode 'sp_setlangalias', 'anymode'
go
grant execute on sp_setlangalias to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_locklogin')
begin
	drop procedure sp_locklogin
end
go
print "Installing sp_locklogin"
go

/* Sccsid = "%Z% generic/sproc/%M% %I% %G%" */
/*	5.0	1.0	10/22/91	sproc/src/locklogin */

/*
** Generated by spgenmsgs.pl on Thu Feb  2 00:39:17 2006 
*/
/*
** raiserror Messages for locklogin [Total 3]
**
** 17756, "The execution of the stored procedure '%1!' in database '%2!' was aborted because there was an error in writing the replication log record."
** 18388, "You must be in the master database in order to run '%1!'."
** 18409, "The built-in function '%1!' failed. Please see the other messages printed along with this message."
** 19606, "To lock inactive accounts, you must run 
** 	    'sp_passwordpolicy 'set','enable last login updates',1'."
** 19607, "You cannot specify both 'inactive_days' and 'unlock' at the same time."
*/
/*
** sp_getmessage Messages for locklogin [Total 16]
**
** 17260, "Can't run %1! from within a transaction."
** 17880, "No such account -- nothing changed."
** 17912, "Error in locking the account."
** 17913, "Locked account(s):"
** 17914, "Account unlocked."
** 17917, "Error: locktype must either be 'lock' or 'unlock'."
** 17918, "Nothing changed."
** 17919, "Account locked."
** 18419, "Account 'sybmail' cannot be unlocked."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on the companion server '%2!'."
** 19390, "One or more accounts do not exist on the companion server."
** 19391, "Warning: One or more accounts specified are active."
** 19392, "Permission Denied. The current account is already locked."
** 19393, "The sets of sa/sso logins on the primary and companion servers are not same."
** 19394, "The set of logins specified is empty."
** 19395, "The login or role to be excluded from locking/unlocking is invalid."
** 19444, "The range for %1! is %2! to %3!."
** 19643, "No account(s) locked."
*/
/*
** End spgenmsgs.pl output.
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_locklogin
@loginame varchar(30) = NULL,		/* name of the login to be locked */
@locktype varchar(30) = NULL,		/* "locked" or "unlock"            */
@except	  varchar(30) = NULL,		/* login/role to be exempted	*/
@inactive_days int    = NULL            /* no of inactive days of a login */
as
declare @suid int			/* suid of login to be modified   */
declare @msg	varchar(1024)		/* message text */
declare @dummy int
declare @HA_CERTIFIED tinyint   	/* Is the SP HA certified ? */
declare @retstat  int
declare @current_id int			/* suid of the current login */
declare @except_is_login tinyint	/* flag to indicate if exception is login/role */ 
declare @except_is_role  tinyint
declare @encompasses_all_logins tinyint 
declare @warning_active	tinyint
declare @row_count_temp	int
declare @encompasses_all_rmt_ha_logins tinyint
declare @temp_current_id int
declare @current_date datetime
declare @scope varchar(32)		/* SDC command execution scope */

select @HA_CERTIFIED = 0
select @except_is_login = 0
select @except_is_role = 0
select @encompasses_all_logins = 1
select @encompasses_all_rmt_ha_logins = 1
select @warning_active = 0
select @row_count_temp = 0
select @current_date = getdate()


/* Dynamic synchronization related variables declaration and initialization */
declare @suid_hacmp	int
declare @nHARSTClass    int
declare @rtn_code int
declare @unlocksuid	int
declare @has_srole	int


declare @log_for_rep int
declare @db_rep_level_all int
declare @db_rep_level_none int
declare @db_rep_level_l1 int
declare @lt_rep_get_failed int

/*
** Initialize some constants
*/
select @db_rep_level_all = -1,
       @db_rep_level_none = 0,
       @db_rep_level_l1 = 1,
       @lt_rep_get_failed = -2


select @nHARSTClass = ha_getrestrictionclass("sp_locklogin")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_locklogin', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/* create a dummy table to store temporary rows */
create table #dummy_table(suid int)

/*
** Do not allow this system procedure to be run from within a transaction
** to avoid creating a multi-database transaction where the 'master'
** database is not the co-ordinating database.
*/
if @@trancount > 0
begin
	/* 17260, "Can't run %1! from within a transaction." */
	exec sp_getmessage 17260, @msg output
	print @msg, "sp_locklogin"
	return (1)
end
else
begin
	set chained off
end

set transaction isolation level 1

/*
** Get the replication status of the 'master' database
*/
select @log_for_rep = getdbrepstat(1) 
if (@log_for_rep = @lt_rep_get_failed)
begin
	raiserror 18409, "getdbrepstat"
	return (1)
end

/*
** Convert the replication status to a boolean
*/
if (@log_for_rep != @db_rep_level_none)
	select @log_for_rep = 1
else
	select @log_for_rep = 0

/*
** If we are logging this system procedure for replication, we must be in
** the 'master' database to avoid creating a multi-database transaction
** which could make recovery of the 'master' database impossible.
*/
if (@log_for_rep = 1) and (db_name() != "master")
begin
	raiserror 18388, "sp_locklogin"
	return (1)
end



/*
** Check if user has sso role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/

if (proc_role("sso_role") = 0)
	return (1)


if @loginame is NULL and @locktype is NULL
begin
	/*
	** 17913, "Locked account(s):"
	*/
	exec sp_getmessage 17913, @msg output
	print @msg
	select name
	from master.dbo.syslogins
	where ((status & 2) = 2) /* LOGIN_LOCKED */
	return (0)
end

if (@loginame is not NULL)
begin 
	/*  Check if any such account exists */

	if not exists (select suid 
			from master.dbo.syslogins 
			where name like @loginame)
	begin
		/*
		** 17880, "No such account -- nothing changed."
		*/
		exec sp_getmessage 17880, @msg output
		print @msg
		return (1)
	end

end 


if ((@locktype != "unlock") and (@locktype != "lock"))
begin
	/*
	** 17917, "Error: locktype must either be 'lock' or 'unlock'."
	*/
	exec sp_getmessage 17917, @msg output
	print @msg
	/*
	** 17918, "Nothing changed."
	*/
	exec sp_getmessage 17918, @msg output
	print @msg
	return (1)
end

/* 
** Check if the exception specified is a login or a role 
** and set the variable @except_is_login accordingly
*/

if (@except is not NULL)
begin
	if exists (select 1 from master.dbo.syslogins 
			where name = @except)
	begin
		/* @except is a login  */

		select @except_is_login = 1 
	end

	/* Check if @except is a valid role */
	if exists (select 1 from master.dbo.sysloginroles as srole,
			 	 master.dbo.syssrvroles as rolename
			where srole.srid = rolename.srid
			and rolename.name = @except)
	begin
		select @except_is_role = 1
	end

	if (@except_is_login = 0) and (@except_is_role = 0)
	begin
		/* 19395, The login or role to be excluded from locking/unlocking is invalid */
		exec sp_getmessage 19395, @msg output
		print @msg
		return (1)
	end
end

/*
** Check if the user specified "effectively NULL" set of logins
** to be locked/unlocked. If so, return doing nothing
** For instance the user might have specified same set of logins
** to be locked as the set to be exempted.
*/

if (@loginame is not NULL) and
	 (((@except_is_login = 1) and 
		(not exists (select suid from master.dbo.syslogins
				where name like @loginame
				and name != @except))) or
   	   ((@except_is_role = 1) and 
		(not exists (select suid from master.dbo.syslogins
				where name like @loginame and
			      	suid not in
				(select suid from master.dbo.sysloginroles 
				      	where srid = role_id(@except))))) ) 
begin

	/* 19394, "The set of logins specified is empty." */
	exec sp_getmessage 19394, @msg output
	print @msg

	return (1)
end



if (@nHARSTClass = 1)
begin
	/* 
	** HA consistency checking
	** suid-based check and name-based check. 
	** Check if logins(name-wise and suid-wise) to be locked/unlocked
	** in syslogins is present in companion server
	*/

	if exists (select sys.suid from master.dbo.syslogins sys
			where sys.name like @loginame and
			      not exists (select 1 from master.dbo.rmt_ha_syslogins
						where sys.suid = suid and
						      sys.name = name) ) 	
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_locklogin", @@hacmpservername

		/*
		** 19390, "One or more accounts do not exist on the remote 
		** HA server." 
		*/
		exec sp_getmessage 19390, @msg output
		print @msg
		
		return (1)
	end
end



if @locktype = "unlock"
begin

	/* 'Sybmail' account cannot be unlocked */
	if (@loginame = "sybmail")
	begin
		/*
		** 18419, "Account 'sybmail' cannot be unlocked."
		*/
		exec sp_getmessage 18419, @msg output
		print @msg
		return (1)
	end
	
	/* '@inactive_days' and 'unlock' cannot be specified at the same time */
	if (@inactive_days != NULL)
	begin
		/*
		** 19607, "You cannot specify both
		** 'inactive_days' and 'unlock' at the same time."
		*/	
		exec sp_getmessage 19607, @msg output
		print @msg
		return (1)
	end

	/* Unlock any existing account */

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		begin tran rs_logexec


if (@nHARSTClass = 1)
begin
	exec @rtn_code = sp_halockclustertables "sp_locklogin"
	if (@rtn_code != 0)
		goto clean_all
end


	if (@loginame is NULL)
	begin
		if (@except_is_login = 1)	
		begin
			/*
			** Unlock logins except ones which match @except
			**
			** The columns lockdate, lockreason, locksuid are
			** reset with values NULL, NULL, NULL whenever
			** a login account is unlocked.
			**
			** The columns lockdate, lockreason and locksuid
			** are set to context specific values when an account
			** is locked. The values reflect the datetime,
			** reason code, and the suid of the login
			** that is locking the account.
			**
			** Changes to these columns should be recorded
			** in the audit trail, and will do so in a future 
			** ASE release when locking is done outside of 
			** stored procedure.
			*/
			update master.dbo.syslogins 
			set status = status & (~2),
			logincount = 0,
			lockdate = NULL,
			lockreason = NULL,
			locksuid = NULL
			where name != @except
		end
		else 
		if (@except_is_role = 1)
		begin
			/* 
			** @except is a role 
			** Unlock all logins except ones whose role matches
			** @except
			*/

			update master.dbo.syslogins 
			set status = status & (~2),
			logincount = 0,
			lockdate = NULL,
                        lockreason = NULL,
                        locksuid = NULL
                        where suid not in
				(select suid from master.dbo.sysloginroles
                              		where srid = role_id(@except))
		end
		else
		begin
			/* @except is NULL */
			update master.dbo.syslogins
			set status = status & (~2),
			logincount = 0,
			lockdate = NULL,
                        lockreason = NULL,
                        locksuid = NULL
		end
	end
	else
	begin
		/* 
		** @loginame is not NULL 
		** Same cases as above but considering @loginame as well
		** Unlock logins which match the specified @loginame 
		** excluding the ones mentioned in @except
		*/

		if (@except_is_login = 1)
		begin
			update master.dbo.syslogins
			set status = status & (~2),	/* LOGIN_UNLOCKED */
			logincount = 0,
			lockdate = NULL,
                        lockreason = NULL,
                        locksuid = NULL
			where name like @loginame
				and name != @except
		end
		else 
		if (@except_is_role = 1)
		begin
			update master.dbo.syslogins
			set status = status & (~2),
			logincount = 0,
			lockdate = NULL,
                        lockreason = NULL,
                        locksuid = NULL
			where name like @loginame and
                        	suid not in
				(select suid from master.dbo.sysloginroles
        		                where srid = role_id(@except))
		end	
		else 
		begin
			update master.dbo.syslogins 
			set status = status & (~2),
			logincount = 0,
			lockdate = NULL,
                        lockreason = NULL,
                        locksuid = NULL
			where name like @loginame
		end
	end



	if (@@error != 0)
		goto clean_all

	/* 
	** Operate according to the HA  restriction class 
	** Make exactly the same changes that were done on main server
	*/
	if (@nHARSTClass = 1)
	begin
		if (@loginame is NULL)
		begin
			if (@except_is_login = 1)
			begin
				/* 
				** @except is a login  
				** Unlock logins except ones which match @except 
				*/
	
				update master.dbo.rmt_ha_syslogins 
				set status = status & (~2),
				logincount = 0,
				lockdate = NULL,
	                        lockreason = NULL,
        	                locksuid = NULL
				where name != @except
			end
			else
			if (@except_is_role = 1) 
			begin
				/* 
				** @except is a role 
				** Unlock all logins except which have the role @except
				*/
	
				update master.dbo.rmt_ha_syslogins
				set status = status & (~2),
				logincount = 0,
				lockdate = NULL,
                                lockreason = NULL,
                                locksuid = NULL
                        	where suid not in
					(select suid from master.dbo.rmt_ha_sysloginroles
                        	      		where srid = role_id(@except))
			end
			else
			begin
				/* @except is NULL */
				update master.dbo.rmt_ha_syslogins 
				set status = status & (~2),
				logincount = 0,
				lockdate = NULL,
                                lockreason = NULL,
                                locksuid = NULL
			end
		end
		else
		begin
			/* @loginame is not NULL */

			if (@except_is_login = 1)
			begin
				/*
				** Unlock logins matching @loginame except ones which 
				** match @except
				*/

    				update master.dbo.rmt_ha_syslogins
				set status = status & (~2),		/* LOGIN_UNLOCKED */
				logincount = 0,
				lockdate = NULL,
                                lockreason = NULL,
                                locksuid = NULL
				where name like @loginame
					and name != @except
			end
			else
			if (@except_is_role = 1)
			begin
				/*
				** unlock logins matching @loginame excluding those
				** which have the role @except
				*/
				update master.dbo.rmt_ha_syslogins
				set status = status & (~2),
				logincount = 0,
				lockdate = NULL,
                                lockreason = NULL,
                                locksuid = NULL
				where name like @loginame and
	                              	suid not in
				      	(select suid from master.dbo.rmt_ha_sysloginroles
                	        		where srid = role_id(@except))
			end
			else
			begin
				update master.dbo.rmt_ha_syslogins
				set status = status & (~2),
				logincount = 0,
				lockdate = NULL,
                                lockreason = NULL,
                                locksuid = NULL
				where name like @loginame
			end	
		end

		if (@@error != 0)
			goto clean_all
        end



	if (@log_for_rep = 1)
	begin
		/*
		** If the 'master' database is marked for replication, the
		** T-SQL built-in 'logexec()' will log for replication the
		** execution instance of this system procedure.  Otherwise,
		** the T-SQL built-in 'logexec()' is a no-op.
		*/
		if (logexec(1) != 1)
		begin
			raiserror 17756, "sp_locklogin", "master"
			goto clean_all
		end
	end

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		commit tran rs_logexec
	
	/*
	** 17914, "Account unlocked."
	*/
	exec sp_getmessage 17914, @msg output
	print @msg
	return (0)
end

/*
**  When it comes down to here, it must be the complicated "lock" case.
*/

select @current_id = suser_id()
/*
** Check if the set of logins to be locked (after taking exceptions into 
** consideration) encompasses all the sso/sa logins in the server.
** If it does, we will be locking all the sa/sso logins; so in this case 
** leave out the current login and lock the rest of the logins.
** If it doesn't, go ahead and lock the set of logins specified.
** By encompassing all sso/sa logins, we mean there must be atleast
** one login with sso privilege and at least one login with sa privilege
** outside our locking set. First we check for sso logins (srid =1) and
** then for sa logins (srid = 0) and set the flag @encompasses_all_logins 
** to false even if one of them is satisfied.
*/

if (@loginame is not NULL)
begin 
	if (@except_is_login = 1)
	begin
		/* 
		** SSO logins srid = 1 and SA logins srid = 0
		** If there exists an sso and sa login outside the
		** set of logins to be locked then it means
		** the set doesn't encompass all of sso and sa logins
		** Similar logic applied in the subsequent code
		** with changes according as login or role specified
		*/

		if exists (select 1 from master.dbo.syslogins as ms,
					 master.dbo.sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 1 and
				(ms.name not like @loginame or ms.name = @except))
		   and 
		   exists (select 1 from master.dbo.syslogins as ms,
					 master.dbo.sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 0 and
				(ms.name not like @loginame or ms.name = @except))
		begin
			select @encompasses_all_logins = 0
		end

	end
	else if (@except_is_role = 1)
	begin
		/*
		** Taking into consideration the exception specified is a role,
		** find out if the set of logins to be locked doesn't encompass
		** all SA and all SSO logins
		*/
		if exists (select 1 from master.dbo.syslogins as ms,
					 master.dbo.sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 1 and	
				((ms.name not like @loginame) or 
				ms.suid in
				(select suid from master.dbo.sysloginroles
					where srid = role_id(@except))) )
		   and
		   exists (select 1 from master.dbo.syslogins as ms,
					 master.dbo.sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 0 and	
				((ms.name not like @loginame) or 
				ms.suid in
				(select suid from master.dbo.sysloginroles
					where srid = role_id(@except))) )
		
		begin
			select @encompasses_all_logins = 0
 		end	

	end
	else
	begin
		/* 
		** @except is NULL
		** See if the set of logins to be locked encompasses
		** all SA logins or all SSO logins
		** If it doesn't encompass all SA logins and all SSO
		** logins set @encompasses_all_logins to 0.
		*/
		if exists (select 1 from master.dbo.syslogins as ms,
					 master.dbo.sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 1 and
				ms.name not like @loginame)
		   and
		   exists (select 1 from master.dbo.syslogins as ms,
					 master.dbo.sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 0 and
				ms.name not like @loginame)
		begin
			select @encompasses_all_logins = 0
		end

	end
end 
else 
begin
	/* @loginame = NULL */

	if (@except_is_login = 1)
	begin	
		/*
		** Set @encompasses_all_logins to 0 if there exists
		** one SA and one SSO login outside the set of logins 
		** to be locked.
		*/
		if exists (select 1 from master.dbo.syslogins as ms,
					 master.dbo.sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 1 and
				ms.name = @except)
		   and
		   exists (select 1 from master.dbo.syslogins as ms,
					 master.dbo.sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 0 and
				ms.name = @except)
		begin
			select @encompasses_all_logins = 0
		end

	end
	else if (@except_is_role = 1)
	begin
		/* 
		** The exception specified is a role. Set @encompasses_all_logins
		** as above considering this @except as a role
		*/
		if exists (select 1 from master.dbo.syslogins as ms,
					 master.dbo.sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 1 and
				ms.suid in
				(select suid from master.dbo.sysloginroles
					where srid = role_id(@except)) )
		   and
		   exists (select 1 from master.dbo.syslogins as ms,
					 master.dbo.sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 0 and
				ms.suid in
                                (select suid from master.dbo.sysloginroles
                                        where srid = role_id(@except)) )
		begin
			select @encompasses_all_logins = 0
		end
	
	end
end

/*
** check if @inactive_days is in valid range 0-32767 and
** 'enable last login' is 1 in sysattributes.
*/
if (@inactive_days != NULL)
begin
	if ((@inactive_days < 0) or (@inactive_days > 32767))
	begin
		/*
                ** 19444,  "The range for %1! is %2! to %3!."
                */
                raiserror 19444, 'inactive days', 0, 32767
                return(1)
	end
	/*
	** no of inactive days = today's date - last login date.
	** For calculation of inactive days, last login updates must be enabled,
	** so attribute row for 'enable last login updates' 
	** in sysattribute should not be set to 0.
	** Either the row should not exists OR it should be set to 1.
	*/
	if ((select int_value from master.dbo.sysattributes
                where class = 32 and attribute = 0) = 0)
                begin
                        /*
                        ** 19606, To lock inactive accounts, you must run
                        ** sp_passwordpolicy 'set','enable last login updates',1
                        */
			raiserror 19606
                        return (1)
                end
end
/*
**  If any of the accounts to be locked are active, go ahead and try 
**  to lock them, but issue a warning message.
**  If @encompasses_all_logins = 1 then the @current_id is not locked
**  but a warning message could be displayed erroneously as the account 
**  is active. So set @temp_current_id and use it to exclude the 
**  current account. If @encompasses_all_logins = 0 @current_id shouldn't
**  come into picture - hence invalidate it.
*/

if (@encompasses_all_logins = 1)
	select @temp_current_id = @current_id
else
	select @temp_current_id = -2 /* @temp_current_id is invalidated */

/*
** SDC only, check clusterwide sysprocesses for active login
*/
if (@@clustermode = "shared disk cluster")
begin
	select @scope=@@system_view
	set system_view cluster
end

if (@loginame is not NULL) 
begin
	if (@except_is_login = 1)
	begin
		/* 
		** set @warning_active to 1 if the set of logins to
		** be locked has any active login
		*/
		if exists (select 1 from master.dbo.sysprocesses as mp,
					 master.dbo.syslogins as ms
				where mp.suid = ms.suid and
				ms.name like @loginame and
				ms.name != @except and
				ms.suid != @temp_current_id)
		begin
			select @warning_active = 1
		end

	end
	else if (@except_is_role = 1)
	begin
		/*
		** Similar to the above condition except that
		** the exception specified is a role
		*/
		if exists (select 1 from master.dbo.sysprocesses as mp,
					 master.dbo.syslogins as ms
				where mp.suid = ms.suid and
				ms.name like @loginame and
				ms.suid != @temp_current_id and
				ms.suid not in 
				(select suid from master.dbo.sysloginroles
					where srid = role_id(@except)) )
		begin		
			select @warning_active = 1
		end

	end
	else
	/* @except is NULL */
	begin
		/*
		** Find out if any login to be locked is active
		** There is no exception specified.
		*/
		if exists (select 1 from master.dbo.sysprocesses as mp,
					 master.dbo.syslogins as ms
				where ms.suid = mp.suid and
				ms.name like @loginame and
				ms.suid != @temp_current_id)
		begin
			select @warning_active = 1
		end
	end
end
else
begin
	/* @loginame = NULL */
	if (@except_is_login = 1)
	begin
		/* 
		** Find out if the set of logins to be locked has
		** any active login
		*/
		if exists (select 1 from master.dbo.sysprocesses as mp,
					 master.dbo.syslogins as ms
				where mp.suid = ms.suid and
				ms.name != @except and
				ms.suid != @temp_current_id)
		begin	
			select @warning_active = 1
		end

	end
	else if (@except_is_role = 1)
	begin
		/* 
		** Similar to the above case 
		** Here the @except specified is a role
		*/
		if exists (select 1 from master.dbo.sysprocesses as mp,
					 master.dbo.syslogins as ms
				where mp.suid = ms.suid and
				ms.suid != @temp_current_id and
				ms.suid not in 
				(select suid from master.dbo.sysloginroles
					where srid = role_id(@except)))
		begin		
			select @warning_active = 1
		end

	end
	else
	/* @except is NULL */
	begin
		if exists (select 1 from master.dbo.sysprocesses as mp,
					 master.dbo.syslogins as ms
				where ms.suid = mp.suid and
				ms.suid != @temp_current_id)
		begin
			select @warning_active = 1
		end	

	end
end
	
/*
** SDC only: restore previous system_view scope
*/
if (@@clustermode = "shared disk cluster")
begin
	set system_view @scope
end

if (@warning_active = 1)
begin
	/*
	** 19391, "Warning: One or more accounts specified are active."
	*/

	exec sp_getmessage 19391, @msg output 
	print @msg

	/* FALL THROUGH */
end



if (@nHARSTClass = 1)
begin 
	/* HA consistency checking */

if (@loginame is not NULL)
begin 
	if (@except_is_login = 1)
	begin
		/* 
		** SSO logins srid = 1 and SA logins srid = 0
		** If there exists an sso and sa login outside the
		** set of logins to be locked then it means
		** the set doesn't encompass all of sso and sa logins
		** Similar logic applied in the subsequent code
		** with changes according as login or role specified
		*/
		if exists (select 1 from master.dbo.rmt_ha_syslogins as ms,
					 master.dbo.rmt_ha_sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 1 and
				(ms.name not like @loginame or ms.name = @except))
		   and
		   exists (select 1 from master.dbo.rmt_ha_syslogins as ms,
					 master.dbo.rmt_ha_sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 0 and
				(ms.name not like @loginame or ms.name = @except))
		begin
			select @encompasses_all_rmt_ha_logins = 0
		end

	end
	else if (@except_is_role = 1)
	begin
		/*
		** Taking into consideration the exception specified is a role,
		** find out if the set of logins to be locked doesn't encompass
		** all SA and all SSO logins
		*/
		if exists (select 1 from master.dbo.rmt_ha_syslogins as ms,
					 master.dbo.rmt_ha_sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 1 and	
				((ms.name not like @loginame) or 
				ms.suid in
				(select suid from master.dbo.rmt_ha_sysloginroles
					where srid = role_id(@except))) )
		   and
		   exists (select 1 from master.dbo.rmt_ha_syslogins as ms,
					 master.dbo.rmt_ha_sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 0 and	
				((ms.name not like @loginame) or 
				ms.suid in
				(select suid from master.dbo.rmt_ha_sysloginroles
					where srid = role_id(@except))) )
		begin
			select @encompasses_all_rmt_ha_logins = 0
		end
	
	end
	else
	/* @except is NULL */
	begin
		/* 
		** @except is NULL
		** See if the set of logins to be locked encompasses
		** all SA logins or all SSO logins
		** If it doesn't encompass all SA logins and all SSO
		** logins set @encompasses_all_rmt_ha_logins to 0.
		*/

		if exists (select 1 from master.dbo.rmt_ha_syslogins as ms,
					 master.dbo.rmt_ha_sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 1 and
				ms.name not like @loginame)
		   and
		   exists (select 1 from master.dbo.rmt_ha_syslogins as ms,
					 master.dbo.rmt_ha_sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 0 and
				ms.name not like @loginame)
		begin
			select @encompasses_all_rmt_ha_logins = 0
		end

	end
end 
else 
begin
	/* @loginame = NULL */
	if (@except_is_login = 1)
	begin	
		/*
		** Set @encompasses_all_rmt_ha_logins to 0 if there exists
		** one SA and one SSO login outside the set of logins 
		** to be locked.
		*/
		if exists (select 1 from master.dbo.rmt_ha_syslogins as ms,
					 master.dbo.rmt_ha_sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 1 and
				ms.name = @except)
		   and
		   exists (select 1 from master.dbo.rmt_ha_syslogins as ms,
					 master.dbo.rmt_ha_sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 0 and
				ms.name = @except)
		begin
			select @encompasses_all_rmt_ha_logins = 0
		end

	end
	else if (@except_is_role = 1)
	begin
		/* 
		** The exception specified is a role. Set @encompasses_all_rmt_ha_logins
		** as above considering this @except as a role
		*/
		if exists (select 1 from master.dbo.rmt_ha_syslogins as ms,
					 master.dbo.rmt_ha_sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 1 and	
				ms.suid in
				(select suid from master.dbo.rmt_ha_sysloginroles
					where srid = role_id(@except)) )
		   and
		   exists (select 1 from master.dbo.rmt_ha_syslogins as ms,
					 master.dbo.rmt_ha_sysloginroles as msr
				where (ms.status)&2 = 0 and
				ms.suid = msr.suid and
				msr.srid = 0 and	
				ms.suid in
				(select suid from master.dbo.rmt_ha_sysloginroles
					where srid = role_id(@except)) )
		begin
			select @encompasses_all_rmt_ha_logins = 0
		end
	
	end
end

end 


if (@encompasses_all_logins != @encompasses_all_rmt_ha_logins)
begin
	/*
	** 18773, "HA_LOG: HA consistency check failure in '%1!' on
	** the companion server '%2!'"
	*/
	exec sp_getmessage 18773, @msg output
	print @msg, "sp_locklogin", @@hacmpservername

	/*
	** 19393, "The set of sa/sso logins on both the servers
	** differ"
	*/
	exec sp_getmessage 19393, @msg output
	print @msg
end



if (@encompasses_all_logins = 1)
begin 
	/*
	** Check if the current account is already locked. If yes,
	** flag an error as locking all accounts excluding the 
	** current is not possible.
	** In other words, an account which is already locked at
	** this point of time cannot be allowed to issue any lock 
	** command.
	** However, under certain race conditions where more than
	** one such accounts issue lock commands simultaneously,
	** this check doesn't guarantee consistency. If the current
	** account is locked AFTER this check passes through by some
	** other login, we have a situation where a locked account
	** will be allowed to lock other accounts. This drawback
	** cannot be overcome without removing the check and without
	** doing the check as well as locking operation in a transaction.
	** Considering it is rare that such a situation occurs, this
	** approach is adopted.
	*/

	if exists (select 1 from master.dbo.syslogins 
			where (status & 2) = 2 and
			suid = @current_id)
	begin
		/* 19392, Permission Denied. The current account is already locked. */
		exec sp_getmessage 19392, @msg output
		print @msg

		return (1)
	end

end

/*  Feel free to lock the account */

if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
	begin tran rs_logexec


if (@nHARSTClass = 1)
begin
	exec @rtn_code = sp_halockclustertables "sp_locklogin"
	if (@rtn_code != 0)
		goto clean_all
end


/*
** There is a race condition possible. Even though we unlock the current account
** before quitting (see the later part of the code), if we lock the current account
** here AND the set of accts encompasses all SA/SSO logins, we have a situation 
** where for a brief period, all SA/SSO logins may be locked. So, if we find that
** all SA/SSO logins have been encompassed we exclude the current account(which has
** SA/SSO role) from locking in which case we set the variable @current_id to
** the suid of the current account. however if all SA/SSO logins have not been
** encompassed we need not exclude the current account from the set of logins 
** being locked, so invalidate the variable @current_id
*/

if (@encompasses_all_logins = 0)
	select @current_id = -2  /* Invalidate @current_id value */

if (@loginame is not NULL) 
begin
	if (@except_is_login = 1)
	begin
		/*
		** Lock all the accounts matching @loginame except
		** "@except" login and current account (current acct
		** may be valid or invalid)
		*/
		if (@inactive_days != NULL)
		begin
                        /*
                        ** As 'last login update' feature(securing passwords) 
			** will not be HA-ized in 15.0.2 release, we need 
			** to handle it specially on primary and companion server.
                        ** To keep locked accounts in sync, we compare 'lastlogindate' 
			** column on both servers, and use the most recent date 
			** to calculate inactive days.
                        **
                        ** Check if companion server is configured. and 
			** then accordingly decide the set of accounts to lock. 
                        */
                        if (@HA_CERTIFIED = 0)
                        begin
                                /*
                                ** Companion server is not configured, so you 
				** can use master.dbo.syslogins for lastlogindate.
				** No need to look at master.dbo.rmt_ha_syslogins
                                */
				update master.dbo.syslogins
				set status = status | 2, /* LOGIN_LOCKED */
				lockreason = 1,  /* locked because inactive */
				lockdate = @current_date,
				locksuid = suser_id()
				where name like @loginame
					and (status & 2) = 0
					and suid != @current_id
					and name != @except
					and (datediff(dd, isnull(lastlogindate, pwdate), @current_date)
						>= @inactive_days)
			end
                        else
                        begin
				/*
				** Companion server is configured.
				** If a login,
				** is inactive on primary server,
				** we check if it is inactive on companion server also.
				** If is inactive on both servers, then only it is locked.
				*/

				if (@nHARSTClass = 1)
                                        insert #dummy_table
                                        select suid from master.dbo.syslogins
					where name like @loginame
					       and (status & 2) = 0
                                               and suid != @current_id
                                               and name != @except
                                               and datediff(dd,
                                                            isnull(lastlogindate,
                                                            pwdate),
                                                            @current_date) >= @inactive_days
                                        if exists (select 1 from #dummy_table)
                                        begin
						update master.dbo.syslogins
						set status = status | 2,
						lockreason = 1,  /* locked because inactive */
						lockdate =  @current_date,
						locksuid = suser_id()
						where suid in
                                                	(select master.dbo.rmt_ha_syslogins.suid
	                                                from master.dbo.rmt_ha_syslogins
        	                                        where datediff(dd,
                	                                                isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
                        	                                        master.dbo.rmt_ha_syslogins.pwdate),
									@current_date) >= @inactive_days
                                	                        and suid in(select suid from #dummy_table))
					end

				/*
				** A 'begin - end' block , that includes all statement in '##if - ##endif' only,
				** gives syntax error. The 'begin - end' block is considered as empty block.
				** following 'select' statement is included to avoid that error.
				*/
	                        select @dummy = 1
                        end
		end
		else /* @inactive_days = NULL  */	
		begin
			update master.dbo.syslogins
			set status = status | 2, /* LOGIN_LOCKED */
                        lockreason = 0,  /* locked manually using sp_locklogin */
                        lockdate =  @current_date,
                        locksuid = suser_id()
			where name like @loginame
				and (status & 2) = 0
				and suid != @current_id
				and name != @except
		end
	end
	else if (@except_is_role = 1)
	begin
		/*
		** Lock all the accounts matching @loginame except
		** those which have the role @except and excluding
		** current account (which may be valid or invalid)
		*/
		if (@inactive_days != NULL)
                begin
			if (@HA_CERTIFIED = 0)
                        begin
				update master.dbo.syslogins
				set status = status | 2, /* LOGIN_LOCKED */
				lockreason = 1,  /* locked because inactive */
				lockdate =  @current_date,
				locksuid = suser_id() 
				where name like @loginame
					and (status & 2) = 0
					and suid != @current_id
					and suid not in
						(select suid from master.dbo.sysloginroles
							where srid = role_id(@except))
					and (datediff(dd, isnull(lastlogindate, pwdate), @current_date)
							>= @inactive_days)
			end
			else /* HA server is configured */
			begin

				if (@nHARSTClass = 1)
				begin
					insert #dummy_table
					select suid from master.dbo.syslogins
		                        where name like @loginame
					       and (status & 2) = 0	
                                               and suid != @current_id
                                               and datediff(dd,
                                                       isnull(lastlogindate,pwdate),
                                                       @current_date) >= @inactive_days
					if exists (select 1 from #dummy_table)
					begin
						update master.dbo.syslogins
						set status = status | 2,
						lockreason = 1,  /* locked because inactive */
						lockdate =  @current_date,
						locksuid = suser_id()
						where suid not in
							(select suid from master.dbo.sysloginroles
							where srid = role_id(@except))
						and suid in
                                	                (select master.dbo.rmt_ha_syslogins.suid
	                                                from master.dbo.rmt_ha_syslogins
	                                                where datediff(dd,
                                                                isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
                                                                master.dbo.rmt_ha_syslogins.pwdate),
								@current_date) >= @inactive_days
                                                        and suid in (select suid from #dummy_table))
					end
				end

	                        select @dummy = 1
			end
                end
                else /* @inactive_days = NULL  */
                begin
			update master.dbo.syslogins
			set status = status | 2,
                        lockreason = 0,  /* locked manually using sp_locklogin */
                        lockdate =  @current_date,
                        locksuid = suser_id()
			where name like @loginame 
				and (status & 2) = 0
				and suid != @current_id 
				and suid not in 
				(select suid from master.dbo.sysloginroles
        		             	where srid = role_id(@except))
		end
	end
	else
	/* @except is NULL */
	begin
		/*
		** Lock all the accounts matching @loginame 
		** excluding current account (which may be valid or invalid)
		*/
                if (@inactive_days != NULL)
                begin
			if (@HA_CERTIFIED = 0)
			begin
				update master.dbo.syslogins
				set status = status | 2, /* LOGIN_LOCKED */
				lockreason = 1,  /* locked because inactive */
				lockdate =  @current_date,
				locksuid = suser_id() 
				where name like @loginame
					and (status & 2) = 0
					and suid != @current_id
					and (datediff(dd, isnull(lastlogindate, pwdate), @current_date)
						>= @inactive_days)
			end
			else /* HA server is configured */
			begin

				if (@nHARSTClass = 1)
				begin
                                        insert #dummy_table
					select suid from master.dbo.syslogins
                                        where name like @loginame
						and (status & 2) = 0
                                                and suid != @current_id
                                                and datediff(dd,
                                                           isnull(lastlogindate,pwdate),
                                                           @current_date) >= @inactive_days
                                        if exists (select 1 from #dummy_table)
                                        begin
						update master.dbo.syslogins
						set status = status | 2,
						lockreason = 1,  /* locked because inactive */
						lockdate =  @current_date,
						locksuid = suser_id()
						where suid in
        	                                        (select master.dbo.rmt_ha_syslogins.suid
                	                                from master.dbo.rmt_ha_syslogins
                        	                        where datediff(dd, 
								isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
                                        	                     master.dbo.rmt_ha_syslogins.pwdate),
									@current_date) >= @inactive_days
                                                       and suid in (select suid from #dummy_table))

					end
				end

                                select @dummy = 1
			end
                end
                else /* @inactive_days = NULL  */
                begin
			update master.dbo.syslogins
			set status = status | 2,
                        lockreason = 0,  /* locked manually using sp_locklogin */
                        lockdate =  @current_date,
                        locksuid = suser_id()
			where name like @loginame
				and (status & 2) = 0
				and suid != @current_id
		end
	end
end
else
/* @loginame is NULL */
begin	
	if (@except_is_login = 1)
	begin		
		/* 
		** Lock all logins except that match @except 
		** leaving out current login
		*/
		 if (@inactive_days != NULL)
                 begin
			if (@HA_CERTIFIED = 0)
			begin
	                        update master.dbo.syslogins
        	        	set status = status | 2, /* LOGIN_LOCKED */
				lockreason = 1,  /* locked because inactive */
				lockdate =  @current_date,
				locksuid = suser_id()
                		where suid != @current_id
					and (status & 2) = 0
       		                 	and name != @except
                	        	and (datediff(dd, isnull(lastlogindate, pwdate), @current_date)
						>= @inactive_days)
			end
			else /* HA server is configured */
			begin

				if (@nHARSTClass = 1)
				begin
                                        insert #dummy_table
					select suid from master.dbo.syslogins
                                        where suid != @current_id
					       and (status & 2) = 0
                                               and name != @except
                                               and datediff(dd,
                                                       isnull(lastlogindate,pwdate),
                                                       @current_date) >= @inactive_days
                                        if exists (select 1 from #dummy_table)
                                        begin
						update master.dbo.syslogins
						set status = status | 2,
						lockreason = 1,  /* locked because inactive */
						lockdate =  @current_date,
						locksuid = suser_id()
						where suid in
        	                                        (select master.dbo.rmt_ha_syslogins.suid
                	                                from master.dbo.rmt_ha_syslogins
                        	                        where datediff(dd,
                                	                                isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
                                        	                        master.dbo.rmt_ha_syslogins.pwdate),
									@current_date) >= @inactive_days
                                                	        and suid in (select suid from #dummy_table))
					end
				end

                                select @dummy = 1
			end
		end
                else /* @inactive_days = NULL  */
                begin
                        update master.dbo.syslogins
                        	set status = status | 2, /* LOGIN_LOCKED */
	                        lockreason = 0,  /* locked manually using sp_locklogin */
        	                lockdate =  @current_date,
                	        locksuid = suser_id()
	                        where suid != @current_id
					and (status & 2) = 0
		                        and name != @except
                end
	end
	else if (@except_is_role = 1)
	begin
		/* 
		** Lock all logins except whose role matches the
		** role specified as exception 
		*/
		if (@inactive_days != NULL)
		begin
			if (@HA_CERTIFIED = 0)
			begin
			update master.dbo.syslogins 
			set status = status | 2,
			lockreason = 1,  /* locked because inactive */
			lockdate =  @current_date,
			locksuid = suser_id()
			where suid != @current_id
				and (status & 2) = 0
				and suid not in
					(select suid from master.dbo.sysloginroles
						where srid = role_id(@except))
				and (datediff(dd, isnull(lastlogindate, pwdate), @current_date)
					>= @inactive_days)
			end
			else /* HA server is configured */
			begin

				if (@nHARSTClass = 1)
				begin
                                        insert #dummy_table
					select suid from master.dbo.syslogins
                                        where suid != @current_id
					       and (status & 2) = 0
                                               and name != @except
                                               and datediff(dd,
                                                       isnull(lastlogindate,pwdate),
                                                       @current_date) >= @inactive_days
                                        if exists (select 1 from #dummy_table)
                                        begin
						update master.dbo.syslogins
						set status = status | 2,
						lockreason = 1,  /* locked because inactive */
						lockdate =  @current_date,
						locksuid = suser_id()
						where suid not in
							(select suid from master.dbo.sysloginroles
							where srid = role_id(@except))
						and suid in
                                                (select master.dbo.rmt_ha_syslogins.suid
                                                from master.dbo.rmt_ha_syslogins
                                                where datediff(dd,
                                                                isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
                                                                master.dbo.rmt_ha_syslogins.pwdate),
								@current_date) >=  @inactive_days
                                                        and suid in (select suid from #dummy_table))
					end
				end

                                select @dummy = 1				
			end
		end
		else /* @inactive_days = NULL */
		begin
			update master.dbo.syslogins
			set status = status | 2,
	                lockreason = 0,  /* locked manually using sp_locklogin */
	                lockdate =  @current_date,
	                locksuid = suser_id()
			where suid != @current_id 
				and (status & 2) = 0
				and suid not in
					(select suid from master.dbo.sysloginroles
					where srid = role_id(@except))
		end
	end
	else
	begin
		/* No exception is specified */
		if (@inactive_days != NULL)
                begin
			if (@HA_CERTIFIED = 0)
			begin
                                update master.dbo.syslogins
                                set status = status | 2,
                                lockreason = 1,  /* locked because inactive */
                                lockdate =  @current_date,
                                locksuid = suser_id()
                                where suid != @current_id
					and (status & 2) = 0
       		                         and (datediff(dd, isnull(lastlogindate,pwdate), @current_date)
						>= @inactive_days)
                        end
			else
			begin

				if (@nHARSTClass = 1)
				begin
					insert #dummy_table
					select suid from master.dbo.syslogins
                                        where suid != @current_id
						and (status & 2) = 0
                                        	and (datediff(dd,
                                               		isnull(lastlogindate,pwdate),
                                                        @current_date) >= @inactive_days)

					if exists (select 1 from #dummy_table)
					begin
						update master.dbo.syslogins
						set status = status | 2,
						lockreason = 1,  /* locked because inactive */
						lockdate =  @current_date,
						locksuid = suser_id()
						where suid in 
							(select master.dbo.rmt_ha_syslogins.suid
							from master.dbo.rmt_ha_syslogins
							where datediff(dd,
									isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
									master.dbo.rmt_ha_syslogins.pwdate),
									@current_date) >=  @inactive_days
								and suid in (select suid from #dummy_table))
					end
				end

			select @dummy = 1
			end
		end
		else
		begin
			update master.dbo.syslogins
			set status = status | 2,
                        lockreason = 0,  /* locked manually using sp_locklogin */
                        lockdate =  @current_date,
                        locksuid = suser_id()
			where suid != @current_id
				and (status & 2) = 0
		end
	end
end

/*
** Because of some possible race-conditions unlock the account
** just before quitting to ensure the current account remains 
** unlocked. Race between different logins trying to lock a set of accounts
** The last login which executes this statement unlocks that
** account, at the end we are sure that at least one login remains unlocked
*/

select @row_count_temp = @@rowcount

if (@encompasses_all_logins = 1)
begin
	update master.dbo.syslogins
	set status = status & ~2 	/* Unlock current account before quitting */
	where suid = @current_id
end

/*
**  Check @@rowcount when it works
*/

if (@row_count_temp > 0)
begin


	/* 
	** Operate according to the HA  restriction class 
	** Do the exact sequence of operations on HA server
	*/
	if (@nHARSTClass = 1)
	begin
		if (@loginame is not NULL)
		begin	
			if (@except_is_login = 1)
			begin
				/*
				** Lock all the accounts matching @loginame except
				** "@except" login and current account (current acct
				** may be valid or invalid)
				*/
		                if (@inactive_days != NULL)
                		begin
					update master.dbo.rmt_ha_syslogins
                                        set status = status | 2, /* LOGIN_LOCKED */
		                        lockreason = 1,  /* locked because inactive */
                		        lockdate =  @current_date,
		                        locksuid = suser_id()
                                        where name like @loginame
						and (status & 2) = 0
						and name != @except
						and suid != @current_id
						and suid in
                                                (select master.dbo.rmt_ha_syslogins.suid
                                                from master.dbo.rmt_ha_syslogins
                                                where datediff(dd,
                                                                isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
                                                                master.dbo.rmt_ha_syslogins.pwdate),
								@current_date) >=  @inactive_days
                                                        and suid in(select suid from #dummy_table))
				end
				else
				begin
					update master.dbo.rmt_ha_syslogins
		 			set status = status | 2, /* LOGIN_LOCKED */
 		                        lockreason = 0,  /* locked manually using sp_locklogin */
                		        lockdate =  @current_date,
		                        locksuid = suser_id()
					where name like @loginame
						and (status & 2) = 0
						and name != @except
						and suid != @current_id
				end
			end
			else if (@except_is_role = 1)
			begin
				/*
				** Lock all the accounts matching @loginame except
				** those which have the role @except and excluding
				** current account (which may be valid or invalid)
				*/
                                if (@inactive_days != NULL)
                                begin
                                        update master.dbo.rmt_ha_syslogins
                                        set status = status | 2, /* LOGIN_LOCKED */
                                        lockreason = 1,  /* locked because inactive */
                                        lockdate =  @current_date,
                                        locksuid = suser_id()
					where name like @loginame
						and (status & 2) = 0
						and suid != @current_id
						and suid not in
							(select suid from master.dbo.rmt_ha_sysloginroles
							where srid = role_id(@except) )
						and suid in
                                                (select master.dbo.rmt_ha_syslogins.suid
                                                from master.dbo.rmt_ha_syslogins
                                                where datediff(dd,
                                                                isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
                                                                master.dbo.rmt_ha_syslogins.pwdate),
								@current_date) >= @inactive_days
                                                        and suid in(select suid from #dummy_table))
				end
				else
				begin
					update master.dbo.rmt_ha_syslogins 
					set status = status | 2,
                                        lockreason = 0,  /* locked because inactive */
                                        lockdate =  @current_date,
                                        locksuid = suser_id()
					where name like @loginame 
						and (status & 2) = 0
						and suid != @current_id 
						and suid not in 
							(select suid from master.dbo.rmt_ha_sysloginroles
                     					where srid = role_id(@except) )
				end
			end
			else
			/* @except is NULL */
			begin
				/*
				** Lock all the accounts matching @loginame 
				** excluding current account (which may be valid or invalid)
				*/
				if (@inactive_days != NULL)
                                begin
                                        update master.dbo.rmt_ha_syslogins
                                        set status = status | 2, /* LOGIN_LOCKED */
                                        lockreason = 1,  /* locked because inactive */
                                        lockdate =  @current_date,
                                        locksuid = suser_id()
                                        where name like @loginame 
						and (status & 2) = 0
						and suid != @current_id 
						and suid in
                                                (select master.dbo.rmt_ha_syslogins.suid
                                                from master.dbo.rmt_ha_syslogins
                                                where datediff(dd,
                                                                isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
                                                                master.dbo.rmt_ha_syslogins.pwdate),
								@current_date) >= @inactive_days
                                                        and suid in(select suid from #dummy_table))
				end
				else
				begin	
					update master.dbo.rmt_ha_syslogins
					set status = status | 2,
                                        lockreason = 0,/* locked manually using sp_locklogin */
                                        lockdate =  @current_date,
                                        locksuid = suser_id()
					where name like @loginame
						and (status & 2) = 0
						and suid != @current_id
				end
			end
		end
		else
		/* @loginame is NULL */
		begin 
			if (@except_is_login = 1)
			begin
				/* 
				** Lock all logins except that match @except 
				** leaving out current login
				*/
                                if (@inactive_days != NULL)
                                begin
                                        update master.dbo.rmt_ha_syslogins
                                        set status = status | 2, /* LOGIN_LOCKED */
                                        lockreason = 1,  /* locked because inactive */
                                        lockdate =  @current_date,
                                        locksuid = suser_id()
 					where suid != @current_id
						and (status & 2) = 0
						and name != @except
						and suid in
                                                (select master.dbo.rmt_ha_syslogins.suid
                                                from master.dbo.rmt_ha_syslogins
                                                where datediff(dd,
                                                                isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
                                                                master.dbo.rmt_ha_syslogins.pwdate),
								@current_date) >=  @inactive_days
                                                        and suid in (select suid from #dummy_table))
				end
				else
				begin
					update master.dbo.rmt_ha_syslogins
						set status = status | 2, 	/* LOGIN_LOCKED */
	                                        lockreason = 0,/* locked manually using sp_locklogin */
        	                                lockdate =  @current_date,
                	                        locksuid = suser_id()
						where suid != @current_id
							and (status & 2) = 0
							and name != @except
				end
			end
			else if (@except_is_role = 1)
			begin
				/* 
				** Lock all logins except whose role matches the
				** role specified as exception 
				*/
                                if (@inactive_days != NULL)
                                begin
                                        update master.dbo.rmt_ha_syslogins
                                        set status = status | 2, /* LOGIN_LOCKED */
                                        lockreason = 1,  /* locked because inactive */
                                        lockdate =  @current_date,
                                        locksuid = suser_id()
					where   suid != @current_id
						and (status & 2) = 0
						and suid not in
							(select suid from master.dbo.rmt_ha_sysloginroles
							where srid = role_id(@except))
						and suid in
                                                (select master.dbo.rmt_ha_syslogins.suid
                                                from master.dbo.rmt_ha_syslogins
                                                where datediff(dd,
                                                                isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
                                                                master.dbo.rmt_ha_syslogins.pwdate),
								@current_date) >=  @inactive_days
                                                        and suid in (select suid from #dummy_table))
				end
				else
 				begin
					update master.dbo.rmt_ha_syslogins
					set status = status | 2,
	                                lockreason = 0,/* locked manually using sp_locklogin */
	                                lockdate =  @current_date,
	                                locksuid = suser_id()
					where suid != @current_id 
						and (status & 2) = 0
						and suid not in 
							(select suid from master.dbo.rmt_ha_sysloginroles
	                		     		where srid = role_id(@except))
				end
			end
			else
			/* @except is NULL */
			begin
				/* No exception is specified */
				if (@inactive_days != NULL)
                                begin
                                        update master.dbo.rmt_ha_syslogins
                                        set status = status | 2, /* LOGIN_LOCKED */
                                        lockreason = 1, /* locked because inactive */
                                        lockdate =  @current_date,
                                        locksuid = suser_id()
                                        where suid != @current_id
						and (status & 2) = 0
						and suid in
                                                (select master.dbo.rmt_ha_syslogins.suid
                                                from master.dbo.rmt_ha_syslogins
                                                where datediff(dd,
                                                                isnull(master.dbo.rmt_ha_syslogins.lastlogindate,
                                                                master.dbo.rmt_ha_syslogins.pwdate),
								@current_date) >= @inactive_days
                                                        and suid in (select suid from #dummy_table))
				end
                                else
                                begin
					update master.dbo.rmt_ha_syslogins
					set status = status | 2,
                                        lockreason = 0,/* locked manually using sp_locklogin */
                                        lockdate =  @current_date,
                                        locksuid = suser_id()
					where suid != @current_id
					and (status & 2) = 0
				end
			end
		end

		if (@@error != 0)
		begin
			goto clean_all
		end
		else
		begin
			if (@encompasses_all_logins = 1)

				update master.dbo.rmt_ha_syslogins
				set status = status & ~2 	   /* Unlock current acct before exit */
				where suid = @current_id
		end
	end



	if (@log_for_rep = 1)
	begin
		/*
		** If the 'master' database is marked for replication, the
		** T-SQL built-in 'logexec()' will log for replication the
		** execution instance of this system procedure.  Otherwise,
		** the T-SQL built-in 'logexec()' is a no-op.
		*/
		if (logexec(1) != 1)
		begin
			raiserror 17756, "sp_locklogin", "master"
			goto clean_all
		end
	end

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		commit tran rs_logexec

	/*
	** 17919, "Account locked."
	*/
	exec sp_getmessage 17919, @msg output
	print @msg
	return (0)
end
else
begin
	/*
	** 19643, "No account(s) locked."
	*/
	exec sp_getmessage 19643, @msg output
	print @msg

	/* 
	** No accounts were locked, as there were no unlocked accounts to be locked.
	** so rollback the transaction , but return 0 as return value.
	*/
	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
                rollback tran rs_logexec
	return (0)
end

clean_all:
	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		rollback tran rs_logexec
        return (1)
go
exec sp_procxmode 'sp_locklogin', 'anymode'
go
grant execute on sp_locklogin to public
go
exec sp_procxmode 'sp_locklogin', 'rep_master'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_set_password')
begin
	drop procedure sp_set_password
end
go
print "Installing sp_set_password"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/* 	4.8	1.1	06/14/90	sproc/src/set_password */

/* sp_set_password is a wrapper of built_in function set_password() */
/* 
** Warning: Do NOT use sp_set_password to set a login's password, instead,
** use sp_password.
*/

/*
** Generated by spgenmsgs.pl on Thu Feb  2 00:39:20 2006 
*/
/*
** raiserror Messages for set_password [Total 1]
**
** 17756, "The execution of the stored procedure '%1!' in database '%2!' was aborted because there was an error in writing the replication log record."
*/
/*
** sp_getmessage Messages for set_password [Total 0]
*/
/*
** End spgenmsgs.pl output.
*/

create procedure sp_set_password
@caller_password varchar(255) = NULL,	/* the current password of caller */
@new_password    varchar(256) = NULL,	/* the new password of the target acct*/
					/* a length of 256 is required to test if
					** user entered a passwd > 255 chars.
					*/
@loginame        varchar(255) = NULL,	/* user to change password on */
@immediate	 int = 0		/* if not 0, change the password in
					** all running processes for loginame.
					*/
as

declare @returncode int

select @returncode = set_password(@caller_password, @new_password, @loginame, @immediate)
if (@returncode != 0)
	return (0)

/*
** Before we log our system procedure execution instance, re-initialize the
** '@caller_password' parameter to NULL and the '@new_password' parameter
** to the encrypted form of the password.  This prevents the passwords from
** being stored in clear text in the transaction log as well as in the
** Replication Server stable queues.
**
** When the ASE RepAgent Thread sends the system procedure execution
** instance to the Replication Server, the ASE RepAgent will re-name the
** system procedure from 'sp_set_password()' to 'sp_set_password_rep()'.
** This will cause the Replication Server to execute, at the target ASE,
** the system procedure 'sp_set_password_rep()' which knows how to properly
** process the encrypted password.
*/
select @caller_password = NULL

if (@loginame is not NULL)
begin
	select @new_password = password
	from master.dbo.syslogins
	where name = @loginame
end
else
begin
	select @new_password = password
	from master.dbo.syslogins
	where suid = suser_id()
end

/*
** If the 'master' database is marked for replication, the T-SQL built-in
** 'logexec()' will log for replication the execution instance of this
** system procedure.  Otherwise, the T-SQL built-in 'logexec()' is a no-op.
*/
if (logexec(1) != 1)
begin
	raiserror 17756, "sp_set_password", "master"
	return (1)
end

return (0)
go
exec sp_procxmode 'sp_set_password', 'anymode'
go
grant execute on sp_set_password to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_password')
begin
	drop procedure sp_password
end
go
print "Installing sp_password"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/* 	4.8	1.1	06/14/90	sproc/src/password */

/*
** Generated by spgenmsgs.pl on Thu Feb  2 00:39:18 2006 
*/
/*
** raiserror Messages for password [Total 3]
**
** 17260, "Can't run %1! from within a transaction."
** 17720, "Error:  Unable to set the Password."
** 17756, "The execution of the stored procedure '%1!' in database '%2!' was aborted because there was an error in writing the replication log record."
*/
/*
** sp_getmessage Messages for password [Total 1]
**
** 17721, "Password correctly set."
*/
/*
** End spgenmsgs.pl output.
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_password
@caller_password varchar(255) = NULL,	/* the current password of caller */
@new_password    varchar(256) = NULL,	/* the new password of the target acct*/
					/* a length of 256 is required to test if
					** user entered a passwd > 255 chars.
					*/
@loginame        varchar(255) = NULL,	/* user to change password on */
@immediate	 int = 0		/* if not 0, change the password in
					** all running processes for loginame.
					*/
as

declare @returncode int
declare @msg  varchar(1024)
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int
declare @set_cis_rpc_handling int
declare @error_save int

select @set_cis_rpc_handling = 0
select @error_save = 0

select @nHARSTClass = ha_getrestrictionclass("sp_password")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_password', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
** Do not allow this system procedure to be run from within a transaction
** to avoid creating a multi-database transaction where the 'master'
** database is not the co-ordinating database.
*/
if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction."
	*/
	raiserror 17260, "sp_password"
	return (1)
end
else
begin
	set chained off
end

set transaction isolation level 1

/*
**  Encrypt and store the input @new_password.
**  @caller_password will be checked against the password of the caller.
**  set_password() builtin will print out nice messages.
*/
select @returncode = set_password(@caller_password, @new_password, @loginame, @immediate)



if (@returncode  != 0) /* set_password succeed */
begin
        /* Set the password on the remote server */
	if (@nHARSTClass = 1)
        begin
		/* Enable cis_rpc_handling to make remote call */
		if (@@cis_rpc_handling = 0)
		begin
			set cis_rpc_handling on
			select @set_cis_rpc_handling = 1
		end

		exec @returncode = SYB_HACMP.sybsystemprocs.dbo.sp_set_password @caller_password, @new_password, @loginame, @immediate
		select @error_save = @@error

		if (@set_cis_rpc_handling = 1)
			set cis_rpc_handling off

		if ((@error_save != 0) or (@returncode != 0))
			select @returncode = 0
		else
			select @returncode = 1
	end
end


if (@returncode = 0)
begin
	/*
	** 17720, "Error:  Unable to set the Password."
	*/
	raiserror 17720
	return (1)
end
else
begin
	/*
	** Before we log our system procedure execution instance,
	** re-initialize the '@caller_password' parameter to NULL and the
	** '@new_password' parameter to the encrypted form of the password.
	** This prevents the passwords from being stored in clear text in
	** the transaction log as well as in the Replication Server stable
	** queues.
	**
	** When the ASE RepAgent Thread sends the system procedure
	** execution instance to the Replication Server, the ASE RepAgent
	** will re-name the system procedure from 'sp_password()' to
	** 'sp_password_rep()'.  This will cause the Replication Server to
	** execute, at the target ASE, the system procedure
	** 'sp_password_rep()' which knows how to properly process the
	** encrypted password.
	*/
	select @caller_password = NULL

	if (@loginame is not NULL)
	begin
		select @new_password = password
		from master.dbo.syslogins
		where name = @loginame
	end
	else
	begin
		select @new_password = password
		from master.dbo.syslogins
		where suid = suser_id()
	end

	/*
	** If the 'master' database is marked for replication, the T-SQL
	** built-in 'logexec()' will log for replication the execution
	** instance of this system procedure.  Otherwise, the T-SQL
	** built-in 'logexec()' is a no-op.
	*/
	if (logexec(1) != 1)
	begin
		raiserror 17756, "sp_password", "master"
		return (1)
	end

	/*
	** 17721, "Password correctly set."
	*/
	exec sp_getmessage 17721, @msg output
	print @msg
	return (0)
end

go
exec sp_procxmode 'sp_password', 'anymode'
go
grant execute on sp_password to public
go
exec sp_procxmode 'sp_password', 'rep_master'
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_addlogin')
begin
	drop procedure sp_addlogin
end
go
print "Installing sp_addlogin"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/addlogin */

/*
** Generated by spgenmsgs.pl on Thu Feb  2 00:39:14 2006 
*/
/*
** raiserror Messages for addlogin [Total 12]
**
** 17201, "'%1!' is not an official language name from syslanguages."
** 17240, "'%1!' is not a valid name."
** 17260, "Can't run %1! from within a transaction."
** 17262, "A user with the specified login name already exists."
** 17263, "Database name not valid -- login not added."
** 17265, "A role with the specified name '%1!' already exists in this Server."
** 17267, "Invalid value specified for %1! option. Login not created."
** 17756, "The execution of the stored procedure '%1!' in database '%2!' was aborted because there was an error in writing the replication log record."
** 18409, "The built-in function %1! failed. Please see the other messages printed along with this message."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on the companion server '%2!'."
** 18881, "Unable to generate %1! for HA use. Please Refer to documentation for details."
** 19257, "The authentication mechanism '%1!' is not valid."
** 19822, "A local temporary database is not permitted as the default database for a login."
*/
/*
** sp_getmessage Messages for addlogin [Total 3]
**
** 17262, "A user with the specified login name already exists."
** 17264, "New login created."
** 19259, "Warning. Authentication mechanism '%1!' is not enabled."
** 19446, "A login mapping for the name '%1!' already exists in this Server.
**		Drop an existing mapping before creating a new mapping."
** 19448, "An existing login mapping for user '%1!' allows only '%2!' authentication mechanism to be used."
*/
/*
** End spgenmsgs.pl output.
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_addlogin
@loginame varchar(255),			/* login name of the new user */
@passwd varchar(256) = NULL,		/* password of the new user */
@defdb varchar(255) = "master",		/* default db for the new user */
@deflanguage varchar(255) = NULL,	/* default language for the new user */
@fullname varchar(255) = NULL,		/* account owner's full name */
@passwdexp int = NULL,			/* value of password expiration */
@minpwdlen int = NULL,			/* value of minimum password 
					** length 
					*/
@maxfailedlogins int = NULL,		/* value of maximum failed 
					** logins
					*/
@auth_mech varchar(30) = "ANY"		/* Authentication mechanism */
as

declare @msg varchar(1024)
declare @dummy int,
	@passeclass int,		/* Class id in Sysattributes */
	@attrib int,			/* attribute id in 
					** Sysatttributes
					*/
	@action int,			/* Insert, update or delete 
					** Sysattributes entry
					*/
	@retstat int,
	@insertsuid int,		/* suid corresponding to 
					** insert slot in Syslogins
					*/
	@HA_CERTIFIED tinyint,		/* Is the SP HA certified ? */
	@authid int,			/* auth mechanism id */
	@config int,			/* Config option for external
					** authentication mechanisms.
					*/
	@status	int,			/* Syslogins status */
	@curname varchar(30),		/* To retrieve name from syslogins */
	@login_class int,		/* To retrieve mapping from
					** sysattributes. 
					*/
	@login_attrib int,		/* To retrieve mapping */
	@map_authid int,		/* sp_maplogin auth mechanism id */
	@map_authnm  varchar(30),	/* sp_maplogin auth mechanism name */

	@maxlen int,
	@log_for_rep int,
	@db_rep_level_all int,
	@db_rep_level_none int,
	@db_rep_level_l1 int,
	@lt_rep_get_failed int

declare sync_cursor cursor for select name from master.dbo.syslogins holdlock for update

/*
** Initialize some constants
*/
select @db_rep_level_all = -1,
       @db_rep_level_none = 0,
       @db_rep_level_l1 = 1,
       @lt_rep_get_failed = -2

select @HA_CERTIFIED = 0	


/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @rtn_code int
declare @error_save int
declare @set_cis_rpc_handling int

select @nHARSTClass = ha_getrestrictionclass("sp_addlogin")
if (@nHARSTClass = -1)
	return (1)

select @rtn_code = 0
select @error_save = 0
select @set_cis_rpc_handling = 0
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_addlogin', @HA_CERTIFIED
if (@retstat != 0)
	return (1)


/*
** Do not allow this system procedure to be run from within a transaction
** to avoid creating a multi-database transaction where the 'master'
** database is not the co-ordinating database.
*/
if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction."
	*/
	raiserror 17260, "sp_addlogin"
	return (1)
end
else
begin
	set chained off
end
set transaction isolation level 1

/*
** Get the replication status of the 'master' database
*/
select @log_for_rep = getdbrepstat(1) 
if (@log_for_rep = @lt_rep_get_failed)
begin
	raiserror 18409, "getdbrepstat"
	return (1)
end

/*
** Convert the replication status to a boolean
*/
if (@log_for_rep != @db_rep_level_none)
	select @log_for_rep = 1
else
	select @log_for_rep = 0

/*
** If we are logging this system procedure for replication, we must be in
** the 'master' database to avoid creating a multi-database transaction
** which could make recovery of the 'master' database impossible.
*/
if (@log_for_rep = 1) and (db_name() != "master")
begin
	raiserror 18388, "sp_addlogin"
	return (1)
end

/* check if user has sso role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/

if (proc_role("sso_role") = 0)
	return (1)

declare @returncode	int

/*
**  Check to see that the @loginame is valid.
*/
if (@loginame is not null)
begin
	select @maxlen = length from master.dbo.syscolumns
	where id = object_id("master.dbo.syslogins") and name = "name"

	if valid_name(@loginame, @maxlen) = 0
	begin
		/*
		** 17240, "'%1!' is not a valid name." 
		*/
		raiserror 17240, @loginame
		return 1
	end
end

/*
** Check to see that the @fullname is valid.
*/
if (@fullname is not NULL) 
begin
	select @maxlen = length from master.dbo.syscolumns
	where id = object_id("master.dbo.syslogins") and name = "fullname"

	if char_length(@fullname) > @maxlen
	begin
		/*
		** 17240, "'%1!' is not a valid name."
		*/
		raiserror 17240, @fullname
		return 1
	end
end

if @deflanguage is not null
begin
	select @returncode = 0
	execute @returncode = sp_validlang @deflanguage
	if @returncode != 0
	begin
		/* Us_english is always valid */
		if @deflanguage != "us_english"
		begin
			/*
			** 17201, "'%1!' is not an official language name from Syslanguages." 
			*/
			raiserror 17201, @deflanguage
			return @returncode
		end
	end
end

open sync_cursor
/*
** To serialize concurrent sp_addlogin requests
*/
fetch sync_cursor into @curname

/*
**  Make sure the login doesn't already exist.
*/
if exists (select *
	from master.dbo.syslogins (index ncsyslogins)
	where name = @loginame)
begin
	/*
	** 17262, "A user with the specified login name already exists."
	*/
	raiserror 17262
	return (1)
end

/*
** Make sure role doesn't already exist with this name.
*/
if exists (select * 
	from master.dbo.syssrvroles
	where name = @loginame)
begin
	/*
	** 17265, "A role with the specified name '%1!' already exists in this
	**	   Server."
	*/
	raiserror 17265, @loginame
	return (1)
end

/*
** Make sure a login mapping doesn't already exist for this name.
** Prevent a login from being added if there already exists a 
** mapping that may obscure the login. This helps to avoid
** another way to alias a user within ASE.
*/
select @login_class = 20, @login_attrib = 0

if exists (select 1 from master.dbo.sysattributes where
			class = @login_class and attribute = @login_attrib and 
			object_cinfo = @loginame)
begin	
	/*
	** 19446, "A login mapping for the name '%1!' already exists in this
	**	   Server.  Drop an existing mapping before creating a new 
	**	   mapping."
	*/
	raiserror 19446, @loginame
	return (1)
end

/*
**  Check that the database name is valid.
**  If it was specified as NULL then default it to "master".  Note that this
**  can happen for 'sp_addlogin peter, password, null, null, "peter rabbit"'
**  but not for 'sp_addlogin peter, password, @fullname = "peter rabbit"'.
*/
if @defdb is NULL
begin
	select @defdb = "master"
end

if not exists (select *
	from master.dbo.sysdatabases
	where name = @defdb)
begin
	/*
	** 17263, "Database name not valid -- login not added."
	*/
	raiserror 17263
	return (1)
end

/*
**  Check that the database name is useable on all instances of cluster.
**  If specified default database is a local temporary database then
**  fail the command to avoid problems at connection time.
*/
if db_instanceid(db_id(@defdb)) is not null
begin
	/*
	** 19822, "A local temporary database is not permitted as the 
	** default database for a login."
	*/
	raiserror 19822
	return (1)
end

/* Assign the class number for the 
** PASSWORD_SECURITY class in
** master.dbo.sysattributes
*/
select @passeclass = class from master.dbo.sysattributes 
where object_type = "PS"


if (@nHARSTClass = 1)
begin
	begin tran ha_dynsyn

	exec @rtn_code = sp_halockclustertables "sp_addlogin"
	if (@rtn_code != 0)
		goto clean_all
end


exec @retstat = sp_gen_login_id @loginame, @insertsuid output
if (@retstat != 0)
	goto clean_all


if (@nHARSTClass = 1)
begin
	/*
	**  HA consistency checking: Make sure the login doesn't already exist
	**  on the companion server.
	*/
	if exists (select 1 from master.dbo.rmt_ha_syslogins
			where name = @loginame)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		raiserror 18773, "sp_addlogin", @@hacmpservername

		/*
		** 17262, "A user with the specified login name already exists."
		*/
		exec sp_getmessage 17262, @msg output
		print @msg

		goto clean_all
	end

	/* 
	** When there is an ID confliction on the companion server,
	** generate ID on the companion server, then see if the new one works
	** locally.
	*/
	if exists (select 1 from master.dbo.rmt_ha_syslogins
			where suid = @insertsuid)
	begin
		if (@@cis_rpc_handling = 0)
		begin
			set cis_rpc_handling on
			select @set_cis_rpc_handling = 1
		end

 		exec @rtn_code = SYB_HACMP.sybsystemprocs.dbo.sp_gen_login_id
					@loginame, @insertsuid output
		select @error_save = @@error

		if (@set_cis_rpc_handling = 1)
			set cis_rpc_handling off
	
		if ((@rtn_code != 0) or (@error_save != 0))
			goto clean_all

		if exists (select 1 from master.dbo.syslogins (index syslogins)
			where suid = @insertsuid)
		begin
			/*
			** 18881, "Unable to generate %1! for HA use. 
			** Please Refer to documentation for details."
			*/
			raiserror 18881, "suid"
			goto clean_all
		end
	end
end

  
/*
** delete entries for local mapped logins 
** from sysattributes for this login.  
** This will cleanup the rows having stale object suid 
** equal to this newly generated suid (insertsuid) 
*/
delete from master.dbo.sysattributes
	where object = @insertsuid
	and object_type = "LM"


	if (@@error != 0)
		goto clean_all

	if (@nHARSTClass = 1)
	begin
		delete from master.dbo.rmt_ha_sysattributes
			where object = @insertsuid
			and object_type = "LM"
		if (@@error != 0) 
			goto clean_all
	end


/* If any of the password options have been
** specified, check for validity & insert
** appropriate entry in Sysattributes
*/
if @passwdexp is not NULL
begin
	select  @attrib = 0,
		@action = 1
	if attrib_valid(@passeclass, @attrib, "PS", @insertsuid, 
		NULL, NULL, NULL, "login", @passwdexp, NULL, NULL, NULL,
		NULL, @action) = 0
	begin
		/*
		** 17267, "Invalid 'password expiration' attribute specified.
		** Login not created."
		*/
		raiserror 17267, "password expiration"
		goto clean_all
	end
	else
	begin
		insert into master.dbo.sysattributes(class, attribute,
			object_type, object_cinfo, object, int_value)
		values
		(@passeclass, @attrib, "PS", "login", @insertsuid, @passwdexp)


		if (@@error != 0)
			goto clean_all
	
		if (@nHARSTClass = 1)
		begin
			insert into master.dbo.rmt_ha_sysattributes
				(class, attribute,
				object_type, object_cinfo, object, int_value)
			  values
				(@passeclass, @attrib, "PS", "login", 
				@insertsuid, @passwdexp)
	
			if (@@error != 0)
				goto clean_all
		end

	
	end
end

if @minpwdlen is not NULL
begin
        select  @attrib = 1,
		@action = 1
        if attrib_valid(@passeclass, @attrib, "PS", @insertsuid, 
                NULL, NULL, NULL, "login", @minpwdlen, NULL, NULL, NULL,
                NULL, @action) = 0
        begin
		/* 
		** 17267, "Incorrect 'minimum password length' attribute
		** specified. Login not created."
		*/
		raiserror 17267, "minimum password length"
                goto clean_all
        end
        else
	begin
                insert into master.dbo.sysattributes(class, attribute,
                        object_type, object_cinfo, object, int_value)
                values
                (@passeclass, @attrib, "PS", "login", @insertsuid, 
			@minpwdlen)


		if (@@error != 0)
			goto clean_all
	
		if (@nHARSTClass = 1)
		begin
			insert into master.dbo.rmt_ha_sysattributes
				(class, attribute,
				object_type, object_cinfo, object, int_value)
			  values
				(@passeclass, @attrib, "PS", "login", 
				@insertsuid, @minpwdlen)
	
			if (@@error != 0)
				goto clean_all
		end


	end
end


if @maxfailedlogins is not NULL
begin
        select  @attrib = 2,
		@action = 1
        if attrib_valid(@passeclass, @attrib, "PS", @insertsuid, 
                NULL, NULL, NULL, "login", @maxfailedlogins, NULL, NULL, 
                NULL, NULL, @action) = 0
        begin
		/* 
		** 17267, "Incorrect 'maximum failed logins' specified.
		** Login not created."
		*/
		raiserror 17267, "maximum failed logins"
		goto clean_all
        end
        else
	begin
	        insert into master.dbo.sysattributes(class, attribute,
                        object_type, object_cinfo, object, int_value)
                values
                (@passeclass, @attrib, "PS", "login", @insertsuid, 
			@maxfailedlogins)


		if (@@error != 0)
			goto clean_all
	
		if (@nHARSTClass = 1)
		begin
			insert into master.dbo.rmt_ha_sysattributes
				(class, attribute, object_type, 
					object_cinfo, object, int_value)
			  values
				(@passeclass, @attrib, "PS", "login", 
					@insertsuid, @maxfailedlogins)
	
			if (@@error != 0)
				goto clean_all
		end


	end
end

/*
** Check whether authentication mechanism specified is valid or not.
** 'AUTH_DEFAULT' and 'AUTH_MASK' are new values added in spt_values
** used to obtain value of default ('ANY') authmech or authentication
** mask respectively. They are not valid names that the user can specify
** as authentication mechanism.
*/
select  @authid = low, @config = number
from master.dbo.spt_values
where type = 'ua' and name = upper(@auth_mech) and
upper(@auth_mech) not in ('AUTH_DEFAULT', 'AUTH_MASK')

if @@rowcount = 0
begin
	/*
	** 19257, "The authentication mechanism '%1!' is not valid."
	*/
	raiserror 19257, @auth_mech
	goto clean_all
end

/*
** If authmech is 'ANY', then obtain the value of default authmech
** 'ASE_DEFAULT' defined in spt_values.
*/
if (upper(@auth_mech) = "ANY")
begin
	select @authid = low from master.dbo.spt_values
		where type = 'ua' and name = "AUTH_DEFAULT"
end

/*
** Check if the authentication method is enabled.
*/
if (@config != 0) and not exists(select 1
	from master.dbo.syscurconfigs a
	where a.config = @config and a.value != 0)
begin
	/*
	** 19259, "Warning. Authentication mechanism '%1!' is not enabled."
	*/
	exec sp_getmessage 19259, @msg output
	print @msg, @auth_mech
end

/* Set status to LOGIN_LOCKED | Authentication mask */
select @status = 2 | @authid 

/*
**  Create the login.  Lock the account temporarily and
**  Put in a dont-care NULL as password.
*/
insert into master.dbo.syslogins (suid, status, accdate, totcpu, totio,
        spacelimit, timelimit, resultlimit,
        dbname, name, password, language,
        pwdate, audflags, fullname)
values ( @insertsuid, @status, getdate(), 0, 0, 0, 0, 0,
        @defdb, @loginame , NULL, @deflanguage,
        getdate(), 0, @fullname )


if (@@error != 0)
	goto clean_all

if (@nHARSTClass = 1)
begin
	insert into master.dbo.rmt_ha_syslogins (suid, status, accdate, 
		totcpu, totio, spacelimit, timelimit, resultlimit,
		dbname, name, password, language,
		pwdate, audflags, fullname)
	  values ( @insertsuid, @status, getdate(), 0, 0, 0, 0, 0,
		@defdb, @loginame , NULL, @deflanguage,
		getdate(), 0, @fullname )

	if (@@error != 0)
		goto clean_all
end
	



if (@nHARSTClass = 1)
	commit tran ha_dynsyn


/*
**  Encrypt and store the input password
*/
execute @returncode = sp_password NULL, @passwd, @loginame


if (@@error != 0)
	select @returncode = 1


if (@returncode = 0)
begin
	/*
	** Before we log our system procedure execution instance,
	** re-initialize the '@password' parameter to the encrypted form of
	** the password.  This prevents the password from being stored in
	** clear text in the transaction log as well as in the Replication
	** Server stable queues.
	**
	** When the ASE RepAgent Thread sends the system procedure
	** execution instance to the Replication Server, the ASE RepAgent
	** will re-name the system procedure from 'sp_addlogin()' to
	** 'sp_addlogin_rep()'.  This will cause the Replication Server to
	** execute, at the target ASE, the system procedure
	** 'sp_addlogin_rep()' which knows how to properly process the
	** encrypted password.
	*/
	select @passwd = password
	from master.dbo.syslogins
	where suid = @insertsuid

	/*
	** If the 'master' database is marked for replication, the T-SQL
	** built-in 'logexec()' will log for replication the execution
	** instance of this system procedure.  Otherwise, the T-SQL
	** built-in 'logexec()' is a no-op.
	*/
	if (logexec(1) != 1)
	begin
		raiserror 17756, "sp_addlogin", "master"
		select @returncode = 1
	end
end

if @returncode = 0
begin
	/* UN-lock the account after successful update */
	/* except in case of user sybmail a MAPI requirement. */
	if (@loginame != "sybmail")
	begin
		execute @returncode = sp_locklogin @loginame, "unlock"

	end
end
else
begin
	/*
	** Delete relevant syslogins and sysattribute login information
	** for this login, in order to backout.
	*/
	delete from master.dbo.syslogins where name = @loginame
	delete from master.dbo.sysattributes 
		where class = @passeclass AND object = @insertsuid
		AND object_cinfo = "login"


	if (@nHARSTClass = 1)
	begin
	        delete from master.dbo.rmt_ha_syslogins where name = @loginame
	        delete from master.dbo.rmt_ha_sysattributes
	                where class = @passeclass AND object = @insertsuid
	                AND object_cinfo = "login"
	end


end

if @returncode = 0
                begin
                        /*
                        ** 17264, "New login created."
                        */
                        exec sp_getmessage 17264, @msg output
                        print @msg
                end

close sync_cursor
deallocate cursor sync_cursor
return (@returncode)

clean_all:

	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn

	return (1)
go
exec sp_procxmode 'sp_addlogin', 'anymode'
go
grant execute on sp_addlogin to public
go
exec sp_procxmode 'sp_addlogin', 'rep_master'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_droplogin')
begin
	drop procedure sp_droplogin
end
go
print "Installing sp_droplogin"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/droplogin */

/*
** Generated by spgenmsgs.pl on Thu Feb  2 00:39:16 2006 
*/
/*
** raiserror Messages for droplogin [Total 10]
**
** 17231, "No login with the specified name exists."
** 17260, "Can't run %1! from within a transaction."
** 17509, "User exists or is an alias or is a database owner in at least one database. Drop the user or the alias, or change the database ownership before dropping the login."
** 17756, "The execution of the stored procedure '%1!' in database '%2!' was aborted because there was an error in writing the replication log record."
** 17880, "No such account -- nothing changed."
** 18013, "Cannot lock the last remaining unlocked SA account."
** 18388, "You must be in the master database in order to run '%1!'."
** 18409, "The built-in function '%1!' failed. Please see the other messages printed along with this message."
** 18553, "Login '%1!' cannot be dropped because it has execution class bindings. Use sp_unbindexeclass before dropping login."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on the companion server '%2!'."
** 19587, "User exists or is an alias or is a database owner in %1! database(s)."
*/
/*
** sp_getmessage Messages for droplogin [Total 5]
**
** 17511, "Login dropped."
** 17915, "Warning: the specified account is currently active."
** 17918, "Nothing changed."
** 18553, "Login '%1!' cannot be dropped because it has execution class bindings. Use sp_unbindexeclass before dropping login."
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins."
*/
/*
** End spgenmsgs.pl output.
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_droplogin
@loginame varchar(255)		/* name of login account to drop */
as
declare @msg varchar (1024)
declare @suid int		/* suid of person to change pw on    */
declare @returncode int
declare @dummy int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int
declare @log_for_rep int
declare @db_rep_level_all int
declare @db_rep_level_none int
declare @db_rep_level_l1 int
declare @lt_rep_get_failed int
declare @dbname varchar(255)    /* Variable to store database name */
declare @temp_val int           /* Temporary variable */
declare @valid_user int         /* Stores if user is valid in any database */
declare @valid_dbnames varchar(2000) /* Stores all database names in
                                     ** which user is valid
                                     */
declare @scope varchar(32)	/* SDC only, command execution scope */
declare @instanceid int		/* SDC only, ID of owning instance of database */

/*
** Initialize some constants
*/
select @db_rep_level_all = -1,
       @db_rep_level_none = 0,
       @db_rep_level_l1 = 1,
       @lt_rep_get_failed = -2

/*
** Get the replication status of the 'master' database
*/
select @log_for_rep = getdbrepstat(1) 
if (@log_for_rep = @lt_rep_get_failed)
begin
	raiserror 18409, "getdbrepstat"
	return (1)
end

/*
** Convert the replication status to a boolean
*/
if (@log_for_rep != @db_rep_level_none)
	select @log_for_rep = 1
else
	select @log_for_rep = 0

/*
** If we are logging this system procedure for replication, we must be in
** the 'master' database to avoid creating a multi-database transaction
** which could make recovery of the 'master' database impossible.
*/
if (@log_for_rep = 1) and (db_name() != "master")
begin
	raiserror 18388, "sp_droplogin"
	return (1)
end

select @HA_CERTIFIED = 0


/* Dynamic synchronization related variables declaration and initialization */
declare @set_cis_rpc_handling int
declare @nHARSTClass	int
declare @error_save	int

select @error_save = 0
select @set_cis_rpc_handling = 0
select @nHARSTClass = ha_getrestrictionclass("sp_droplogin")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_droplogin', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
**  This procedure makes a weak attempt to check for any dependencies.
**  It looks in the current database to see if the suid is used in
**  sysusers or sysalternates.  If so, a diagnostic is issued and the
**  login is not dropped.
**
**  Ideally, this procedure should check each database to see if the login
**  is a user.  However, this is not yet possible since procedures do not
**  allow parameters to be used for database or table names.
*/

/*
** Do not allow this system procedure to be run from within a transaction
** to avoid creating a multi-database transaction where the 'master'
** database is not the co-ordinating database.
*/
if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_droplogin"
	return (1)
end
else
begin
	set chained off
end

set transaction isolation level 1

/* check if user has sso role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/
if (proc_role("sso_role") = 0)
	return (1)

/*
**  Check if the account exists
*/
select @suid = suid 
	from master.dbo.syslogins
	where name = @loginame
if @suid is NULL
begin
        /*
        ** 17880, "No such account -- nothing changed."
        */
	raiserror 17880
        return (1)
end

/*
** Declare a read only cursor to select all the database names
** in master.dbo.sysdatabases
*/
declare drop_login cursor for
select name from master.dbo.sysdatabases

for read only

/* Open the cusor to fetch the content in local variable */
open drop_login

fetch drop_login into @dbname

while @@sqlstatus <> 2
begin
        if @@sqlstatus = 1
        begin
                /*
                ** 18999, "An error occurred while fetching data from a temporary
                ** table. If there are no other error messages and this error
                ** persists, please contact Sybase Technical Support."
                */
                raiserror 18999
                close drop_login
                deallocate cursor drop_login
                return (1)
        end

	/*
	** SDC only, skip the local temporary database belonging to other nodes
	*/
	if (@@clustermode = "shared disk cluster")
	begin
		/*
		** Get the ID of the owning instance if the specified database
		** is a local temporary database
		*/
		select @instanceid = db_instanceid(@dbname)
		if ( (@instanceid is not null)  and (@instanceid <> @@instanceid) )
		begin
			fetch drop_login into @dbname
			continue
		end
	end

        select @temp_val = 0

        /*
	** while executing sp_is_valid_user last parameter(mode parameter) is 2,
	** to ignore sa_role check since sso_role checking is already performed before
	*/
	exec sp_is_valid_user @temp_val output, @dbname, @loginame, 2

        if (@temp_val = 1 or @temp_val > 2)
        begin
                select @valid_dbnames = @valid_dbnames + "'" + @dbname + "'" + " "
                select @valid_user = 1
        end

        fetch drop_login into @dbname
end
close drop_login
deallocate cursor drop_login

/* return if user is valid in any database */
if @valid_user = 1
begin
        /* 19587, "User exists or is an alias or is a database owner in %1! database(s)." */
        raiserror 19587, @valid_dbnames
        return (1)
end

/*
** SDC only, check clusterwide sysprocesses for active login
*/
if (@@clustermode = "shared disk cluster")
begin
	select @scope=@@system_view
	set system_view cluster
end

/*
**  Disallow dropping an account who has already logged in.
**  Note that it eliminates the race condition between two processes
**  for checking the last remaining unlocked SSO account.
*/
if exists (select * from master.dbo.sysprocesses where suid = @suid)
begin
	/*
	** SDC only, restore previous system_view scope
	*/
	if (@@clustermode = "shared disk cluster")
	begin
		set system_view @scope
	end

	/* 17915,
	** "Warning: the specified account is currently active."
	*/
	exec sp_getmessage 17915, @msg output
	print @msg
	/*
	** 17918, "Nothing changed."
	*/
	exec sp_getmessage 17918, @msg output
	print @msg
	return (1)
end
/*
** SDC only, restore previous system_view scope
*/
if (@@clustermode = "shared disk cluster")
begin
	set system_view @scope
end


if (@nHARSTClass = 1)
begin
    /* HA consistency checking */
	/* Make sure the login already exist on the companion server. */
	if not exists (select 1 from master.dbo.rmt_ha_syslogins
			where name = @loginame and suid = @suid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		raiserror 18773, "sp_droplogin", @@hacmpservername

                /*
                ** 18778, "Unable to find login '%1!' with id '%2!'
                ** in syslogins.
                */
                exec sp_getmessage 18778, @msg output
                print @msg, @loginame, @suid

                return (1)
        end

	/* 
	** Some consistency checking cannot be done with proxy table. 
	** Do it via remote rpc call.
	*/ 
	/* Enable cis_rpc_handling to make remote call */
	if (@@cis_rpc_handling = 0)
	begin
		set cis_rpc_handling on
		select @set_cis_rpc_handling = 1
	end

	exec @retstat = SYB_HACMP.sybsystemprocs.dbo.sp_ha_verification
				"sp_droplogin", @loginame
	select @error_save = @@error

	if (@set_cis_rpc_handling = 1)
		set cis_rpc_handling off

	/*
	** We want to catch error reported by either @retstat or
	** @@error and save the error code in @retstat if any
	*/
	if (@error_save != 0)
		return (1)
	
	if (@retstat != 0)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		raiserror 18773, "sp_droplogin", @@hacmpservername
		return (1)
	end
end




/*
**  Lock the account to prevent it from begin active.
*/
execute @returncode = sp_locklogin @loginame, "lock"

select @error_save = @@error
if (@error_save != 0)
	return (@error_save)

if (@returncode != 0)
	return (@returncode)

if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
	begin tran rs_logexec


if (@nHARSTClass = 1)
begin
	exec @returncode = sp_halockclustertables "sp_droplogin"
	if (@returncode != 0)
		goto clean_all
end


/* remove all resource limits associated with this login */
delete from master.dbo.sysresourcelimits where name = @loginame

if (@@error != 0) goto clean_all


/*
**  Delete the login.
*/
delete from master.dbo.syslogins
	where name = @loginame

/*
**  Check @@rowcount when it works
*/
if (@@rowcount > 0)
begin
	/* remove all roles related information from sysloginroles */
	delete from master.dbo.sysloginroles
		where suid = @suid

	if (@@error != 0) goto clean_all


	/*
	** delete entries from sysattributes for this login.
	** login entries are type 'PS'; login entries are 
	** type 'L' or external login entries are type 'EL';
	** login entries for local mapped logins
	** are type 'LM'
	*/
	delete from master.dbo.sysattributes
		where object = @suid
		and object_type in ("EL", "L", "LM")

	if (@@error != 0) goto clean_all


	delete from master.dbo.sysattributes
		where object_type = "PS" and object_cinfo = "login"
		and object = @suid

	if (@@error != 0) goto clean_all


	/*
	** Delete any bindings associated with the login.
	*/
	delete from master.dbo.sysattributes
		where (     (class = 6 or class = 16) 
			and (    (     object_type = "LG" 
				   and object = @suid)
			      or (     object_type = "AP" 
			           and object_info1 = @suid)))

	if (@@error != 0) goto clean_all


	/* delete entries in sysremotelogins for this login */
	delete from master.dbo.sysremotelogins
		where suid = @suid


        if (@@error != 0) goto clean_all
	
	/* Operate according to the HA restriction class */
        if (@nHARSTClass = 1)
        begin
                /* remove all resource limits associated with this login */
		delete from master.dbo.rmt_ha_sysresourcelimits 
			where name = @loginame
		if (@@error != 0) goto clean_all

		/* Delete the login.  */
		delete from master.dbo.rmt_ha_syslogins
	         	where name = @loginame
		if (@@error != 0) goto clean_all

		/*
		**  Check @@rowcount when it works
		** Actually, no need to check it because within this branch
		** it is assured
		*/
        	delete from master.dbo.rmt_ha_sysloginroles
                	where suid = @suid
		if (@@error != 0) goto clean_all
        
        	/*
		** delete entries from sysattributes for this login
		** login entries are type 'PS'; login entries are 
		** type 'L' or external login entries are type 'EL'
		** login entries for local mapped logins are type 'LM'
		*/
		delete from master.dbo.rmt_ha_sysattributes
			where object = @suid
			and object_type in ("EL", "L", "LM")
		if (@@error != 0) goto clean_all

		delete from master.dbo.rmt_ha_sysattributes
	        	where object_type = "PS" and object_cinfo = "login"
	                and object = @suid
		if (@@error != 0) goto clean_all

		/*
		** Delete any bindings associated with the login.
		*/
		delete from master.dbo.rmt_ha_sysattributes
			where (     (class = 6 or class = 16) 
				and (    (     object_type = "LG" 
					   and object = @suid)
				      or (     object_type = "AP" 
				           and object_info1 = @suid)))
		if (@@error != 0) goto clean_all

        	/* delete entries in sysremotelogins for this login */
		delete from master.dbo.rmt_ha_sysremotelogins
       			where suid = @suid
		if (@@error != 0) goto clean_all
        end 



	if (@log_for_rep = 1)
	begin
		/*
		** If the 'master' database is marked for replication, the
		** T-SQL built-in 'logexec()' will log for replication the
		** execution instance of this system procedure.  Otherwise,
		** the T-SQL built-in 'logexec()' is a no-op.
		*/
		if (logexec(1) != 1)
		begin
			raiserror 17756, "sp_droplogin", "master"
			goto clean_all
		end
	end

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		commit tran rs_logexec

	/*
	** Run the custom clean up procedure
	*/
	if exists (select 1 from master.dbo.sysobjects where name = 
		'sp_cleanpwdchecks')
	begin
		exec("exec master.dbo.sp_cleanpwdchecks @loginame")
	end

	/*
	** 17511, "Login dropped."
	*/
	exec sp_getmessage 17511, @msg output
	print @msg
	return (0)
end
else
begin
	/*
	** 17231, "No login with the specified name exists."
	*/
	raiserror 17231
	goto clean_all
end

clean_all:
	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		rollback tran rs_logexec
	return (1)
go
exec sp_procxmode 'sp_droplogin', 'anymode'
go
grant execute on sp_droplogin to public
go
exec sp_procxmode 'sp_droplogin', 'rep_master'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_defaultdb')
begin
	drop procedure sp_defaultdb
end
go
print "Installing sp_defaultdb"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.2	28.1	05/14/90	sproc/src/defaultdb */

/*
** Generated by spgenmsgs.pl on Thu Feb  2 00:39:15 2006 
*/
/*
** raiserror Messages for defaultdb [Total 7]
**
** 17231, "No login with the specified name exists."
** 17260, "Can't run %1! from within a transaction."
** 17440, "Database name not valid -- default not changed."
** 17443, "Error in updating the default database."
** 17445, "Cannot change default database since login trigger for user '%1!' is currently active."
** 17756, "The execution of the stored procedure '%1!' in database '%2!' was aborted because there was an error in writing the replication log record."
** 18388, "You must be in the master database in order to run '%1!'."
** 18409, "The built-in function %1! failed. Please see the other messages printed along with this message."
** 19822, "A local temporary database is not permitted as the default database for a login."
*/
/*
** sp_getmessage Messages for defaultdb [Total 4]
**
** 17442, "Default database changed."
** 17444, "Automatic login script for user '%1!' is disabled. Use sp_modifylogin to enable execution of auto login script for the new database."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on the companion server '%2!'."
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins."
*/
/*
** End spgenmsgs.pl output.
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_defaultdb
@loginame varchar(30),			/* login name of the user */
@defdb varchar(30) 			/* default db for the user */
as

declare @msg varchar(1024)
declare @rtn_code int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int
declare @dummy int
declare @sa_role int	/* has sa role */
declare @sso_role int	/* has sso role */

declare @log_for_rep int
declare @db_rep_level_all int
declare @db_rep_level_none int
declare @db_rep_level_l1 int
declare @lt_rep_get_failed int

/*
** Initialize some constants
*/
select @db_rep_level_all = -1,
       @db_rep_level_none = 0,
       @db_rep_level_l1 = 1,
       @lt_rep_get_failed = -2

select @HA_CERTIFIED = 0

select @sa_role = charindex("sa_role", show_role()),
	@sso_role = charindex ("sso_role", show_role())


/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int
declare @suid int

select @nHARSTClass = ha_getrestrictionclass("sp_defaultdb")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_defaultdb', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
** Do not allow this system procedure to be run from within a transaction
** to avoid creating a multi-database transaction where the 'master'
** database is not the co-ordinating database.
*/
if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction."
	*/
	raiserror 17260, "sp_defaultdb"
	return (1)
end
else
begin
	set chained off
end

set transaction isolation level 1

/*
** Get the replication status of the 'master' database
*/
select @log_for_rep = getdbrepstat(1) 
if (@log_for_rep = @lt_rep_get_failed)
begin
	raiserror 18409, "getdbrepstat"
	return (1)
end

/*
** Convert the replication status to a boolean
*/
if (@log_for_rep != @db_rep_level_none)
	select @log_for_rep = 1
else
	select @log_for_rep = 0

/*
** If we are logging this system procedure for replication, we must be in
** the 'master' database to avoid creating a multi-database transaction
** which could make recovery of the 'master' database impossible.
*/
if (@log_for_rep = 1) and (db_name() != "master")
begin
	raiserror 18388, "sp_defaultdb"
	return (1)
end

/*
**  Only the Account Owner or
**  Accounts with SA role or SSO role can execute it.
**  proc_role will also do auditing if required and
**  will also print error message if required.
*/
if ((suser_name() != @loginame) and
		(@sa_role = 0) and (@sso_role = 0))
begin
	select @dummy = proc_role("sa_role")
	select @dummy = proc_role("sso_role")
	return(1)
end
else
begin
	if (@sa_role > 0)
	begin
		select @dummy = proc_role("sa_role")
	end
	if (@sso_role > 0)
	begin
		select @dummy = proc_role("sso_role")
	end
end

/*
**  Check that the account exists.
*/
if not exists (select *
	from master.dbo.syslogins
	where name = @loginame)
begin
	/*
	** 17231, "No login with the specified name exists."
	*/
	raiserror 17231
	return (1)
end

/*
**  Check that the database name is valid.
*/
if not exists (select *
	from master.dbo.sysdatabases
	where name = @defdb)
begin
	/*
	** 17440, "Database name not valid -- default not changed."
	*/
	raiserror 17440
	return (1)
end

/*
**  Check that the database name is useable on all instances of cluster.
**  If specified default database is a local temporary database then
**  fail the command to avoid problems at connection time.
*/
if db_instanceid(db_id(@defdb)) is not null
begin
	/*
	** 19822, "A local temporary database is not permitted as the 
	** default database for a login."
	*/
	raiserror 19822
	return (1)
end


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */
	
	select @suid = suser_id(@loginame)
	if not exists (select 1 from master.dbo.rmt_ha_syslogins
		where name = @loginame and suid = @suid)
        begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_defaultdb", @@hacmpservername

		/*
		** 18778, "Unable to find login '%1!' with id '%2!' 
		** in syslogins."
		*/
		exec sp_getmessage 18778, @msg output
		print @msg, @loginame, @suid

                return (1)
        end

	/* We won't verify database availability remotely unless 
	** proxy db option enabled 
	*/
	if (@@crthaproxy = 1)
	begin
		if not exists (select 1 from master.dbo.rmt_ha_sysdatabases
			where name = @defdb)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure 
			** in '%1!' on the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_defaultdb", @@hacmpservername

			/*
			** 17440, "Database name not valid -- default 
			** not changed."
			*/
			raiserror 17440
	
			return (1)
		end
	end


	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		begin tran rs_logexec


	exec @rtn_code = sp_halockclustertables "sp_defaultdb"
	if (@rtn_code != 0)
		goto clean_all
end


/*
** User cannot change the default database if automatic login script
** is enabled.
*/
if exists ( select * from master.dbo.syslogins
		where name = @loginame  and procid is not NULL )
begin
	/*
	** 17445, "Cannot change default database since login trigger for
	** user '%1!' is currently active."
	*/
	exec sp_getmessage 17445, @msg output
	print @msg, @loginame
	return (1)
end

/*
**  Change the database
*/

update master.dbo.syslogins
	set dbname = @defdb, procid = NULL
	where name = @loginame

if @@rowcount = 1
	select @rtn_code = 0
else
	select @rtn_code = 1



        /* Operate according to the HA restriction class */
	if (@rtn_code = 0 and @nHARSTClass = 1)
	begin
		update master.dbo.rmt_ha_syslogins
		        set dbname = @defdb, procid = NULL
		        where name = @loginame
	
		if (@@rowcount != 1)
			select @rtn_code = 1
		begin
			select @rtn_code = 0
		end
                
	end



if (@rtn_code = 0)
begin
	if (@log_for_rep = 1)
	begin
		/*
		** If the 'master' database is marked for replication, the
		** T-SQL built-in 'logexec()' will log for replication the
		** execution instance of this system procedure.  Otherwise,
		** the T-SQL built-in 'logexec()' is a no-op.
		*/
		if (logexec(1) != 1)
		begin
			raiserror 17756, "sp_defaultdb", "master"
			goto clean_all
		end
	end

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		commit tran rs_logexec

	/*
	** 17442, "Default database changed." 
	*/
	exec sp_getmessage 17442, @msg output
	print @msg
	return (0)
end
else
begin
	/*
	** 17443, "Error in updating the default database."
	*/
	raiserror 17443
	goto clean_all
end

return (0)

clean_all:
	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		rollback tran rs_logexec
        return (1)

go
exec sp_procxmode 'sp_defaultdb', 'anymode'
go
grant execute on sp_defaultdb to public
go
exec sp_procxmode 'sp_defaultdb', 'rep_master'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_defaultlanguage')
begin
	drop procedure sp_defaultlanguage
end
go
print "Installing sp_defaultlanguage"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/defaultlanguage */

/*
** Generated by spgenmsgs.pl on Thu Feb  2 00:39:15 2006 
*/
/*
** raiserror Messages for defaultlanguage [Total 7]
**
** 17201, "'%1!' is not an official language name from syslanguages."
** 17260, "Can't run %1! from within a transaction."
** 17451, "This user does not exist.  Run sp_addlogin to add this user in."
** 17453, "Error in changing the default language."
** 17756, "The execution of the stored procedure '%1!' in database '%2!' was aborted because there was an error in writing the replication log record."
** 18388, "You must be in the master database in order to run '%1!'."
** 18409, "The built-in function %1! failed. Please see the other messages printed along with this message."
*/
/*
** sp_getmessage Messages for defaultlanguage [Total 3]
**
** 17452, "%1!'s default language has been changed to %2!."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on the companion server '%2!'."
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins."
*/
/*
** End spgenmsgs.pl output.
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_defaultlanguage
@loginame varchar(30),			/* login name of the user */
@language varchar(30) = NULL		/* default language for the new user */
as

declare @msg varchar(1024)
declare @returncode int
declare @suid int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int
declare @dummy int
declare @sa_role int	/* has sa role */
declare @sso_role int	/* has sso_role */

declare @log_for_rep int
declare @db_rep_level_all int
declare @db_rep_level_none int
declare @db_rep_level_l1 int
declare @lt_rep_get_failed int 

/*
** Initialize some constants
*/
select @db_rep_level_all = -1,
       @db_rep_level_none = 0,
       @db_rep_level_l1 = 1,
       @lt_rep_get_failed = -2

select @HA_CERTIFIED = 0

select @sa_role = charindex("sa_role", show_role()),
	@sso_role = charindex ("sso_role", show_role())


/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int

select @nHARSTClass = ha_getrestrictionclass("sp_defaultlanguage")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_defaultlanguage', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
** Do not allow this system procedure to be run from within a transaction
** to avoid creating a multi-database transaction where the 'master'
** database is not the co-ordinating database.
*/
if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction."
	*/
	raiserror 17260, "sp_defaultlanguage"
	return (1)
end
else
begin
	set chained off
end

set transaction isolation level 1

/*
** Get the replication status of the 'master' database
*/
select @log_for_rep = getdbrepstat(1) 
if (@log_for_rep = @lt_rep_get_failed)
begin
	raiserror 18409, "getdbrepstat"
	return (1)
end

/*
** Convert the replication status to a boolean
*/
if (@log_for_rep != @db_rep_level_none)
	select @log_for_rep = 1
else
	select @log_for_rep = 0

/*
** If we are logging this system procedure for replication, we must be in
** the 'master' database to avoid creating a multi-database transaction
** which could make recovery of the 'master' database impossible.
*/
if (@log_for_rep = 1) and (db_name() != "master")
begin
	raiserror 18388, "sp_defaultlanguage"
	return (1)
end

/* 
**  Check to see that the @language is valid.
*/
if @language is not null
begin
	select @returncode = 0
	execute @returncode = sp_validlang @language
	if @returncode != 0
	begin
		if @language != "us_english"
		begin
			/*
			** 17201, "'%1!' is not a valid official language name." **
			*/
			raiserror 17201, @language
			return @returncode
		end
	end
end

/*
**  Make sure the login already exist.
*/
if not exists (select *
	from master.dbo.syslogins
	where name = @loginame)
begin
	/*
	** 17451, "This user does not exist.  Run sp_addlogin to add this user in."
	*/
	raiserror 17451
	return 1
end

/*
**  Only the Account Owner or
**  Accounts with SA role or SSO role can execute it.
**  proc_role will also do auditing if required and
**  will also print error message if required.
**
*/
if ((suser_id() != suser_id(@loginame)) and
		(@sa_role = 0) and (@sso_role = 0))
begin
	select @dummy = proc_role("sa_role")
	select @dummy = proc_role("sso_role")
	return(1)
end
else
begin
	if (@sa_role > 0)
	begin
		select @dummy = proc_role("sa_role")
	end
	if (@sso_role > 0)
	begin
		select @dummy = proc_role("sso_role")
	end
end


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */
	select @suid = suser_id(@loginame)
	if not exists (select 1 from master.dbo.rmt_ha_syslogins
			where name = @loginame and suid = @suid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_defaultlanguage", @@hacmpservername

		/*
		** 18778, "Unable to find login '%1!' with id '%2!' 
		** in syslogins."
		*/
		exec sp_getmessage 18778, @msg output
		print @msg, @loginame, @suid

		return (1)
	end

	
	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		begin tran rs_logexec


	exec @returncode = sp_halockclustertables "sp_defaultlanguage"
	if (@returncode != 0)
		goto clean_all
end


/*
**  Set the default language for this user.
*/

update master.dbo.syslogins 
	set language = @language
 	where name = @loginame

if (@@rowcount = 1)
begin


        /* Operate according to the HA restriction class */
	if (@nHARSTClass = 1)
	begin
		update master.dbo.rmt_ha_syslogins
		set language = @language
		where name = @loginame

                if (@@error != 0)
			goto clean_all
	end


	if (@log_for_rep = 1)
	begin
		/*
		** If the 'master' database is marked for replication, the
		** T-SQL built-in 'logexec()' will log for replication the
		** execution instance of this system procedure.  Otherwise,
		** the T-SQL built-in 'logexec()' is a no-op.
		*/
		if (logexec(1) != 1)
		begin
			raiserror 17756, "sp_defaultlanguage", "master"
			goto clean_all
		end
	end

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		commit tran rs_logexec

	/*
	** 17452, "%1!'s default language has been changed to %2!."
	*/
	exec sp_getmessage 17452, @msg output
	print @msg, @loginame, @language
	select @returncode = 0
end
else
begin
	/*
	** 17453, "Error in changing the default language."
	*/

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		rollback tran rs_logexec

	raiserror 17453
	select @returncode = 1
end
return (@returncode)

clean_all:
	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		rollback tran rs_logexec
        return (1)

go
exec sp_procxmode 'sp_defaultlanguage', 'anymode'
go
grant execute on sp_defaultlanguage to public
go
exec sp_procxmode 'sp_defaultlanguage', 'rep_master'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_logintrigger')
begin
	drop procedure sp_logintrigger
end
go
print "Installing sp_logintrigger"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */

/*
** Messages for "sp_logintrigger"    
**
** 19388, "Global login trigger updated."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated to the companion 
**	server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for details.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_logintrigger
	@trigname	varchar(256) = NULL
AS
BEGIN

DECLARE	@msg		varchar(1024),
	@authid		int,
	@suid		int,
	@login_class	smallint,
	@attrib		smallint,
	@action		smallint,
	@dummy		int,
	@HA_CERTIFIED	tinyint,   /* Is the SP HA certified ? */
	@retstat	int,
	@config		int,
	@type		char(2),
	@del		int

/*
** The login trigger is stored in sysattributes:
**
**	- class:	20
**	- attribute:	1
**	- type:		'LT'
**	- char_value:	login trigger name. It can include database and
**	  owner, but the total length must be < 256 chars.
**
** If there is a login trigger configured, we will update it, otherwise
** we will insert a new row.
**
** If the trigger name is null, the current trigger name will be displayed.
** If the trigger name is the keyword 'drop', the current trigger will be 
** removed from sysattributes.
**
*/
	select @login_class = 20, @attrib = 1, @type = 'LT'
	if (@trigname is null)
	BEGIN
		select 	'name' = char_value,
			'status' = 
				case when (@@logintrigger is null)
					then 'Disabled'
					else 'Enabled'
				end
		into #tmp
		from master.dbo.sysattributes
		where class = 20 and attribute = 1 and object_type = 'LT'

		exec sp_autoformat 
			@fulltabname = '#tmp',
			@selectlist = '''Global login trigger'' = name, 
				''Status'' = status'
		return 0
	END
		
	
/*
** Only a user with sso_role can set login triggers
*/
	if (proc_role('sso_role') < 1)
		return 1

	select @HA_CERTIFIED = 0
	select @retstat = 0


/* Dynamic synchronization related variables declaration and initialization */

	declare @nHARSTClass    int
	declare @set_cis_rpc_handling int
	declare @error_save	int

	select @set_cis_rpc_handling = 0
	select @error_save = 0

	select @nHARSTClass = ha_getrestrictionclass('sp_logintrigger')
	if (@nHARSTClass = -1)
		return (1)

	select @HA_CERTIFIED = 1



/* check to see if we are using HA specific SP for a HA enabled server */
	exec @retstat = sp_ha_check_certified 'sp_logintrigger', @HA_CERTIFIED
	if (@retstat != 0)
        	return (1)

	if (upper(@trigname) = 'DROP')
		select @del = 1
	else
		select @del = 0
	

/*
** Check whether a login trigger already exists. If it does, update it
** or delete it, depending on the variable @del.
*/
	if exists(select 1 from master.dbo.sysattributes where
			class = @login_class 
			and attribute = @attrib 
			and object_type = @type)
	BEGIN	
		if (@del = 0)
			select @action = 2 	/* update attribute */
		else
			select @action = 3  	/* delete attribute */
	END
	else 
	BEGIN
		if (@del = 0)
			select @action = 1 	/* insert attribute */	
		else
			/* Nothing to delete. */
			return (0)
	END

/*
** First validate the row. 
*/
	if attrib_valid(@login_class, @attrib, 'LT', NULL, NULL, NULL, NULL,
		NULL, NULL, @trigname, NULL, NULL, NULL, @action) = 0         
	BEGIN
		return(1)
	END


if (@nHARSTClass = 1)
begin

	begin tran ha_dynsyn

	exec @retstat = sp_halockclustertables 'sp_logintrigger'
	if (@retstat != 0)
		goto clean_lt_all
end


/*
** Now insert/update/delete the row
*/
	if @action = 1
	BEGIN
		insert into master.dbo.sysattributes (class, attribute, 
			object_type, char_value)
		values (@login_class, @attrib, @type, @trigname)
	END
	else if @action = 2 
	BEGIN
	        update master.dbo.sysattributes
			set     char_value = @trigname
			where class = @login_class 
			and attribute = @attrib
			and object_type = @type

	END 
	else if @action = 3
	BEGIN
		delete master.dbo.sysattributes
		where   class = @login_class 
		and attribute = @attrib 
		and object_type = @type
	END

	if (@@error != 0)
		goto clean_lt_all

	/*
	** 19388, "Global login trigger updated."
	*/
	exec sp_getmessage 19388, @msg output
	print @msg


	if (@nHARSTClass = 1)
	begin
		if @action = 1
		BEGIN
			insert into master.dbo.rmt_ha_sysattributes 
				(class, attribute, object_type, char_value)
			values (@login_class, @attrib, @type, @trigname)
		END
		else if @action = 2 
		BEGIN
			update master.dbo.rmt_ha_sysattributes
			set     char_value = @trigname
			where class = @login_class 
			and attribute = @attrib
			and object_type = @type
		END 
		else if @action = 3
		BEGIN
			delete master.dbo.rmt_ha_sysattributes
			where   class = @login_class 
			and attribute = @attrib 
			and object_type = @type
		END

		if (@@error != 0)
			goto clean_lt_all


		commit tran ha_dynsyn

		/* Enable cis_rpc_handling to make remote call */
		if (@@cis_rpc_handling = 0)
		begin
			set cis_rpc_handling on
			select @set_cis_rpc_handling = 1
		end

		exec @retstat = SYB_HACMP.sybsystemprocs.dbo.sp_attrib_notify 
			@class_id = @login_class, 
			@attrib_id = @attrib, 
			@object_type = 'LT',
			@object_id = NULL,
			@object_info1 = NULL,
			@object_info2 = NULL,
			@object_info3 = NULL,
			@object_cinfo = NULL,
			@int_value = NULL,
			@char_value = @trigname, 
			@text_value = NULL,
			@image_value = NULL,
			@comments = NULL,
			@action = @action

		select @error_save = @@error
	
		if (@set_cis_rpc_handling = 1)
			set cis_rpc_handling off
		
		/* 
		** We want to catch error reported by either @retstat or
		** @@error and save the error code in @retstat if any
		*/
		if ((@retstat != 0) or (@error_save != 0))
			select @retstat = 1
		else
			select @retstat = 0
	end



	/*
	** Sync the in-memory RDES with the new values
	** in sysattributes.
	*/
	if attrib_notify(@login_class, @attrib, 'LT', NULL, NULL, NULL,
			NULL, NULL, NULL, @trigname, NULL, NULL, NULL,
			@action) = 0
		return (1)
	else
		return (@retstat)
END

clean_lt_all:

	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn

	return (1)
go
exec sp_procxmode 'sp_logintrigger', 'anymode'
go
grant execute on sp_logintrigger to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_modifylogin')
begin
	drop procedure sp_modifylogin
end
go
print "Installing sp_modifylogin"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	5.0	1.0	10/22/91	sproc/src/modifylogin */

/*
** Generated by spgenmsgs.pl on Thu Feb  2 00:39:18 2006 
*/
/*
** raiserror Messages for modifylogin [Total 14]
**
** 17260, "Can't run %1! from within a transaction."
** 17756, "The execution of the stored procedure '%1!' in database '%2!' was aborted because there was an error in writing the replication log record."
** 17880, "No such account -- nothing changed."
** 17925, "You entered an invalid option name. No change was made."
** 17927, "Error in changing the value of the specified column."
** 17928, "Invalid role name specified -- nothing changed."
** 17929, "The specified role is not granted to the account -- nothing changed."
** 17930, "Specify a value for the option to be modified."
** 17932, "You entered an invalid value. No change was made."
** 17933, "Specify the name of the option to be modified."
** 18388, "You must be in the master database in order to run '%1!'."
** 18409, "The built-in function '%1!' failed. Please see the other messages printed along with this message."
** 18898, "Login script '%1!' is not valid."
** 19257, "The authentication mechanism '%1!' is not valid."
*/
/*
** sp_getmessage Messages for modifylogin [Total 5]
**
** 17926, "Option changed."
** 17934, "All overrides for the password security option have been removed."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on the companion server '%2!'."
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins."
** 19259, "Warning. Authentication mechanism '%1!' is not enabled."
** 19448 "An existing login mapping for user '%1!' allows only '%2!' 
**		authentication mechanism to be used."
** 19812 "There is no login-specific '%1!' attribute set for this user."
** 19813 "The login-specific '%1!' attribute has been removed."
*/
/*
** End spgenmsgs.pl output.
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_modifylogin
@loginame varchar(255),		/* the login name of the account being modified */
@option varchar(30) = NULL,	/* the option to be updated */
@value varchar(255) = NULL	/* the new character value of the option */
as
declare @suid int		/* suid of account to be modified   */
declare @msg varchar(1024)	/* message text */
declare @retstat int		/* return status from other procedures */
declare @enable_login_role int	/* value of the status bit which is used
				** for enabling a role
				*/

declare @action  int        	/* Insert, update or delete 
		            	** Sysattributes entry 
		            	*/		
declare @attrib  int        	/* attribute id in Sysattributes */
declare @passeclass   int	/* Class id in Sysattributes */
declare @int_val  int        	/* convert char input into integer */
declare @deleted  int        	/* toggle to print the right return message */ 
declare @rowcount_saved int	/* Store @@rowcount as "if-then" resets it to 0*/
declare @dummy int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare	@defdb	varchar(255)	/* User's default database */
declare	@dbname	varchar(30)	/* Parsed login script dbname */
declare	@own	varchar(30)	/* Parsed login script owner */
declare	@objname varchar(30)	/* Parsed login script name */
declare @status int		/* Output of sp_namecrack */
declare @procid	int		/* Login script id */
declare	@curdb	varchar(30)	/* User's current database */
declare @sa_role int		/* has sa_role */
declare @sso_role int		/* has sso_role */
declare @sa_audited int		/* proc_role(sa_role) was called */
declare @sso_audited int	/* proc_role(sso_role) was called */
declare @sqltext varchar(2055)	/* a string buffer for concatenated sql */	
declare @authid int		/* authe mechanism id */
declare @allauth int		/* all auth mechanisms mask */
declare @map_authid int		/* auth mech id for login mapping */
declare @map_authnm varchar(30)	/* auth mech name for login mapping */
declare @login_class int	/* sysattributes class for login mapping */
declare @login_attrib int	/* sysattributes attribute for login mapping */
declare @config int
declare @err1 int		/* temp. variable to store @@error */

/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int
declare @rtn_code int
declare @srid int
declare @error int

declare @log_for_rep int
declare @db_rep_level_all int
declare @db_rep_level_none int
declare @db_rep_level_l1 int
declare @lt_rep_get_failed int

/*
** Initialize some constants
*/
select @db_rep_level_all = -1,
       @db_rep_level_none = 0,
       @db_rep_level_l1 = 1,
       @lt_rep_get_failed = -2

if (@loginame is null and @option = 'login script')
begin
        exec @retstat = sp_logintrigger @value
	return @retstat
end

select @HA_CERTIFIED = 0


select @nHARSTClass = ha_getrestrictionclass("sp_modifylogin")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_modifylogin', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/* Initialize variables */
select	@rowcount_saved = 0,
	@enable_login_role = 1,
	@sa_audited = 0,
	@sso_audited = 0,
	@sa_role = charindex("sa_role", show_role()),
	@sso_role = charindex("sso_role", show_role())

/*
** Do not allow this system procedure to be run from within a transaction
** to avoid creating a multi-database transaction where the 'master'
** database is not the co-ordinating database.
*/
if @@trancount > 0
begin
	/* 17260, "Can't run %1! from within a transaction." */
	raiserror 17260, "sp_modifylogin"
	return (1)
end
else
begin
	set chained off
end

set transaction isolation level 1

/*
** Get the replication status of the 'master' database
*/
select @log_for_rep = getdbrepstat(1) 
if (@log_for_rep = @lt_rep_get_failed)
begin
	raiserror 18409, "getdbrepstat"
	return (1)
end

/*
** Convert the replication status to a boolean
*/
if (@log_for_rep != @db_rep_level_none)
	select @log_for_rep = 1
else
	select @log_for_rep = 0

/*
** If we are logging this system procedure for replication, we must be in
** the 'master' database to avoid creating a multi-database transaction
** which could make recovery of the 'master' database impossible.
*/
if (@log_for_rep = 1) and (db_name() != "master")
begin
	raiserror 18388, "sp_modifylogin"
	return (1)
end

if (@option is NULL)
begin
	/*
	** 17933, "Specify the name of the option to be modified."
	*/
	raiserror 17933 
	return (1)
end
	
/* Allow NULL for 'login script' option when @loginame != 'all overrides' */
if ((@value is NULL) and ((@option != "login script") or
		(@loginame = "all overrides")))
begin
	/*
	** 17930, "Specify a value for the option to be modified."
	*/
	raiserror 17930
	return (1)
end

/* User is trying to modify user's own login */
if (suser_id(@loginame) = suser_id())
begin
	/*
	** Allow only logins with sa/sso role to modify the foll. options:
	** o "min passwd length"
	** o "passwd expiration"
	** o "max failed_logins" 
	** o "login script"
	** o "add default role"
	** o "drop default role"
	** o "authenticate with"
	*/
	

	if (@option = "min passwd length" or 
	    @option = "passwd expiration" or 
	    @option = "max failed_logins" or 
	    @option = "login script" or
            @option = "add default role" or
            @option = "drop default role" or
	    @option = "authenticate with")
	begin

		/* check if user has sa or sso role, proc_role will also do auditing
		** if required. proc_role will also print error message if required.
		*/

		if (@sa_role = 0 and @sso_role = 0)
		begin
			select @dummy = proc_role("sa_role")
			raiserror 17888, "modifylogin"
			return (1)
		end
		else
		begin
			if (@sa_role > 0)
			begin
				select @sa_audited = 1
				select @dummy = proc_role("sa_role")
			end
			if (@sso_role > 0)
			begin
				select @sso_audited = 1
				select @dummy = proc_role("sso_role")
			end
       		end
	end
end
/*
** If user is trying to modify someone else's login then
** check if user has sso role, when modifying non security-related 
** stuff sa role is also allowed. Proc_role will perform auditing
** and print error message if required.
*/
if (suser_id(@loginame) != suser_id())
begin
	if (@option = "add default role" or
		@option = "drop default role" or
		@option = "passwd expiration" or
		@option = "min passwd length" or
		@option = "max failed_logins" or
		@option = "login script" or 
		@option = "authenticate with")
	begin
		/* With or without SSO role, must be audited */
		if (@sso_audited = 0)
			select @dummy = proc_role("sso_role")

		/* Cannot proceed without SSO role */
		if (@sso_role = 0)
			return (1)
	end
	else
	begin
		/* Only SA and SSO can proceed */
		if (@sa_role = 0 and @sso_role = 0)
		begin
			select @dummy = proc_role("sa_role")/* to perform auditing if sa_role fails */
			raiserror 17888, "modifylogin"
			return(1)
		end

		/* Audit whatever has not been done yet */
		if (@sso_role > 0 and @sso_audited = 0)
			select @dummy = proc_role("sso_role")
		if (@sa_role > 0 and @sa_audited = 0)
			select @dummy = proc_role("sa_role")
	end
end

if ((@option = "passwd expiration") or (@option = "min passwd length") or 
	(@option = "max failed_logins"))
begin
	select @passeclass = class from master.dbo.sysattributes where
	object_type = "PS"

	/* With the exception of 'clear', these options expect only numbers */
	select @value = lower(@value)
	if @value != "clear"
	begin
		select @int_val = convert(int, @value)
			
		/*
		** int_val can't be less than -1 or greater than 32767
		** For "min passwd length", it can't be greater than 30
		*/
		if ((@int_val < -1) or ((@option = "min passwd length") and
			(@int_val > 30)) or (@int_val > 32767))
		begin
			/*
			** 17932, "You entered an invalid value. No 
			** change was made."
			*/
			raiserror 17932
			return (1)
		end
	end
end


/* Check if "all overrides". If so, check the new value input.
** If it is -1, then all entries in Sysattributes corresponding 
** to the attribute are deleted. Else, the entries in master.dbo.sysattributes 
** are overwritten with the new value
*/
if (@loginame = "all overrides")
begin

	if (@option = "passwd expiration")
		select @attrib = 0
	else 
	if (@option = "min passwd length")
		select @attrib = 1
	else 
	if (@option = "max failed_logins")
		select @attrib = 2
	else
	begin
		/*
		** 17925, You entered an invalid option name. No change was made."
		*/
		raiserror 17925
		return (1)
	end

	if @int_val = -1
	/* Remove all the overrides for the option */
	begin
		delete from master.dbo.sysattributes
		where class = @passeclass AND attribute = @attrib
		AND object_cinfo = "login"


		if (@@error != 0) goto clean_all

		if (@nHARSTClass = 1)
        	begin
                	delete from master.dbo.rmt_ha_sysattributes
		                where class = @passeclass 
					AND attribute = @attrib
			                AND object_cinfo = "login"
			if (@@error != 0) goto clean_all
		end


		/*
		** 17934, "All overrides for the password security option 
		** have been removed."
		*/
		exec sp_getmessage 17934, @msg output
		print @msg
		return (0)
	end

	else
	/* Modify the value of the overrides for the option */
	begin
		if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
			begin tran rs_logexec


		if (@nHARSTClass = 1)
		begin
			exec @rtn_code = sp_halockclustertables "sp_modifylogin"
			if (@rtn_code != 0)
				goto clean_all
		end

		update master.dbo.sysattributes
		set int_value = @int_val
		where class = @passeclass AND attribute = @attrib
		AND object_cinfo = "login"

		select @err1 = @@error, @rowcount_saved = @@rowcount
	

		if ((@err1 != 0) or (@@error != 0))
			goto clean_all
			
		if (@nHARSTClass = 1)
		begin
			update master.dbo.rmt_ha_sysattributes
               			set int_value = @int_val
				where class = @passeclass 
					AND attribute = @attrib
                        		AND object_cinfo = "login"

			if (@@error != 0)
				goto clean_all
                end


		if (@log_for_rep = 1)
		begin
			/*
			** If the 'master' database is marked for
			** replication, the T-SQL built-in 'logexec()' will
			** log for replication the execution instance of
			** this system procedure.  Otherwise, the T-SQL
			** built-in 'logexec()' is a no-op.
			*/
			if (logexec(1) != 1)
			begin
				raiserror 17756, "sp_modifylogin", "master"
				goto clean_all
			end
		end

		if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
			commit tran rs_logexec
	end
end

else
/* This must be modification for a specific login. */
begin
select @suid = suid
	from master.dbo.syslogins
	where name = @loginame

/* Check if the loginame exists */
if (@suid is NULL)
begin
	/*
	** 17880, "No such account -- nothing changed."
	*/
	raiserror 17880
	return (1)
end

if (@nHARSTClass = 1)
begin
	/*
	**  HA consistency checking: Make sure the login already exist
	**  on the companion server.
	*/
	if not exists (select 1 from master.dbo.rmt_ha_syslogins
		where name = @loginame AND suid = @suid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_modifylogin", @@hacmpservername

		/*
                ** 18778, "Unable to find login '%1!' with id '%2!' 
		** in syslogins."
		*/
		exec sp_getmessage 18778, @msg output
		print @msg, @loginame, @suid
		
		return (1)
	end
end


/*
**  Update takes place here: option can only be fullname for C2
*/
if @option = "fullname"
begin

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		begin tran rs_logexec


	if (@nHARSTClass = 1)
	begin
		exec @rtn_code = sp_halockclustertables "sp_modifylogin"
		if (@rtn_code != 0)
			goto clean_all
	end


        update master.dbo.syslogins set fullname  = @value where suid = @suid
	select @rowcount_saved = @@rowcount
end
else if (@option = "login script" and @loginame != "all overrides")
begin

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		begin tran rs_logexec


	if (@nHARSTClass = 1)
	begin
		exec @rtn_code = sp_halockclustertables "sp_modifylogin"
		if (@rtn_code != 0)
			goto clean_all
	end


	/*
	** If the 'login script' is provided, get the object id
	** from the default database verifying that it's really 
	** a stored procedure.
	*/
	if (@value is not NULL)
	begin
		set nocount on
 
		select @defdb = dbname
		from master.dbo.syslogins
		where name = @loginame

		exec @status = sp_namecrack @value, @db = @dbname output,
			@owner = @own output, @object = @objname output

		/* If a db name is given, it has to be the user's default */
		if ((@status != 0) or
			((@dbname is not null) and (@dbname != @defdb)))
		begin
			raiserror 18898, @value
			goto clean_all
		end

		/* Verify that the object exists and its a stored proc */
		if (@own is not null)
			exec("declare @dummy int " +
				"select @dummy = 1 from " + @defdb +
				"..sysobjects where name='" + @objname + "'" +
				" and type = 'P'" +
				" and uid = user_id('" + @own + "')")
		else
			exec("declare @dummy int " +
				"select @dummy = 1 from " + @defdb +
				"..sysobjects where name='" + @objname + "'" +
				" and type = 'P'" )

		if (@@rowcount = 0)
			select @procid = NULL
		else if (@own is not null)
			select @procid = object_id(@defdb+'.'+@own+'.'+@objname)
		else
			select @procid = object_id(@defdb+'..'+@objname)

		if (@procid is NULL)
		begin
			raiserror 18898, @value
			goto clean_all
		end
	end
	else
	begin
		select @procid = NULL
	end

	update master.dbo.syslogins set procid = @procid
		where name = @loginame

	select @rowcount_saved = @@rowcount
end

else if @option = "defdb"
begin
	execute @retstat = sp_defaultdb @loginame, @value

	select @error = @@error
	if (@error != 0)
		select @retstat = @error

	if (@retstat = 0)
	begin
		if (@log_for_rep = 1)
		begin
			/*
			** If the 'master' database is marked for
			** replication, the T-SQL built-in 'logexec()' will
			** log for replication the execution instance of
			** this system procedure.  Otherwise, the T-SQL
			** built-in 'logexec()' is a no-op.
			*/
			if (logexec(1) != 1)
			begin
				raiserror 17756, "sp_modifylogin", "master"
				goto clean_all
			end
		end
	end
	return (@retstat)
end
else if @option = "deflanguage"
begin
	execute @retstat = sp_defaultlanguage @loginame, @value

	select @error = @@error
	if (@error != 0)
		select @retstat = @error

	if (@retstat = 0)
	begin
		if (@log_for_rep = 1)
		begin
			/*
			** If the 'master' database is marked for
			** replication, the T-SQL built-in 'logexec()' will
			** log for replication the execution instance of
			** this system procedure.  Otherwise, the T-SQL
			** built-in 'logexec()' is a no-op.
			*/
			if (logexec(1) != 1)
			begin
				raiserror 17756, "sp_modifylogin", "master"
				goto clean_all
			end
		end
	end
	return (@retstat)
end
else if @option = "add default role" or @option = "drop default role"
begin
	/* 
	** verify that the role exists
	*/
	if (role_id(@value) is NULL)
	begin
		/*
		** Invalid role name specified -- nothing changed
		*/
		raiserror 17928
		return(1)
	end

	/*
	** verify that the role is granted to the loginame
	*/
	if not exists (select 1 from master.dbo.sysloginroles 
			where suid = @suid and srid = role_id(@value))
	begin
		/*
		** The specified role is not granted to the 
		** account -- nothing changed
		*/
		raiserror 17929
		return(1)
	end

	/*
	** perform the job
	*/

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		begin tran rs_logexec


	if (@nHARSTClass = 1)
	begin
		exec @rtn_code = sp_halockclustertables "sp_modifylogin"
		if (@rtn_code != 0)
			goto clean_all
	end


	if @option = "add default role"
	begin
		update master.dbo.sysloginroles set 
			status = status | @enable_login_role
			where suid = @suid and srid = role_id(@value)
	end
	else if @option = "drop default role"
	begin
		update master.dbo.sysloginroles set 
			status = status & ~@enable_login_role
			where suid = @suid and srid = role_id(@value)
	end
	
	select @rowcount_saved = @@rowcount
end
else
if ((@option = "passwd expiration") or (@option = "min passwd length") or 
	(@option = "max failed_logins"))
begin
	if (@option = "passwd expiration")
		select @attrib = 0
	else 
	if (@option = "min passwd length")
		select @attrib = 1
	else 
	if (@option = "max failed_logins")
		select @attrib = 2

	if exists (select 1 from master.dbo.sysattributes where
		class = @passeclass  AND attribute = @attrib AND 
		object = @suid AND object_cinfo = "login")
		select @action = 2
       	else
       		select @action = 1

	if @value = "clear"
	begin
		if @action = 1 
		begin
			/* There is no login-specific attr for this user */ 
			exec sp_getmessage 19812, @msg output
			print @msg, @option
			return(1)
		end
		else
		begin
			/* Remove the login-specific setting for this attr */
       			select @action = 0
			if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
				begin tran rs_logexec


			if (@nHARSTClass = 1)
			begin
                        	exec @rtn_code = sp_halockclustertables "sp_modifylogin"
                        	if (@rtn_code != 0)
					goto clean_all
			end


			delete from master.dbo.sysattributes
				where class = @passeclass
				AND attribute = @attrib
				AND object = @suid
				AND object_cinfo = "login"

			select @rowcount_saved = @@rowcount
			select @deleted = 1
		end
	end

	else if attrib_valid(@passeclass, @attrib, "PS", @suid, NULL, NULL,
		NULL, "login", @int_val, NULL, NULL, NULL, 
		NULL, @action) = 0
	begin
		/*
		** 17932, "You entered an invalid value. No
		** change was made."
		*/
		raiserror 17932
		return(1)
	end

	else
	begin
		if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
			begin tran rs_logexec


		if (@nHARSTClass = 1)
		begin
                        exec @rtn_code = sp_halockclustertables "sp_modifylogin"
                        if (@rtn_code != 0)
				goto clean_all
		end


		if @action = 1
		begin
			insert into master.dbo.sysattributes(class,attribute,
				object_type,object,object_cinfo, int_value)
			  values
			  (@passeclass,@attrib,"PS",@suid, "login", @int_val)
		end
		else
		begin
			update master.dbo.sysattributes
			  set int_value = @int_val
			  where class = @passeclass AND attribute = @attrib AND
				object = @suid AND object_cinfo = "login"
		end

		select @rowcount_saved = @@rowcount
	end
end
else if @option like "auth%with"
begin
        /*
        ** Check whether authentication mechanism specified is valid or not.
        ** 'AUTH_DEFAULT' and 'AUTH_MASK' are new values added in spt_values
        ** used to obtain value of default ('ANY') authmech or authentication
        ** mask respectively. They are not valid names that the user can specify
        ** as authentication mechanism.
        */
	select  @authid = low, @config = number
	from master.dbo.spt_values
	where type = 'ua' and name = upper(@value)
	and upper(name) not in ('AUTH_DEFAULT', 'AUTH_MASK')

	if @@rowcount = 0
        begin
                /*
                ** 19257, "The authentication mechanism '%1!' is not valid."
                */
                raiserror 19257, @value
                return(1)
	end

	/*
	** Check if the authentication method is enabled.
	** SMP or SDC, one row is expected.
	*/
	if (@config != 0) and not exists(select 1
		from master.dbo.syscurconfigs a

		where a.config = @config and a.value != 0)


	begin
		/*
		** 19259, "Warning. Authentication mechanism '%1!' is not enabled."
		*/
		exec sp_getmessage 19259, @msg output
		print @msg, @value
	end

	/*
	**  Obtain any login mapping for this login that may conflict
	**  with the new authentication mechanism being set.  The following
	**  query looks for the mapping in sysattributes by suid and
	**  by comparing authid bitmask from object_info1 with the parameter
	**  authid bitmask value. If a row is found, then prevent modifylogin
	**  action from proceeding, thus avoiding the mapping conflict
	**  with the new login restrictions.
	*/
	select @login_class = 20, @login_attrib = 0

	select @map_authid=object_info1 from master.dbo.sysattributes where
		class = @login_class and attribute = @login_attrib and
			object = @suid and ((object_info1 & @authid) = 0)
	if @@rowcount > 0
	begin
		/* Lookup the name for the authid value found. */
		select @map_authnm = name
			from master.dbo.spt_values
			where type = 'ua' and low = @map_authid

		/*		
		** 19448 "An existing login mapping for user '%1!' 
		** allows only '%2!' authentication mechanism to 
		** be used."
		*/
		raiserror 19448, @loginame, @map_authnm
		return (1)
	end

	/* Reset any auth mechanisms bits and set this one. */
	select @allauth = low
	from master.dbo.spt_values
	where type = 'ua' and upper(name) = 'AUTH_MASK'

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		begin tran rs_logexec


	if (@nHARSTClass = 1)
	begin
		exec @rtn_code = sp_halockclustertables "sp_modifylogin"
		if (@rtn_code != 0)
			goto clean_all
	end


        /*
        ** "ANY" is the name used for default authmech in sprocs, whereas the
        **  value is obtained from AUTH_DEFAULT.
        */
        if (upper(@value) = 'ANY')
        begin
                select @authid = low from master.dbo.spt_values
                        where type = 'ua' and upper(name) = 'AUTH_DEFAULT'
        end

        update master.dbo.syslogins 
	set status =  @authid | (status & ~@allauth)
	where suid = @suid

	select @rowcount_saved = @@rowcount


	if (@nHARSTClass = 1)
	begin
		update master.dbo.rmt_ha_syslogins
		set status =  @authid | (status & ~@allauth)
		where suid = @suid

		if (@@error != 0)
			goto clean_all
	end


	if (@log_for_rep = 1)
	begin
		/*
		** If the 'master' database is marked for replication, the
		** T-SQL built-in 'logexec()' will log for replication the
		** execution instance of this system procedure.  Otherwise,
		** the T-SQL built-in 'logexec()' is a no-op.
		*/
		if (logexec(1) != 1)
		begin
			raiserror 17756, "sp_modifylogin", "master"
			goto clean_all
		end
	end

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		commit tran rs_logexec
end
else /* error */
begin
	/*
	** 17925, "You entered an invalid option name. No change was made."
	*/
	raiserror 17925
	return (1)
end

end

/*
**  Check @rowcount_saved when it works
*/
if (@rowcount_saved >= 1)
begin


	if (@nHARSTClass = 1)
        begin
		if (@option = "fullname")
		begin
        		update master.dbo.rmt_ha_syslogins 
			  set fullname  = @value 
			  where suid = @suid
		end
			
		else if (@option = "login script")
		begin
        		update master.dbo.rmt_ha_syslogins 
			  set procid  = @procid 
			  where name = @loginame
		end

		else if ((@option = "add default role") or 
				(@option = "drop default role"))
		begin
			select @srid = role_id(@value)

        		if (@option = "add default role")
			begin
                		update master.dbo.rmt_ha_sysloginroles 
				  set status = status | @enable_login_role
		                  where suid = @suid and srid = @srid
			end
			else if (@option = "drop default role")
			begin
				update master.dbo.rmt_ha_sysloginroles
				  set status = status & ~@enable_login_role
		                  where suid = @suid and srid = @srid
        		end
		end
			
		else if ((@option= "passwd expiration") or
			(@option = "min passwd length") or
			(@option = "max failed_logins"))
		begin
                	if (@action = 0)
		        begin
				delete from master.dbo.rmt_ha_sysattributes
					where class = @passeclass
					AND attribute = @attrib
					AND object = @suid
					AND object_cinfo = "login"
				select @deleted = 1
			end
                	else if (@action = 1)
		        begin
                        	insert into master.dbo.rmt_ha_sysattributes
					(class, attribute, object_type, object,
					object_cinfo, int_value)
                        	  values
                        		(@passeclass, @attrib, "PS", @suid, 
					"login", @int_val)
			end
                	else
                	begin
                        	update master.dbo.rmt_ha_sysattributes
			          set int_value = @int_val
		                  where class = @passeclass AND 
				      attribute = @attrib AND 
				      object = @suid AND object_cinfo = "login"
                	end
        	end
			
		if (@@rowcount = 0)
			goto clean_all
	end


	if (@log_for_rep = 1)
	begin
		/*
		** If the 'master' database is marked for replication, the
		** T-SQL built-in 'logexec()' will log for replication the
		** execution instance of this system procedure.  Otherwise,
		** the T-SQL built-in 'logexec()' is a no-op.
		*/
		if (logexec(1) != 1)
		begin
			raiserror 17756, "sp_modifylogin", "master"
			goto clean_all
		end
	end

	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		commit tran rs_logexec
	
	if (@deleted = 1)
	begin
		exec sp_getmessage 19813, @msg output
		print @msg, @option
	end
	else
	begin
		/*
		** 17926, "Option changed."
		*/
		exec sp_getmessage 17926, @msg output
		print @msg
	end
	return (0)
end
else
begin
	/*
	** 17927, "Error in changing the value of the specified column."
	*/
	raiserror 17927
	goto clean_all	
end

clean_all:
	if ((@log_for_rep = 1) or (@HA_CERTIFIED = 1))
		rollback tran rs_logexec
	return (1)
		
go
exec sp_procxmode 'sp_modifylogin', 'anymode'
go
grant execute on sp_modifylogin to public
go
exec sp_procxmode 'sp_modifylogin', 'rep_master'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_addremotelogin')
begin
	drop procedure sp_addremotelogin
end
go
print "Installing sp_addremotelogin"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/addremotelogin */
/*
** Messages for "sp_addremotelogin"     17270
**
** 17240, "'%1!' is not a valid name."
** 17260, "Can't run %1! from within a transaction." 
** 17270, "There is not a server named '%1!'."
** 17271, "'%1!' is the local server - remote login not applicable."               
** 17272, "There is already a default-name mapping of a remote login from remote server '%1!'."
** 17273, "New remote login created."
** 17274, "'%1!' isn't a local user -- remote login denied."
** 17275, "There is already a remote user named '%1!' for remote server '%2!'."
** 17276  "Usage: sp_addremotelogin remoteserver [, loginame [,remotename]]"
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on companion server '%2!'"
** 18780, "Synchronization will not occur because server '%1!' is the companion server."
** 18782, "Unable to find a server with name '%1!' and id '%2!'."
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_addremotelogin
@remoteserver	varchar(255),		/* name of remote server */
@loginame varchar(255) = NULL,		/* user's remote name */
@remotename varchar(255) = NULL		/* user's local user name */
as

declare	@msg	varchar(1024)
declare @name   varchar(255)
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @maxlen	 int
declare @retstat  int
declare @dummy  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int
declare @case		int
declare @hacmpsrv_netname varchar(255)
declare @remoteserver_netname varchar(255)
declare @srvid		int
declare @suid		int
declare @rtn_code	int


select @nHARSTClass = ha_getrestrictionclass("sp_addremotelogin")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 1)
begin
	if ((@remoteserver = @@hacmpservername) OR (@remoteserver = "SYB_HACMP"))
	begin
		/*
		** 18780, "Synchronization will not occur because server 
		** '%1!' is the companion server."
		*/
		exec sp_getmessage 18780, @msg output
		print @msg, @remoteserver
		select @nHARSTClass = 0
	end
	else
	begin
		select @hacmpsrv_netname = srvnetname
		from master.dbo.sysservers
		where srvname = @@hacmpservername

		select @remoteserver_netname = srvnetname
		from master.dbo.sysservers
		where srvname = @remoteserver

		if (@hacmpsrv_netname = @remoteserver_netname)
		begin
			/*
			** 18780, "Synchronization will not occur because 
			** server '%1!' is the companion server."
			*/
			exec sp_getmessage 18780, @msg output
			print @msg, @remoteserver
			select @nHARSTClass = 0
		end
	end
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_addremotelogin', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_addremotelogin"
	return (1)
end
else
begin
	set chained off
end
set transaction isolation level 1

/* check if user has sa role or sso role. proc_role also generates an 
** audit record and prints an error message for sa role if both sa role 
** and sso role are not present.
*/


if ( (charindex("sa_role", show_role()) = 0) AND (charindex("sso_role", show_role()) = 0) )
begin
        select @dummy = proc_role("sa_role") /* to perform auditing if sa_role fails */
        raiserror 17888, "addremotelogin"
        return (1)
end

/*
**  Check that the server name is valid.
*/
if not exists (select *
			from master.dbo.sysservers
		where srvname = @remoteserver)
begin
	/*
	** 17270, "There is not a server named '%1!'."
	*/
	raiserror 17270, @remoteserver
	return (1)
end

/*
**  If it's the local server don't bother.
*/
if exists (select *
		from master.dbo.sysservers
			where srvname = @remoteserver
				and srvid = 0)
begin
	/*
	** 17271, "'%1!' is the local server - remote login not applicable."        
	*/
	raiserror 17271, @remoteserver
	return (1)
end


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */

	/* Make sure we are talking same server on the 2 sides */
	select @srvid = srvid from master.dbo.rmt_ha_sysservers
		where srvname = @remoteserver

	if not exists (select 1 from master.dbo.rmt_ha_sysservers
		where srvname = @remoteserver AND srvid = @srvid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_addremotelogin", @@hacmpservername
		
		/*
		** 18782, "Unable to find a server with name '%1!' and 
		** id '%2!'."
		*/
		exec sp_getmessage 18782, @msg output
		print @msg, @remoteserver, @srvid

		return (1)
	end

	begin tran ha_dynsyn

	exec @rtn_code = sp_halockclustertables "sp_addremotelogin"
	if (@rtn_code != 0)
		goto clean_all
end


/*
**  There are three cases to handle.
**
**	1) if only @remoteserver is given then a entry is made in
**		sysremotelogins that means anyone that doesn't have
**		an exact of mapped match in sysremotelogins will use
**		their remotename as their local name and it will be looked
**		up in syslogins.
**
**	2) if @remotename is omitted then it means that anyone from the
**		remote server logging in that doesn't have a complete
**		match in sysremotelogins will be mapped to @loginame.
**
**	3) if @remotename and @loginame are given then it is a straight
**		remote login for sysremotelogins.
*/

/*
**  Case 1:  Only @remoteserver given.
*/
if @loginame is null and @remotename is null
begin
	/*
	**  Check that there is not already an entry for local mapping.
	*/
	if exists (select *
		from master.dbo.sysremotelogins l, master.dbo.sysservers s
			where l.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and l.remoteusername is null)
	begin
		/*
		** 17272, "There is already a default-name mapping of a remote login from remote server '%1!'."
		*/
		raiserror 17272, @remoteserver
		goto clean_all
	end


	if (@nHARSTClass = 1)
	begin
		if exists (select 1
			from master.dbo.rmt_ha_sysremotelogins l, 
				master.dbo.rmt_ha_sysservers s
                        where l.remoteserverid = s.srvid
                                and s.srvname = @remoteserver
                                and l.remoteusername is null)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in stored
			** procedure '%1!' on companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_addremotelogin", @@hacmpservername
	
			/*
			** 17272, "There is already a default-name mapping 
			** of a remote login from remote server '%1!'."
			*/
			raiserror 17272, @remoteserver

			goto clean_all
		end
	end


	/*
	**  Add the entry.
	*/
	insert into master.dbo.sysremotelogins 
		(remoteserverid, remoteusername, suid, status)
	select srvid, null, -1, 0
		from master.dbo.sysservers
			where srvname = @remoteserver


	if (@@error != 0)
		goto clean_all
	select @case = 1


	/*
	** 17273, "New remote login created."
	*/
	exec sp_getmessage 17273, @msg output
	print @msg

	goto ha_syn
end

/*
**  Check that the @loginame is valid.  These is needed for both
**  case 2 and 3.
*/
if not exists (select *
		from master.dbo.syslogins
			where name = @loginame)
begin
	/*
	** 17274, "'%1!' isn't a local user -- remote login denied."
	*/
	raiserror 17274, @loginame
	goto clean_all
end

/*
**  Check to make sure that there is not already a @remotename for 
**  the @remoteserver.
*/
if (@remotename is not null)
begin
	select @maxlen = length from master.dbo.syscolumns
	where id = object_id("master.dbo.sysremotelogins") and 
				name = "remoteusername"

	if char_length(@remotename) > @maxlen
	begin
		/*
		** 17240, "'%1!' is not a valid name."
		*/
		raiserror 17240, @remotename
		return 1
	end
end

if exists (select *
		from master.dbo.sysremotelogins l, master.dbo.sysservers s
			where l.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and l.remoteusername = @remotename)
begin
	/*
	** 17275, "There is already a remote user named '%1!' for remote server '%2!'."
	*/
	select @name = isnull(@remotename, "NULL")
	raiserror 17275, @name, @remoteserver
	goto clean_all
end
	

	/* HA consistency checking */
	if (@nHARSTClass = 1)
	begin
		select @suid = suser_id(@loginame)
		if not exists (select 1 from master.dbo.rmt_ha_syslogins
                        where name = @loginame and suid = @suid)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in stored
			** procedure '%1!' on companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_addremotelogin", @@hacmpservername

			/*
			** 18778, "Unable to find login '%1!' with id '%2!' 
			** in syslogins."
			*/
			exec sp_getmessage 18778, @msg output
			print @msg, @loginame, @suid

			goto clean_all
		end

		/*
		**  Check to make sure that there is not already 
		**  a @remotename for the @remoteserver.
		*/
		if exists (select *
	                from master.dbo.rmt_ha_sysremotelogins l, 
				master.dbo.rmt_ha_sysservers s
	                        where l.remoteserverid = s.srvid
	                                and s.srvname = @remoteserver
	                                and l.remoteusername = @remotename)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in stored
			** procedure '%1!' on companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_addremotelogin", @@hacmpservername

			/*
			** 17275, "There is already a remote user 
			** named '%1!' for remote server '%2!'."
		        */
			select @name = isnull(@remotename, "NULL")
			raiserror 17275, @name, @remoteserver
			
			goto clean_all
		end
	end


/*
**  Case 2: We want to make an entry into sysremotelogins that will map
**	any non-exact matches to a particular local user.
*/
if @remotename is null
begin
	/*
	**  Check that there is not already an entry for local mapping.
	*/
	if exists (select *
		from master.dbo.sysremotelogins l, master.dbo.sysservers s
			where l.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and l.remoteusername is null)
	begin
		/*
		** 17272, "There is already a default-name mapping of a remote login from remote server '%1!'."
		*/
		raiserror 17272, @remoteserver
		goto clean_all
	end



	if (@nHARSTClass = 1)
	begin
		/*
		**  Check that there is not already an entry for local mapping.
		*/
		if exists (select 1 
			from master.dbo.rmt_ha_sysremotelogins l, 
				master.dbo.rmt_ha_sysservers s
				where l.remoteserverid = s.srvid
					and s.srvname = @remoteserver
					and l.remoteusername is null)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in stored
			** procedure '%1!' on companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_addremotelogin", @@hacmpservername

			/*
			** 17272, "There is already a default-name mapping 
			** of a remote login from remote server '%1!'."
			*/
			raiserror 17272, @remoteserver
			
			goto clean_all
		end
	end


	/*
	**  Go ahead and make the entry.
	*/
	insert into master.dbo.sysremotelogins
		(remoteserverid, remoteusername, suid, status)
	select srvid, null, suser_id(@loginame), 0
		from master.dbo.sysservers
				where srvname = @remoteserver

	if (@@error != 0)
		goto clean_all

	select @case = 2


	/*
	** 17273, "New remote login created."
	*/
	exec sp_getmessage 17273, @msg output
	print @msg

	goto ha_syn
end

/*
**  Case 3:  All the parameters have been supplied.  All we need to check
**	is that the entry isn't already in sysremotelogins.
**	We've verified the @remoteserver and @loginame above.
*/
if @loginame is not null and @remotename is not null
begin
	/*
	**  Make sure that the @loginame and @remotename are a
	**  unique combination.
	*/
	if exists (select *
		from master.dbo.sysremotelogins l, master.dbo.sysservers s
			where l.remoteusername = @remotename
				and l.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and l.suid = suser_id(@loginame))
	begin
		/*
		** 17275, "There is already a remote user named '%1!' for remote server '%2!'."
		*/
		raiserror 17275, @remotename, @remoteserver
		goto clean_all
	end


	if (@nHARSTClass = 1)
	begin
		/*
		**  Make sure that the @loginame and @remotename are a
		**  unique combination.
		*/
		if exists (select 1
			from master.dbo.rmt_ha_sysremotelogins l, 
				master.dbo.rmt_ha_sysservers s
			where l.remoteusername = @remotename
				and l.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and l.suid = suser_id(@loginame))
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in stored
			** procedure '%1!' on companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_addremotelogin", @@hacmpservername

			/*
			** 17275, "There is already a remote user 
			** named '%1!' for remote server '%2!'."
			*/
			raiserror 17275, @remotename, @remoteserver
			
			goto clean_all
		end
	end


	/*
	**  Go ahead and do the insert.
	*/
	insert into master.dbo.sysremotelogins
		(remoteserverid, remoteusername, suid, status)
	select srvid, @remotename, suser_id(@loginame), 0
		from master.dbo.sysservers
			where srvname = @remoteserver


	if (@@error != 0)
		goto clean_all

	select @case = 3

	
	/*
	** 17273, "New remote login created."
	*/
	exec sp_getmessage 17273, @msg output
	print @msg

	goto ha_syn
end

/*
**  We got here because the syntax was incorrect.
*/

raiserror 17276

clean_all:



	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn



	return (1)

ha_syn:


        if (@nHARSTClass = 1)
        begin
		if (@case = 1)
		begin
	                insert into master.dbo.rmt_ha_sysremotelogins
			      (remoteserverid, remoteusername, suid, status)
	                  select srvid, null, -1, 0
	                        from master.dbo.sysservers
	                        where srvname = @remoteserver

	                if (@@error != 0)
	                        goto clean_all
        	end
        	else if (@case = 2)
	        begin
	        	insert into master.dbo.rmt_ha_sysremotelogins
			     (remoteserverid, remoteusername, suid, status)
		          select srvid, null, suser_id(@loginame), 0
		                from master.dbo.sysservers
	                        where srvname = @remoteserver

			if (@@error != 0)
				goto clean_all
		end
		else if (@case = 3)
		begin
			insert into master.dbo.rmt_ha_sysremotelogins
			     (remoteserverid, remoteusername, suid, status)
	                  select srvid, @remotename, suser_id(@loginame), 0
	                        from master.dbo.sysservers
				where srvname = @remoteserver

	                if (@@error != 0)
	                        goto clean_all
        	end
		else
			/* Wrong case # */
			goto clean_all

		commit tran ha_dynsyn
	end



return (0)

go
exec sp_procxmode 'sp_addremotelogin', 'anymode'
go
grant execute on sp_addremotelogin to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_dropremotelogin')
begin
	drop procedure sp_dropremotelogin
end
go
print "Installing sp_dropremotelogin"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/defaultlanguage */

/*
** Messages for "sp_dropremotelogin"    17512
**
** 17260, "Can't run %1! from within a transaction." 
** 17512, "Remote login dropped."
** 17513, "There is no remote user '%1!' mapped to local user '%2!' from the remote server '%3!'."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on companion server '%2!'"
** 18780, "Synchronization will not occur because server '%1!' is the companion server."
** 18782, "Unable to find a server with name '%1!' and id '%2!'."
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_dropremotelogin
@remoteserver	varchar(255),		/* name of remote server */
@loginame varchar(255) = NULL,		/* user's remote name */
@remotename varchar(255) = NULL		/* user's local user name */
as

declare	@msg	varchar(1024)
declare @suid	int
declare @rname  varchar(255)
declare @lname  varchar(255)
declare @rtn_code int
declare @rowcount_save int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int
declare @dummy  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int
declare @srvid		int
declare @hacmpsrv_netname varchar(255)
declare @remoteserver_netname varchar(255)

select @nHARSTClass = ha_getrestrictionclass("sp_dropremotelogin")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

/* If we are dropping remotelogin for companion server
** the population of modification is disallowed
*/
if (@nHARSTClass = 1)
begin
	if ((@remoteserver = @@hacmpservername) OR (@remoteserver = "SYB_HACMP"))
	begin
		/*
		** 18780, "Synchronization will not occur because server '%1!' 
		** is the companion server."
		*/
		exec sp_getmessage 18780, @msg output
		print @msg, @remoteserver
		select @nHARSTClass = 0
	end
	else
	begin
		select @hacmpsrv_netname = srvnetname
		from master.dbo.sysservers
		where srvname = @@hacmpservername

		select @remoteserver_netname = srvnetname
		from master.dbo.sysservers
		where srvname = @remoteserver

		if (@hacmpsrv_netname = @remoteserver_netname)
		begin
			/*
			** 18780, "Synchronization will not occur because 
			** server '%1!' is the companion server."
			*/
			exec sp_getmessage 18780, @msg output
			print @msg, @remoteserver
			select @nHARSTClass = 0
		end
	end
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_dropremotelogin', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_dropremotelogin"
	return (1)
end
else
begin
	set chained off
end

set transaction isolation level 1

/* check if user has sa role or sso_role,proc_role also generates an 
** audit record and prints an error message for sa role if both sa role 
** and sso role are not present.
*/


if ( (charindex("sa_role", show_role()) = 0) AND (charindex("sso_role", show_role()) = 0) ) 
begin
	select @dummy = proc_role("sa_role") /* to perform auditing if sa_role fails */
        raiserror 17888, "dropremotelogin"
	return (1)
end


/*
**  If @loginame is NULL then we want to set @suid = -1. Otherwise get
**  it real value.
*/
if @loginame is null
	select @suid = -1
else select @suid = suser_id(@loginame)


if (@nHARSTClass = 1)
begin
	/* If it's the local server don't bother. */
	if exists (select 1 from master.dbo.sysservers
			where srvname = @remoteserver and srvid = 0)
	begin
		/*
		** 17271, "'%1!' is the local server - remote 
		** login not applicable."
		*/
		raiserror 17271, @remoteserver
		return (1)
	end

	/* HA consistency checking */

	/* Make sure we are deleting same entry on both servers */
	select @srvid = srvid from master.dbo.sysservers
	where srvname = @remoteserver
	if (@srvid is not null)
	begin
		if not exists (select 1 from master.dbo.rmt_ha_sysservers 
			where srvid = @srvid AND
				srvname = @remoteserver)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in stored
			** procedure '%1!' on companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_dropremotelogin", @@hacmpservername
			
			/*
			** 18782, "Unable to find a server with name 
			** '%1!' and id '%2!'."
			*/
			exec sp_getmessage 18782, @msg output
			print @msg, @remoteserver, @srvid

			return (1)
		end
	end
	else
	begin
		/*
		** 17270, "There is not a server named '%1!'."
		*/
		raiserror 17270, @remoteserver
		return (1)
	end

	if (@suid != -1)
	begin
		if not exists (select 1 from master.dbo.rmt_ha_syslogins
				where name = @loginame and suid = @suid)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in '%1!' on
			** the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_dropremotelogin", @@hacmpservername

			/*
			** 18778, "Unable to find login '%1!' with id '%2!' 
			** in syslogins."
			*/
			exec sp_getmessage 18778, @msg output
			print @msg, @loginame, @suid
		
			return (1)
		end
	end

	begin tran ha_dynsyn

	exec @rtn_code = sp_halockclustertables "sp_dropremotelogin"
	if (@rtn_code != 0)
		goto clean_all
end


/*
**  Delete the remote login.
*/

delete master.dbo.sysremotelogins
	from master.dbo.sysremotelogins l, master.dbo.sysservers s
	where l.remoteserverid = s.srvid
		and s.srvname = @remoteserver
		and l.remoteusername = @remotename
		and l.suid = @suid

/*
** Check @@rowcount when it works
*/
select @rowcount_save = @@rowcount

if (@rowcount_save > 0)
	select @rtn_code = 0
else
	select @rtn_code = 1


	if (@rtn_code = 0 and @nHARSTClass = 1)
	begin
		delete master.dbo.rmt_ha_sysremotelogins
       	 	from master.dbo.rmt_ha_sysremotelogins l, 
			master.dbo.rmt_ha_sysservers s
        	where l.remoteserverid = s.srvid
                	and s.srvname = @remoteserver
                	and l.remoteusername = @remotename
                	and l.suid = @suid

		if (@@rowcount <= 0)
			select @rtn_code = 1
		else
		begin
			commit tran ha_dynsyn
			select @rtn_code = 0
		end
	end


if (@rtn_code = 0)
begin
	/*
	** 17512, "Remote login dropped."
	*/
	exec sp_getmessage 17512, @msg output
	print @msg
	return (0)
end
else
begin
	/*
	** 17513, "There is no remote user '%1!' mapped to local user '%2!' from the remote server '%3!'."
	*/
	select @rname = isnull(@remotename, "NULL")
	select @lname = isnull(@loginame, "NULL")
	raiserror 17513, @rname, @lname, @remoteserver

	goto clean_all
end

return (0)

clean_all:

        if (@nHARSTClass = 1)
                rollback tran ha_dynsyn

        return (1)

go
exec sp_procxmode 'sp_dropremotelogin', 'anymode'
go
grant execute on sp_dropremotelogin to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_addexternlogin')
begin
	drop procedure sp_addexternlogin
end
go
print "Installing sp_addexternlogin"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */

/*
** Omni only
**
** Messages for "sp_addexternlogin"    18294
**
** 17240, "'%1!' is not a valid name."
** 17260, "Can't run '%1!' from within a transaction."
** 17270, "There is not a server named '%1!'."
** 17271, "'%1!' is the local server - remote login not applicable."
** 18294, "User '%1!' is not a local user -- request denied."
** 18295, "Only the 'sa' may update another's external login."
** 18296, "External login updated."
** 18297, "User '%1!' will be known as '%2!' in remote server '%3!'."
** 18342, "Invalid name '%1!'. This role or user does not exist in this SQL Server." 
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins."
** 18780, "Synchronization will not occur because server '%1!' is the companion server."
** 18782 "Unable to find a server with name '%1!' and id '%2!'."
** 18886, "Users with role '%1!' will be known as '%2!' in remote server '%3!'."
** 19403, "IBM MQ servers cannot have a registered login"
** 19404, "IBM MQ servers cannot have a default login"
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_addexternlogin
	@server		varchar(255),		/* name of remote server */
	@loginame	varchar(255),		/* user's local name */
	@externname	varchar(255),		/* user's remote name */
	@externpasswd	varchar(255) = NULL,	/* user's remote password */
	@rolename	varchar(255) = NULL	/* name of roll to map */
AS
BEGIN

DECLARE	@msg		varchar(1024),
	@srvid		smallint,
	@suid		int,
	@srid		int,
	@action		smallint,
	@dso_class	smallint,		/* omni's attribute  class */
	@attrib		smallint,		/* attr. id for ext. login */
	@dummy		int,
	@maxlen		int,
	@HA_CERTIFIED	tinyint,   /* Is the SP HA certified ? */
	@retstat	int,
	@srvclass	smallint 		
select @HA_CERTIFIED = 0
select @retstat = 0
select @srid = -1

if  (@externname is not null)
begin
	select @maxlen = length from master.dbo.syscolumns
	where id = object_id("master.dbo.syslogins") and name = "name"

	if (char_length(@externname) > @maxlen)
	begin
		/*
		** 17240, "'%1!' is not a valid name."
		*/
		raiserror 17240, @externname
		return 1
	end
end

/* check for password */
if (@externpasswd is not null) 
begin
	select @maxlen = length from master.dbo.syscolumns
	where id = object_id("master.dbo.syslogins") and name = "password"

	if (char_length(@externpasswd) >  @maxlen) 
	begin
		/*
		** 17240, "'%1!' is not a valid name."
		*/
		raiserror 17240, @externpasswd
		return 1
	end
end


/* Dynamic synchronization related variables declaration and initialization */
declare @hacmpsrv_netname varchar (32)
declare @remoteserver_netname varchar (32)
declare @nHARSTClass    int
declare @set_cis_rpc_handling int
declare @error_save	int

select @set_cis_rpc_handling = 0
select @error_save = 0

select @nHARSTClass = ha_getrestrictionclass("sp_addexternlogin")
if (@nHARSTClass = -1)
	return (1)

select @HA_CERTIFIED = 1
/* If we are adding external login for companion server
** the changes are not propagated to the companion server.
*/
if (@nHARSTClass = 1)
begin
	if ((@server = @@hacmpservername) OR (@server = "SYB_HACMP"))
		select @nHARSTClass = 0
	else
	begin
		select @hacmpsrv_netname = srvnetname
		  from master.dbo.sysservers
		  where srvname = @@hacmpservername

		select @remoteserver_netname = srvnetname
		  from master.dbo.sysservers
		  where srvname = @server

		if (@hacmpsrv_netname = @remoteserver_netname)
			select @nHARSTClass = 0
	end
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_addexternlogin', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
	if @@trancount > 0
	BEGIN
		/*		
		** 17260 Can't run '%1!' from within a transaction.
		*/
		raiserror 17260, "sp_addexternlogin"
		return 1
	END

/*
**  Check that the server name is valid.
*/

	select	@srvid = srvid,  @srvclass=srvclass
		from master.dbo.sysservers
		where srvname = @server

	if @@rowcount != 1
	BEGIN
		/*		
		** 17270  "There is not a server named %1!"  
		*/
		raiserror 17270, @server
		return (1)
	END

/*
**  If it's the local server don't bother.
*/
	if @srvid = 0
	BEGIN
		/*		
		** 17271 "'%1!' is the local server - remote login not applicable."
		*/
		raiserror 17271, @server
		return (1)
	END

/*
**  If @rolename was specified, ignore @loginame
*/
	if @rolename is not NULL
	BEGIN	
		select @loginame = NULL
/*
**  Check that the @rolename is valid.
*/

		select @srid = srid from master.dbo.syssrvroles	
			where name = @rolename

		if @@rowcount != 1
		BEGIN
			/* 
			** 18342, "Invalid name '%1!'. This role or user does 
			** not exist in this SQL Server."  
			*/ 
			raiserror 18342, @rolename
			return (1)
		END
	END

	if @loginame is NULL
	BEGIN
		select @suid = -1
	END
	else
	BEGIN
/*
**  Check that the @loginame is valid.
*/
		select @suid = suid
			from master.dbo.syslogins
			where name = @loginame
		if @@rowcount != 1
		BEGIN
			/*		
			** 18294 "User '%1!' is not a local user -- request denied."
			*/
			raiserror 18294, @loginame
			return (1)
		END
	END
/*
** Only a user with sa_role or sso_role can add extern logins for another
** user or for a role.
*/
	if @suid != suser_id()
	BEGIN
		/*
		** check if user has sa role, proc_role will
		** also do auditing if required. proc_role will also
		** print error message if required.
		*/
		if (charindex("sa_role",show_role()) = 0 and
			charindex("sso_role",show_role()) = 0)
		BEGIN
			select @dummy = proc_role("sa_role")
			select @dummy = proc_role("sso_role")
			return (1)
		END
	END


	/*
	** We don't allow IBM_MQ servers to have extern logins.
	*/
	if (@srvclass = 13)
	begin
		if @loginame is NULL
		begin
			/*
			** 19404, "IBM MQ servers cannot have a default login"
			*/
			raiserror 19404
		end
		else
		begin
			/*
			** 19403, "IBM MQ servers cannot have a registered login"
			*/
			raiserror 19403
		end
		return (1)
	end

/*
** If there is already a user for this server defined, we'll update
** it, else we'll insert a new row.
*/

	if ((@srvclass != 12) and (@srvclass != 14) and (@srvclass != 15))
		select @dso_class = 9
	else
		select @dso_class = 21

        select @attrib = 0

	if exists(select * from master.dbo.sysattributes where
			class = @dso_class and attribute = @attrib and 
			object_info1 = @srvid and object = @suid and
			(object_info2 = @srid or object_info2 is null))
		select @action = 2      /* attribute change */
	else
		select @action = 1      /* attribute add */	

/*
** First validate the row. This will also cause the password to be encrypted.
*/
	if attrib_valid(@dso_class, @attrib, "EL", @suid, @srvid, @srid, NULL,
		@externname, NULL, NULL, NULL, @externpasswd, NULL, @action) = 0
	BEGIN
		return(1)
	END


if (@nHARSTClass = 1)
begin

	/* HA consistency checking */

	/* Make sure the server name and id are consistent on 
	** the two companion servers 
	*/
	if not exists (select 1 from master.dbo.rmt_ha_sysservers
			where srvname = @server AND srvid = @srvid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_addexternlogin", @@hacmpservername

		/* 
		** 18782 "Unable to find a server with name '%1!' and id '%2!'."
		*/
                exec sp_getmessage 18782, @msg output
                print @msg, @server, @srvid

		return (1)
	end

	if @loginame is not NULL
	BEGIN
		/* Make sure that the @loginame is valid on the companion server */
		if not exists (select 1 from master.dbo.rmt_ha_syslogins
			where name = @loginame AND suid = @suid)
		BEGIN
			/*
			** 18773, "HA_LOG: HA consistency check failure in '%1!' on
			** the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_addexternlogin", @@hacmpservername

			/*
			** 18778, "Unable to find login '%1!' with id '%2!' 
			** in syslogins."
			*/
       		        exec sp_getmessage 18778, @msg output
       		        print @msg, @loginame, @suid

			return (1)
		END
	END
/*
**  Check that the @rolename is valid.
*/
	else if @rolename is not NULL
	BEGIN	
		if not exists (select 1 from master.dbo.rmt_ha_syssrvroles 
				where name = @rolename)
		BEGIN
			/* 
			** 18342, "Invalid name '%1!'. This role or user does 
			** not exist in this SQL Server."  
			*/ 
			raiserror 18342, @rolename
			return (1)
		END
	END

	begin tran ha_dynsyn

	exec @retstat = sp_halockclustertables "sp_addexternlogin"
	if (@retstat != 0)
		goto clean_all

end


/*
** Now update/insert the row
*/
	if @action = 2
	BEGIN
		update master.dbo.sysattributes
			set	object_cinfo = @externname,
				image_value = internal_encrypt(@externpasswd)
			where	class = @dso_class and attribute = @attrib and
				object_info1 = @srvid and object = @suid and
				(object_info2 = @srid or object_info2 is null)

		if (@@error = 0)
		BEGIN
			/*
			** 18296 "External login updated."
			*/
			exec sp_getmessage 18296, @msg output
			print @msg
		END
		ELSE
			goto clean_all

	END 
	else
	BEGIN
		insert into master.dbo.sysattributes (class, attribute, 
			object_type, object_info1, object, object_cinfo,
			image_value, object_info2)
		values (@dso_class, @attrib, "EL", @srvid, @suid, @externname, 
			internal_encrypt(@externpasswd), @srid)

		if (@@error = 0)
		BEGIN
			if @rolename is not null
			BEGIN
				/*
				** 18886 "Users with role '%1!' will be
				** known as '%2!' in remote server '%3!'."
				*/
				exec sp_getmessage 18886, @msg output
				print @msg, @rolename, @externname, @server
			END
			else
			BEGIN
				/*
				** 18297 "User '%1!' will be known as '%2!' 
				** in remote server '%3!'."
				*/
				exec sp_getmessage 18297, @msg output
				print @msg, @loginame, @externname, @server
			END
		END
		ELSE
			goto clean_all
	END



	if (@nHARSTClass = 1)
	begin
		if (@action = 2)
		begin
			update master.dbo.rmt_ha_sysattributes
			  set    object_cinfo = @externname,
				image_value = internal_encrypt(@externpasswd)
			  where   class = @dso_class and
				attribute = @attrib and
				object_info1 = @srvid and object = @suid and
				(object_info2 = @srid or object_info2 is null)
		end
		else
		begin
			insert into master.dbo.rmt_ha_sysattributes
				(class, attribute,
				object_type, object_info1, object,
				object_cinfo, image_value, object_info2)
			  values (@dso_class, @attrib, "EL", @srvid,
				@suid, @externname,
				internal_encrypt(@externpasswd), @srid)
		end

		if (@@error != 0)
			goto clean_all

		commit tran ha_dynsyn

		/* Enable cis_rpc_handling to make remote call */
		if (@@cis_rpc_handling = 0)
		begin
			set cis_rpc_handling on
			select @set_cis_rpc_handling = 1
		end
	
		exec @retstat = SYB_HACMP.sybsystemprocs.dbo.sp_attrib_notify @dso_class, @attrib, "EL", @suid, @srvid, @srid, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @action
		select @error_save = @@error
	
		if (@set_cis_rpc_handling = 1)
			set cis_rpc_handling off
		
		/* 
		** We want to catch error reported by either @retstat or
		** @@error and save the error code in @retstat if any
		*/
		if ((@retstat != 0) or (@error_save != 0))
			select @retstat = 1
		else
			select @retstat = 0
	end



	/*
	** Sync the in-memory RDES with the new values
	** in sysattributes.
	*/
	if attrib_notify(@dso_class, @attrib, "EL", @suid, @srvid, @srid,
			NULL, NULL, NULL, NULL, NULL, NULL, NULL,
			@action) = 0
		return (1)
	else
		return (@retstat)
END

clean_all:

	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn

	return (1)


go
exec sp_procxmode 'sp_addexternlogin', 'anymode'
go
grant execute on sp_addexternlogin to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_dropexternlogin')
begin
	drop procedure sp_dropexternlogin
end
go
print "Installing sp_dropexternlogin"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */

/*
** Omni only
**
** Messages for "sp_dropexternlogin"	18319
**
** 17260, "Can't run '%1!' from within a transaction."
** 18307, "Server name '%1!' does not exist in sysservers."
** 18319, "There is no external login for server '%1!'."
** 18320, "Only the 'sa' may drop another's external login."
** 18321, "Remote login/alias dropped."
** 17271, "'%1!' is the local server - remote login not applicable."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins."
** 18780, "Synchronization will not occur because server '%1!' is the companion server."
** 18782 "Unable to find a server with name '%1!' and id '%2!'."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_dropexternlogin
	@server		varchar(255),		/* name of remote server */
	@loginame	varchar(255) = NULL,	/* user's local login */
	@rolename	varchar(255) = NULL	/* role name */
AS
BEGIN

	declare	@msg		varchar(1024),
		@suid		int,
		@srid		int,
		@srvid		smallint,
		@dso_class	smallint,	/* omni's attribute  class */
		@attrib		smallint,	/* attr. id for ext. login */
		@action		smallint,
		@dummy		int,
		@HA_CERTIFIED	tinyint,   /* Is the SP HA certified ? */
		@retstat	int,
		@srvclass	smallint   

select @srid = -1
select @retstat = 0
select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @remoteserver_netname varchar(32)
declare @hacmpsrv_netname varchar(32)
declare @nHARSTClass    int
declare @set_cis_rpc_handling int
declare @error_save int

select @set_cis_rpc_handling = 0
select @error_save = 0
select @nHARSTClass = ha_getrestrictionclass("sp_dropexternlogin")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 1)
begin
	if ((@server = @@hacmpservername) OR (@server = "SYB_HACMP"))
		select @nHARSTClass = 0
	else
	begin
		select @hacmpsrv_netname = srvnetname
		from master.dbo.sysservers
		where srvname = @@hacmpservername

		select @remoteserver_netname = srvnetname
		from master.dbo.sysservers
		where srvname = @server

		if (@hacmpsrv_netname = @remoteserver_netname)
			select @nHARSTClass = 0
	end
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_dropexternlogin', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
	if @@trancount > 0
	BEGIN
		/*
		** 17260 "Can't run '%1!' from within a transaction."
		*/
		raiserror 17260, "sp_dropexternlogin"
		return (1)
	END

/*
** Validate the server name.
*/	


	select	@srvid = srvid,  @srvclass=srvclass
		from	master.dbo.sysservers
		where	srvname = @server
	if @@rowcount != 1
	BEGIN
		/*
		** 18307, "Server name '%1!' does not exist in sysservers."
		*/
		raiserror 18307, @server
		return(1)
	END

/*
**  If @rolename was specified, ignore @loginame
*/
	if @rolename is not NULL
	BEGIN	
		select @loginame = NULL
/*
**  Check that the @rolename is valid.
*/
		select @srid = srid from master.dbo.syssrvroles 
			where name = @rolename
		if @@rowcount != 1
		BEGIN
			/* 
			** 18342, "Invalid name '%1!'. This role or user does 
			** not exist in this SQL Server."  
			*/ 
			raiserror 18342, @rolename
			return (1)
		END
	END

	if @loginame is NULL
	BEGIN
		select @suid = -1
	END
	else
	BEGIN
/*
**  Check that the @loginame is valid.
*/
		select @suid = suid
			from master.dbo.syslogins
			where name = @loginame
		if @@rowcount != 1
		BEGIN
			/*		
			** 18294 "User '%1!' is not a local user -- request denied."
			*/
			raiserror 18294, @loginame
			return (1)
		END
	END
/*
** Only a user with sa_role or sso_role can add extern logins for another
** user or for a role.
*/
	if @suid != suser_id()
	BEGIN
		/*
		** check if user has sa or sso role, proc_role will
		** also do auditing if required. proc_role will also
		** print error message if required.
		*/
		if (charindex("sa_role",show_role()) = 0 and
			charindex("sso_role",show_role()) = 0)
		BEGIN
			select @dummy = proc_role("sa_role")
			select @dummy = proc_role("sso_role")
			return (1)
		END
	END


	if (@nHARSTClass = 1)
	begin
		/* If it's the local server don't bother. */
		if exists (select * from master.dbo.sysservers
				where srvname = @server and srvid = 0)
		begin
		        /*
			** 17271, "'%1!' is the local server - remote 
			** login not applicable."
			*/
			raiserror 17271, @server
			return (1)
		end

		/* HA consistency checking */

		/* Validate the server name.  */	
		if not exists (select 1 from master.dbo.rmt_ha_sysservers
			where srvname = @server AND srvid = @srvid)
		BEGIN
			/*
			** 18773, "HA_LOG: HA consistency check failure in '%1!' on
			** the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_dropexternlogin", @@hacmpservername

			/*
			** 18782 "Unable to find a server with name '%1!' and 
			** id '%2!'."
			*/
			exec sp_getmessage 18782, @msg output
			print @msg, @server, @srvid

			return(1)
		END

		if @loginame is not null
		begin		
			if not exists (select 1 from master.dbo.rmt_ha_syslogins
				where suid = @suid AND name = @loginame)
			begin
				/*
				** 18773, "HA_LOG: HA consistency check failure
				** in '%1!' on the companion server '%2!'"
				*/
				exec sp_getmessage 18773, @msg output
				print @msg, "sp_dropexternlogin", @@hacmpservername
	
				/*
				** 18778, "Unable to find login '%1!' with id 
				** '%2!' in syslogins."
				*/
				exec sp_getmessage 18778, @msg output
				print @msg, @loginame, @suid

				return (1)
			end
		end

/*
**  Check that the @rolename is valid.
*/
		else if @rolename is not null
		begin	
			if not exists (select 1 from 
				master.dbo.rmt_ha_syssrvroles 
				where name = @rolename)
			begin
				/* 
				** 18342, "Invalid name '%1!'. This role or 
				** user does not exist in this SQL Server."  
				*/ 
				raiserror 18342, @rolename
				return (1)
			end
		end
	
		begin tran ha_dynsyn

		exec @retstat = sp_halockclustertables "sp_dropexternlogin"
		if (@retstat != 0)
			goto clean_all
	end


/*
**  Delete the remote login.
*/

	if ((@srvclass != 12) and (@srvclass != 14) and (@srvclass != 15))
		select @dso_class = 9
	else
		select @dso_class = 21

        select @attrib = 0

	delete	master.dbo.sysattributes
		where	class = @dso_class and attribute = @attrib and
			object_info1 = @srvid and object = @suid and
			(object_info2 = @srid or object_info2 is null)
/*
** Check @@rowcount when it works
*/
	if @@rowcount > 0
	BEGIN
		select @action = 3      /* attribute drop */


		if (@nHARSTClass = 1)
		begin
        		delete  master.dbo.rmt_ha_sysattributes
			where   class = @dso_class and attribute = @attrib and
				object_info1 = @srvid and object = @suid and
				(object_info2 = @srid or object_info2 is null)

			if (@@error != 0)
				goto clean_all
	
			commit tran ha_dynsyn

			/* Enable cis_rpc_handling to make remote call */
			if (@@cis_rpc_handling = 0)
			begin
				set cis_rpc_handling on
				select @set_cis_rpc_handling = 1
			end
	
			exec @retstat = SYB_HACMP.sybsystemprocs.dbo.sp_attrib_notify @dso_class, @attrib, "EL", @suid, @srvid, @srid, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @action
			select @error_save = @@error

			if (@set_cis_rpc_handling = 1)
			begin
				set cis_rpc_handling off
				select @set_cis_rpc_handling = 0
			end

			/*
			** We want to catch error reported by either 
			** @retstat or @@error and save the error code in 
			** @retstat if any
			*/
			if ((@retstat != 0) or (@error_save != 0))
				select @retstat = 1
			else
				select @retstat = 0
		end

		/*
		** 18321, "Remote login/alias dropped"
		*/
		exec sp_getmessage 18321, @msg output
		print @msg

		/*
		** Sync the in-memory RDES with the new values
		** in sysattributes.
		*/
		if attrib_notify(@dso_class, @attrib, "EL", @suid, @srvid,
				@srid, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
				@action) = 0
			return (1)
		else
			return (@retstat)
	
	END ELSE
	BEGIN
		/*
		** 18319, "There is no external login for server '%1!'."
		*/
		raiserror 18319, @server
		goto clean_all
	END
END

clean_all:

	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn

	return (1)




go
exec sp_procxmode 'sp_dropexternlogin', 'anymode'
go
grant execute on sp_dropexternlogin to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_addalias')
begin
	drop procedure sp_addalias
end
go
print "Installing sp_addalias"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/addalias */

/*
** Messages for "sp_addalias"           17230
**
** 17231, "No login with the specified name exists."
** 17232, "No user with the specified name exists in the current database."
** 17233, "'%1!' is already a user in the current database."
** 17234, "The specified user name is already aliased."
** 17235, "Alias user added."
** 17236, "Setting curwrite label to data_low for inserts into sysalternates
**	   table failed."
** 17240, "'%1!' is not a valid name."
** 17289, "Set your curwrite to the hurdle of current database."
** 17756, "The execution of the stored procedure '%1!' in database
**         '%2!' was aborted because there was an error in writing the
**         replication log record."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18778, "A login with Login name '%1!' AND login id '%2!' could not be found in syslogins."
** 18795, "Unable to find a user with name '%1!' and login id '%2!' in sysusers."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	After that, you need to add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_addalias
@loginame varchar(255),		/* the name of the pretender */
@name_in_db varchar(255)	/* who the pretender wants to pretend to be */
as

declare @suid int		/* the suid of the pretender */
declare @asuid int		/* the suid of the person to impersonate */
declare @msg varchar(1024)
declare @name   varchar(255)
declare @dbname varchar(255)
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int
declare @dummy int

select @HA_CERTIFIED = 0


/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int
declare @sqlbuf		varchar(255)
declare @rtn_code	int

select @nHARSTClass = ha_getrestrictionclass("sp_addalias")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 3)
begin
        if (db_id() = 1)
                /* We only synch the alias information for 'master' database */
                select @nHARSTClass = 1
        else
                select @nHARSTClass = 0
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_addalias', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

set transaction isolation level 1
if @@trancount = 0
begin
	set chained off
end

/*
**  Only the Database Owner (DBO) or
**  Accounts with SA or SSO role can execute it.
**  If the user has SA role, it's uid will
**  be DBO uid (1).
*/
if ((user_id() != 1) and (charindex("sso_role", show_role()) = 0))
begin
	/* 
	** proc_role() will raise permission errors
	** and send audit records to the audit trail
	*/
	select @dummy = proc_role("sa_role")
	select @dummy = proc_role("sso_role")
	return (1)
end

/* Send apropriate audit records. */
if (charindex("sa_role", show_role()) > 0)
	select @dummy = proc_role("sa_role")
if (charindex("sso_role", show_role()) > 0)
	select @dummy = proc_role("sso_role")

/*
**  Make sure that the pretender has an account.
*/
select @suid = suid
	from master.dbo.syslogins
where name = @loginame

if @suid is NULL
begin
	/* 17231, "No login with the specified name exists." */

	raiserror 17231
	return (1)
end

/*
**  Get the suid of the person we want to pretend to be.
*/
select @asuid = suid
from sysusers
where name = @name_in_db
and ((uid >= @@minuserid and uid < @@mingroupid and uid != 0) 
or uid > @@maxgroupid)

/*
**  Does the user to be impersonated exist in the current database?
*/
if @asuid is NULL
begin
	/* 
	** 17232, "No user with the specified name exists in the
	** current database." 
	*/
	
	raiserror 17232
	return (1)
end

/*
**  Does the login to do the impersonating already a user in the current db?
*/
if exists (select *
		from sysusers
			where suid = @suid)
begin
	/* 17233, "'%1!' is already a user in the current database." */
        select @name = name
                from sysusers
                        where suid = @suid
	
		raiserror 17233, @name
        return (1)
end

/*
** Is the person already aliased to a user?
*/
if exists (select *
		from sysalternates
	where suid = @suid)
begin
	/* 17234, "The specified user name is already aliased." */

	raiserror 17234
	return (1)
end


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */
		
	if not exists (select 1 from master.dbo.rmt_ha_syslogins
		where suid = @suid and name = @loginame)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_addalias", @@hacmpservername

		/*
		** 18778, "A login with Login name '%1!' AND 
		** login id '%2!' could not be found in syslogins."
		*/
		exec sp_getmessage 18778, @msg output
		print @msg, @loginame, @suid

		return (1)
	end

	if not exists (select 1 from master.dbo.rmt_ha_sysusers
			where @asuid = suid and ((uid != 0 and
			uid >= @@minuserid and uid < @@mingroupid)
			or uid > @@maxgroupid) and @name_in_db = name)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_addalias", @@hacmpservername

		/*
		** 18795, "Unable to find a user with name '%1!' 
		** and login id '%2!' in sysusers."
		*/
		exec sp_getmessage 18795, @msg output
		print @msg, @name_in_db, @asuid

		return (1)
	end
end


/*
**  Add the alias.
*/

/* 
** This transaction also writes a log record for replicating the
** invocation of this procedure. If logexec() fails, the transaction
** is aborted.
**
** IMPORTANT: The name rs_logexec is significant and is used by
** Replication Server.
*/
begin transaction rs_logexec


if (@nHARSTClass = 1)
begin
	exec @rtn_code = sp_halockclustertables "sp_addalias"
	if (@rtn_code != 0)
		goto clean_all
end


	insert into sysalternates (suid, altsuid)
		values (@suid, @asuid)

	/*
	** Write the log record to replicate this invocation 
	** of the stored procedure.
	*/
	if (logexec() != 1)
	begin
		/*
		** 17756, "The execution of the stored procedure '%1!'
		** 	   in database '%2!' was aborted because there
		** 	   was an error in writing the replication log
		**	   record."
		*/
		select @dbname = db_name()
		raiserror 17756, "sp_addalias", @dbname
				
		rollback transaction rs_logexec
		return(1)
	end


        /* Operate according to the HA restriction class */
	if (@nHARSTClass = 1)
	begin
		insert into master.dbo.rmt_ha_sysalternates (suid, altsuid)
			values (@suid, @asuid)

		if (@@error != 0)
		begin
			rollback tran rs_logexec
			return (1)
		end

		select @sqlbuf = "declare @dummy int select @dummy = logexec()"
		exec sp_remotesql "SYB_HACMP", @sqlbuf
	end


commit transaction rs_logexec

/* 17235, "Alias user added." */
exec sp_getmessage 17235, @msg out
print @msg

return (0)

clean_all:
	rollback transaction rs_logexec
        return (1)

go
exec sp_procxmode 'sp_addalias', 'anymode'
go
grant execute on sp_addalias to public
go
exec sp_procxmode 'sp_addalias', 'rep_current'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_dropalias')
begin
	drop procedure sp_dropalias
end
go
print "Installing sp_dropalias"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */

/*
** Messages for "sp_dropalias"          17480
**
** 17231, "No login with the specified name exists."
** 17480, "Alias user dropped."
** 17481, "No alias for specified user exists."
** 17756, "The execution of the stored procedure '%1!' in database
**         '%2!' was aborted because there was an error in writing the
**         replication log record."
** 18337, "Setting curwrite label to data_low for deleting from sysalternates
**	   table failed."
** 18790, "You cannot drop the alias for login '%1!' because '%2!' owns
**	   objects in the database."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18778, "A login with Login name '%1!' AND login id '%2!' could not be found in syslogins."
** 18806, "You cannot drop the alias for login '%1!' because '%2!' owns
**	   thresholds in the database."
** 18935, "Warning: You have forced the drop of the alias for login '%1!'
**	   which owns objects in the database. This may result in errors when
**	   those objects are accessed from or contain references to another
**	   database."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	After that, you need to add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
** 18790, "You cannot drop the alias for login '%1!' because '%2!' owns objects in the database."
*/

create procedure sp_dropalias
@loginame varchar(255),		/* account name of the user with the alias */
@option varchar(30) = NULL	/* 'force' to force dropping the alias, even if
				** there are objects created by the alias.
				*/
as

declare @msg varchar(1024)
declare @dbname varchar(255)
declare @suid	int		/* suid of the user */
declare @objectcount int	/* count of objects owned by login */
declare @threshcount int	/* count of thresholds owned by login */
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int
declare @dummy int

select @HA_CERTIFIED = 0


/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int
declare @sqlbuf varchar(255)
declare @rtn_code	int

select @rtn_code = 0
select @nHARSTClass = ha_getrestrictionclass("sp_dropalias")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 3)
begin
        if (db_id() = 1)
                /* We only synch the alias information for 'master' database */
                select @nHARSTClass = 1
        else
                select @nHARSTClass = 0
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_dropalias', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if @@trancount = 0
begin
	set chained off
end

set transaction isolation level 1

/*
**  Only the Database Owner (DBO) or
**  Accounts with SA or SSO role can execute it.
**  If the user has SA role, it's uid will
**  be DBO uid (1).
*/
if ((user_id() != 1) and (charindex("sso_role", show_role()) = 0)) 
begin
	/* 
	** proc_role() will raise permission errors  
	** and send audit records to the audit trail
	*/
	select @dummy = proc_role("sa_role")        
	select @dummy = proc_role("sso_role")        
	return (1)        
end

/* Send apropriate audit records. */
if (charindex("sa_role", show_role()) > 0)
	select @dummy = proc_role("sa_role")
if (charindex("sso_role", show_role()) > 0)
	select @dummy = proc_role("sso_role")

/*
**  Check to make sure that the @loginame has an account.
*/
select @suid = suser_id(@loginame)
if @suid is NULL
begin
	/*
	** 17231, "No login with the specified name exists."
	*/
	raiserror 17231
	return (1)
end

/*
** If the user owns any objects return after raising error. 
*/
select @objectcount = count(*)
	from sysobjects
		where loginame = @loginame

if @objectcount > 0
begin
if @option = 'force'
        begin
		/* 18935, "Warning: You have forced the drop of the alias for
		** login '%1!' which owns objects in the database. This
		** may result in errors when those objects are accessed
		** from or contain references to another database."
		*/
		exec sp_getmessage 18935, @msg output
		print @msg, @loginame
	end
	else
	begin
		/* 18790, "You cannot drop the alias for login '%1!' because
		** '%2!' owns objects in the database."
		*/
		raiserror 18790, @loginame, @loginame
		select name, type from sysobjects
				where loginame = @loginame
		return(1)
	end

end
/*
** If the user owns any thresholds return after raising error.
*/
select @threshcount = count(*)
	from systhresholds
		where suid = @suid

if @threshcount > 0
begin
	/* 18806, "You cannot drop the alias for login '%1!' because
	**	'%2!' owns thresholds in the database."
	*/
	raiserror 18806, @loginame, @loginame
	select "Segment name" = g.name, "Free pages" = t.free_space
		from syssegments g, systhresholds t
			where t.suid = @suid
			and t.segment = g.segment
	return(1)
end


if (@nHARSTClass = 1)
begin
      /* HA consistency checking */
	
	/*
	** The loginame and suid exist on the remote server?
	*/
	select @suid = suser_id(@loginame)

	if not exists (select 1 from master.dbo.rmt_ha_syslogins
		where @loginame = name and @suid = suid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
                raiserror 18773, "sp_dropalias", @@hacmpservername

		/*
		** 18778, "A login with Login name '%1!' AND
		** login id '%2!' could not be found in syslogins."
		*/
		exec sp_getmessage 18778, @msg output
		print @msg, @loginame, @suid

		return (1)
	end

	/*
	** Does the user own any objects?
	*/
	if exists (select 1 from master.dbo.rmt_ha_sysobjects
	  where loginame = @loginame)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		raiserror 18773, "sp_dropalias", @@hacmpservername

		/* 
		** 18790, "You cannot drop the alias for login '%1!' because
		**        '%2!' owns objects in the database."
		*/
		exec sp_getmessage 18790, @msg output
		print @msg, @loginame, @loginame
		
		select name, type from master.dbo.rmt_ha_sysobjects
		  where loginame = @loginame

		return(1)
	end

	/*
	** Does the user own any thresholds?
	*/
	if exists (select 1 from master.dbo.rmt_ha_systhresholds
			where suid = @suid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		raiserror 18773, "sp_dropalias", @@hacmpservername

		/* 
		** 18806, "You cannot drop the alias for login '%1!' because
		**      '%2!' owns thresholds in the database."
		*/
		exec sp_getmessage 18806, @msg output
		print @msg, @loginame, @loginame
	
		return(1)
	end
end


/*
**  Delete the alias, if any, from sysalternates.
*/

/* 
** This transaction also writes a log record for replicating the
** invocation of this procedure. If logexec() fails, the transaction
** is aborted.
**
** IMPORTANT: The name rs_logexec is significant and is used by
** Replication Server.
*/
begin transaction rs_logexec


if (@nHARSTClass = 1)
begin
	exec @rtn_code = sp_halockclustertables "sp_dropalias"
	if (@rtn_code != 0)
		goto clean_all
end


	delete from sysalternates
		where suid = suser_id(@loginame)

	/*
	**  If nothing happened (rowcount = 0), there was no alias.
	*/
	if (@@rowcount = 0)
	begin
		/*
		** 17481, "No alias for specified user exists."
		*/
		raiserror 17481
	
		rollback transaction rs_logexec
		return (1)
	end

	/*
	** Write the log record to replicate this invocation 
	** of the stored procedure.
	*/
	if (logexec() != 1)
	begin
		/*
		** 17756, "The execution of the stored procedure '%1!'
		** 	   in database '%2!' was aborted because there
		** 	   was an error in writing the replication log
		**	   record."
		*/
		select @dbname = db_name()
		raiserror 17756, "sp_dropalias", @dbname
				
		rollback transaction rs_logexec
		return(1)
	end


	if (@nHARSTClass = 1)
        begin
		delete from master.dbo.rmt_ha_sysalternates
                	where suid = suser_id(@loginame)

                if (@@rowcount = 0)
		begin
			rollback tran rs_logexec
			return (1)
		end

		select @sqlbuf = "declare @dummy int select @dummy = logexec()"
		exec sp_remotesql "SYB_HACMP", @sqlbuf
	end


commit transaction rs_logexec

/*
** 17480, "Alias user dropped."
*/
exec sp_getmessage 17480, @msg output
print @msg

return (0)

clean_all:
	rollback transaction rs_logexec
	return (1)
go
exec sp_procxmode 'sp_dropalias', 'anymode'
go
grant execute on sp_dropalias to public
go
exec sp_procxmode 'sp_dropalias', 'rep_current'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_dropserver')
begin
	drop procedure sp_dropserver
end
go
print "Installing sp_dropserver"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/defaultlanguage */

/*
** Messages for "sp_dropserver"         17530
**
** 17260, "Can't run %1! from within a transaction." 
** 17270, "There is not a server named '%1!'."
** 17530, "There are still remote logins for the server '%1!'."
** 17531, "Remote logins for remote server '%1!' have been dropped."
** 17532, "Usage: sp_dropserver server [, droplogins]"
** 17533, "Server dropped."
** 17534, "There are still external logins for the server '%1!'."
** 17535, "External logins for remote server '%1!' have been dropped."
** 17536, "Unable to drop server '%1!' because it is referenced in master.dbo.sysdatabases."
** 17537, "Unable to drop server '%1!' because it is referenced by 
**	   transaction coordinator."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on companion server '%2!'."
** 18782, "Unable to find a server with name '%1!' and id '%2!'."
** 18783, "You cannot drop the companion server '%1!' in the companion mode because it is configured as a node of HA cluster."
** 18785, "Unable to drop the local server '%1!' because it is in HA companion mode."
** 19660, "Unable to drop server '%1!' because it stores information of existing cluster instance '%2!'."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_dropserver
@server	varchar(255),			/* server name */
@droplogins	char(10) = NULL		/* drop all related logins? */
as

declare	@msg	varchar(1024),
	@srvid	smallint,
	@retstat int

declare	@srvclass smallint	/* Class id of the server */
declare	@command varchar(30)	/* Command passed to sp_extengine */
declare	@physname varchar(255)	/* Class name of the external engine class */
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @inst_id int		/* Cluster instance id */
declare @status2 unsigned int	/* To store 'srvstatus2' column value */
declare @insysattributes int    /* Is the rtds provider in sysattributes ? */
declare	@outstr	varchar(255),	/* for SDC dbcc set_scope */
	@scope	varchar(16)	/* for SDC dbcc set_scope */

select @HA_CERTIFIED = 0
select @insysattributes = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @str_srvid 	varchar(6)
declare @sqlbuf 	varchar(255)
declare @nHARSTClass    int
declare @status		int
declare @srvid_hacmp	smallint
declare @rtn_code	int

select @nHARSTClass = ha_getrestrictionclass("sp_dropserver")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@@cmpstate > 0)
begin
	if (((@server = "SYB_HACMP") OR (@server = @@hacmpservername) OR
		(@server = @@servername)) and @@cmpstate > 0)
	begin
		/*
		** 18783, "You cannot drop the companion server '%1!' 
		**  because it is configured as a node of HA cluster."
		*/
		exec sp_getmessage 18783, @msg output
		print @msg, @server

		return (1)
	end

	/* 
	** Need to be able to drop backup server and the EJB Server locally 
	** without affecting the entries in the remote server
	*/
	select @srvclass = srvclass from master.dbo.sysservers
		where srvname = @server

	if ((@server = "SYB_BACKUP") OR (@server = "%_BS") OR (@srvclass = 10))
	begin
		select @nHARSTClass = 0
	end
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_dropserver', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_dropserver"
	return (1)
end
else
begin
	set chained off
end

set transaction isolation level 1

/* check if user has sso role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/

if (proc_role("sso_role") = 0)
	return (1)

/*
**  Check to see if the server exists.
*/
if not exists (select * from master.dbo.sysservers
			where srvname = @server)
begin
	/*
	** 17270, "There is not a server named '%1!'."
	*/
	raiserror 17270, @server
	return (1)
end

/*
** Check to see if this is a rtds provider which
** is registered in sysattributes.
*/
select @srvclass = srvclass from master.dbo.sysservers
	where srvname = @server
if (@srvclass in (12,13,14,15))
	and (exists (select 1 from master.dbo.sysattributes
			where class = 21 and attribute = 10
				and object_type = 'PR'
				and object_cinfo = @server))
        select @insysattributes = 1
else
        select @insysattributes = 0


/*
** Check to see if server stores cluster instance information 
*/
select @status2=srvstatus2 from master.dbo.sysservers where srvname=@server
if ((@status2 & 4) != 0)
begin
	select @inst_id=instance_id(@server)
	if @inst_id is not NULL
	begin
		/*
		** 19660, "Unable to drop server '%1!' 
		** because it stores information of 
		** existing cluster instance '%2!'."
		*/
		raiserror 19660, @server, @inst_id
		return (1)
	end
end

/*
** OMNI: check to see if there is a default location referenced in sysdatabases
*/
if exists (select * from master.dbo.sysdatabases where
		substring(def_remote_loc, 1, 
			  charindex('.', def_remote_loc) - 1) = @server)
begin
	/*
	** 17536, "Unable to drop server '%1!' because it is referenced 
	** in master.dbo.sysdatabases."
	*/
	raiserror 17536, @server
	return (1)
end


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */

	/* Check to see if the server exists. */
	if (not exists (select 1
		from master.dbo.rmt_ha_sysservers
		where srvname = @server))
		or ((@insysattributes = 1)
			and (not exists (select 1
				from master.dbo.rmt_ha_sysattributes
				where class = 21 and attribute = 10
					and object_type = 'PR'
					and object_cinfo = @server)))
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_dropserver", @@hacmpservername
		
		/*
		** 17270, "There is not a server named '%1!'."
		*/
		raiserror 17270, @server
		
		return (1)
	end

	select @srvid_hacmp = srvid
		from master.dbo.rmt_ha_sysservers
		where srvname = @server
	select @srvid = srvid
		from master.dbo.sysservers
		where srvname = @server
	if (@srvid = 0)
	begin
		/*
		** 18785, "Unable to drop the local server '%1!' because 
		** it is in HA companion mode." 
		*/
		exec sp_getmessage 18785, @msg output
		print @msg, @server
		return (1)
	end
	if (@srvid_hacmp != @srvid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_dropserver", @@hacmpservername
		
		/*
		** 18782, "Unable to find a server with name '%1!' 
		** and id '%2!'."
		*/
		exec sp_getmessage 18782, @msg output
		print @msg, @server, @srvid

		return (1)
	end

	/*
	** OMNI: check to see if there is a default location 
	** referenced in sysdatabases
	*/
	if exists (select 1 from master.dbo.rmt_ha_sysdatabases where
	   substring(def_remote_loc, 1, charindex('.', def_remote_loc) - 1) = 
		@server)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_dropserver", @@hacmpservername
		
		/*
		** 17536, "Unable to drop server '%1!' because it is 
		** referenced in master.dbo.sysdatabases."
		*/
		raiserror 17536, @server

	        return (1)
	end
end


/* Start a transaction */
begin transaction dropserver

/* 
** Do more consistency checks to ensure that transaction coordinator
** is not using the server entry being dropped.
*/

/*
** Lock syscoordinations to synchronize with dtm service. This type of
** locking on syscoordinations should be done only in extreme case like 
** dropserver as this will potentially block dtm services.
*/
lock table sybsystemdb.dbo.syscoordinations in share mode



/* If server is in asymmetric/symmetric failover state */
if exists (select * from master.dbo.sysdatabases 
	   where name = "sybsystemdb_companion")
begin
	/* Get the server id, it is needed for dbcc below */
	select @srvid = srvid from master.dbo.sysservers
	where srvname = @server

	dbcc ha_admin("", "coord_noref", @srvid)
	if (@@error != 0)
	begin
		rollback transaction dropserver

		/*
		** 17537, "Unable to drop server '%1!' because it
		**	   is referenced by transaction coordinator."
		*/
		raiserror 17537, @server
		return (1)
	end
end

/*
** This is covering the NCM mode right now. In suspend mode, 
** sp_dropserver is disallowed right now. Please refer to 
** ha_getrestrictionclass() implementation.
*/
if (@nHARSTClass = 1)
begin
	select @sqlbuf = 
		"lock table sybsystemdb.dbo.syscoordinations"
			select @sqlbuf = @sqlbuf + " in share mode"
			exec sp_remotesql "SYB_HACMP", @sqlbuf
                
		exec @rtn_code = sp_halockclustertables "sp_dropserver"
		if (@rtn_code != 0)
			goto clean_all

	/*
	** Ensure that the transaction coordinator on 
	** companion is not referencing the server being
	** dropped.
	*/
	if exists (select * from master.dbo.rmt_ha_syscoordinations c,
		   master.dbo.rmt_ha_sysservers s
		   where s.srvname = @server and 
			 s.srvid = c.participant and 
			 c.owner = 1)
	begin
		rollback transaction dropserver

		/*
		** 17537, "Unable to drop server '%1!' because it
		**	   is referenced by transaction coordinator."
		*/
		raiserror 17537, @server
		return (1)
	end
end


if exists (select * from sybsystemdb.dbo.syscoordinations c,
	   master.dbo.sysservers s
	   where s.srvname = @server and 
	   	s.srvid = c.participant and c.owner = 1)
begin
	rollback transaction dropserver

	/*
	** 17537, "Unable to drop server '%1!' because it is 
	** 	   referenced by transaction coordinator."
	*/
	raiserror 17537, @server
	return (1)
end


/* Check to see if there are any related logins in sysremotelogins. */
if (@droplogins is NULL)
begin
	if exists (select *
		from master.dbo.sysremotelogins l,
			master.dbo.sysservers s
		where s.srvid = l.remoteserverid
			and s.srvname = @server)
	begin
		rollback transaction dropserver
		/*
		** 17530, "There are still remote logins for the server '%1!'."
		*/
		raiserror 17530, @server
		return (1)
	end

	/*
	** OMNI: Check to see if there are any related external logins
	*/
	if exists (select * from master.dbo.sysattributes a,
			master.dbo.sysservers s
			where s.srvid = a.object_info1 and
			s.srvname = @server and
			a.class = 9 and a.attribute = 0)
	begin
		rollback transaction dropserver
		/*
		** 17534, "There are still external logins for the 
		**	   server '%1!'."
		*/
		raiserror 17534, @server
		return (1)
	end


	/* HA consistency checking */
	if (@nHARSTClass = 1)
	begin
		if exists (select 1 from 
				master.dbo.rmt_ha_sysremotelogins l,
				master.dbo.rmt_ha_sysservers s where 
				s.srvid = l.remoteserverid and 
				s.srvname = @server)
		begin
			rollback transaction dropserver

			/*
			** 18773, "HA_LOG: HA consistency check failure in 
			** stored procedure '%1!' on companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_dropserver", @@hacmpservername
			
			/*
			** 17530, "There are still remote logins for the 
			** server '%1!'."
			*/
			raiserror 17530, @server
			return (1)
		end

		/*
		** OMNI: Check to see if there are any related external logins
		*/
		if exists (select 1 from 
			master.dbo.rmt_ha_sysattributes a,
			master.dbo.rmt_ha_sysservers s 
			where s.srvid = a.object_info1 and
			s.srvname = @server and
			a.class = 9 and a.attribute = 0)
		begin
			rollback transaction dropserver

			/*
			** 18773, "HA_LOG: HA consistency check failure in 
			** stored procedure '%1!' on companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_dropserver", @@hacmpservername

			/* 
			** 17534, "There are still external logins for 
			** the server '%1!'."
			*/
			raiserror 17534, @server
			return (1)
		end
	end


end

/*
**  If @droplogins is true then drop any associated logins
*/
else if @droplogins = "droplogins"
begin
		delete master.dbo.sysremotelogins
			from master.dbo.sysremotelogins l,
				master.dbo.sysservers s
			where s.srvid = l.remoteserverid
				and s.srvname = @server

		if (@@rowcount > 0)
		begin

			if (@nHARSTClass = 1)
			begin
				delete master.dbo.rmt_ha_sysremotelogins from 
					master.dbo.sysremotelogins l,
					master.dbo.sysservers s 
					where s.srvid = l.remoteserverid and 
					s.srvname = @server
				if (@@rowcount <= 0)
				begin
					rollback tran dropserver
					return (1)
				end
			end


			/*
			** 17531, "Remote logins for remote server '%1!' 
			**	  have been dropped."
			*/
			exec sp_getmessage 17531, @msg output
			print @msg, @server
		end

		/*
		** OMNI: Drop any external logins as well
		*/
		delete master.dbo.sysattributes 
			from master.dbo.sysattributes a,
				master.dbo.sysservers s
			where s.srvname = @server
				and s.srvid = a.object_info1
				and a.class = 9 and a.attribute = 0

		if (@@rowcount > 0)
		begin
		

			if (@nHARSTClass = 1)
			begin
				delete master.dbo.rmt_ha_sysattributes from 
					master.dbo.rmt_ha_sysattributes a,
					master.dbo.rmt_ha_sysservers s where 
					s.srvname = @server and 
					s.srvid = a.object_info1 and 
					a.class = 9 and 
					a.attribute = 0
				if (@@rowcount <= 0)
				begin
					rollback tran dropserver
					return (1)
				end
			end

			/*
			** 17535, "External logins for remote server '%1!'
			** have been dropped."
			*/
			exec sp_getmessage 17535, @msg output
			print @msg, @server
		end

		/* Continue below and drop the server */
end

/*
**  Bad argument to @droplogins.
*/
else
begin
	/*
	** 17532, "Usage: sp_dropserver server [, droplogins]"
	*/
	rollback tran dropserver
	raiserror 17532
	return (1)
end

/*
** Hang up the connection to the server if there is one
*/
dbcc connection_hangup(@server)		


if (@nHARSTClass = 1)
begin
	select @sqlbuf = "dbcc connection_hangup(" + @server + ")"
	exec @status = sp_remotesql "SYB_HACMP", @sqlbuf
end


/*
** Fetch the srvid for this server
*/
select @srvid = srvid
from master.dbo.sysservers
	where srvname = @server

/*
** If the server belongs to the ejb class make sure the server is stopped
** before the entry from sysserver is deleted
*/

select @srvclass = srvclass , @physname = srvnetname
	from master.dbo.sysservers 
	where srvname = @server

if @srvclass = 10
begin
	select @command = "STOP"
	/*
	** We go ahead and stop the ejb server when the sp_dropserver command
	** is executed on an ejb server
	*/
	dbcc extengine(@physname, @srvclass, @command)
end

/*
**  Drop the server.
*/
delete master.dbo.sysservers
	where srvname = @server
if (@@error != 0)
begin
	rollback tran dropserver
	return (1)
end

/*
** Drop the rtds provider registered in sysattributes
*/
if (@insysattributes = 1)
	delete master.dbo.sysattributes
	where class = 21 and attribute = 10
		and object_type = 'PR'
		and object_cinfo = @server


if (@@error != 0)
begin
	rollback tran dropserver
	return (1)
end

if (@nHARSTClass = 1)
begin
	delete master.dbo.rmt_ha_sysservers
	where srvname = @server

	if (@@error != 0)
	begin
		rollback tran dropserver
		return (1)
	end

	if (@insysattributes = 1)
	begin
		delete master.dbo.rmt_ha_sysattributes
		where class = 21 and attribute = 10
			and object_type = 'PR'
			and object_cinfo = @server and object_cinfo = @server
		if (@@error != 0)
		begin
			rollback tran dropserver
			return (1)
		end
	end

	select @str_srvid = convert(char(6), @srvid)
	select @sqlbuf = "dbcc cis ('srvdes', " + @str_srvid + ")"
	exec @status = sp_remotesql "SYB_HACMP", @sqlbuf
end



/*
** For SDC, update cluster-wide in-memory SRVDES with data from
** just-updated SYSSERVERS table. Before dbcc cis, the dbcc command scope
** needs to be set to cluster.
*/
if (@@clustermode = "shared disk cluster")
begin
	select @scope = NULL
	select @outstr = "dbcc set_scope_in_cluster('scope')"
	if (charindex("instance", @outstr) != 0)
	begin
		/* save the scope to be restored later */
		select @scope = "instance"
		dbcc set_scope_in_cluster('cluster')
	end
end

/*
** Tag in-memory copy as
** unusable.
*/

dbcc cis ("srvdes", @srvid)

/* restore dbcc command scope */
if (@@clustermode = "shared disk cluster")
begin
	if (@scope = "instance")
	begin
		dbcc set_scope_in_cluster('instance')
	end
end

commit transaction dropserver

/*
** 17533, "Server dropped."
*/
exec sp_getmessage 17533, @msg output
print @msg

return (0)

clean_all:

	if (@nHARSTClass = 1)
		rollback transaction dropserver

	return (1)

go
exec sp_procxmode 'sp_dropserver', 'anymode'
go
grant execute on sp_dropserver to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_addgroup')
begin
	drop procedure sp_addgroup
end
go
print "Installing sp_addgroup"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.2	28.1	05/14/90	sproc/src/addgroup */

/*
** Messages for "sp_addgroup"           17240
**
** 17240, "'%1!' is not a valid name."
** 17241, "A user with the specified group name already exists."
** 17242, "A group with the specified name already exists."
** 17243, "New group added."  
** 17244, "All group ids have been assigned. No more groups can be added
**	   at this time."  
** 17336, "Setting curwrite label to data_low for inserts into sysusers
**	   table failed."
** 17756, "The execution of the stored procedure '%1!' in database
**         '%2!' was aborted because there was an error in writing the
**         replication log record."
** 17265, "A role with the specified name '%1!' already exists in this Server."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	After that, you need to add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_addgroup
@grpname varchar(255)			/* new group name */
as

declare @gid int			/* group id */
declare @msg varchar(1024)
declare @dummy int
declare @dbname varchar(255)
declare @maxlen int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @gid_hacmp int
declare @sqlbuf varchar(255)
declare @rtn_code int

select @nHARSTClass = ha_getrestrictionclass("sp_addgroup")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 3)
begin
	if (db_id() = 1)
		/* We only synch the user information for 'master' database */
		select @nHARSTClass = 1
	else
		select @nHARSTClass = 0
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_addgroup', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

set transaction isolation level 1
if @@trancount = 0
begin
	set chained off
end

/*
**  Only the Database Owner (DBO) or
**  Accounts with SA or SSO role can execute it.
**  Call proc_role() with the required SA role.
*/
if (user_id() != 1)
begin
	if (charindex("sa_role", show_role()) = 0 and
	    charindex("sso_role", show_role()) = 0)
	begin
		select @dummy = proc_role("sa_role")
		select @dummy = proc_role("sso_role")
		return (1)
	end
end

if (charindex("sa_role", show_role()) > 0)
	select @dummy = proc_role("sa_role")

if (charindex("sso_role", show_role()) > 0)
	select @dummy = proc_role("sso_role")

/*
**  Check to see that the @grpname is valid.
*/
if (@grpname is not null)
begin
	select @maxlen = length from syscolumns
	where id = object_id("sysusers") and name = "name"
	
	if valid_name(@grpname, @maxlen) = 0
	begin
		/*
		** 17240, "'%1!' is not a valid name."
		*/ 
		raiserror 17240,@grpname
		return 1
	end
end

/*
**  Check to see that @grpname is not a role name.
*/
if exists (select srid from master.dbo.syssrvroles
		where name = @grpname)
begin
	/*
	** 17265, "A role with the specified name '%1!' already exists in this
	**	   Server."
	*/
	raiserror 17265, @grpname
	return (1)
end

/*
**  See if the new group name is already being used as a user or group name.
*/
select @gid = uid
	from sysusers
where name = @grpname

/*
**  public group has id = 0
*/
if @gid is not null
begin

	if (@gid != 0) and (@gid < @@mingroupid or @gid > @@maxgroupid)
	begin
		/*
		** 17241, "A user with the specified group name already exists."
		*/
		raiserror 17241
	end
	else
	begin
		/*
		** 17242, "A group with the specified name already exists."
		*/
		raiserror 17242
	end
	return (1)
end

/*
**  Now get the group id for the new group.  It is the current maximum group
**  number + 1.  If this is the first group use the lowest possible group id
**  @@mingroupid.
*/
select @gid = max(uid)+1
	from sysusers where uid=gid and gid <= @@maxgroupid

/*
** No more group ids available
*/
if @gid = @@maxgroupid + 1
begin
	/*
	** 17244, "All group ids have been assigned. No more groups can be 
	** 	added at this time."  
	*/
	raiserror 17244
	return (1)
end
	
/*
**  This is the first group.
*/
if @gid < @@mingroupid or @gid is NULL
	select @gid = @@mingroupid


	if (@nHARSTClass = 1)
	begin
		/* HA consistency checking */

		/* Check to see that @grpname is not a role name. */
		if exists (select 1 from master.dbo.rmt_ha_syssrvroles
			where name = @grpname)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in '%1!' on
			** the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_addgroup", @@hacmpservername

			/*
			** 17265, "A role with the specified name '%1!' 
			** already exists in this Server."
		        */
		        raiserror 17265, @grpname
		        return (1)
		end

		/*
		** See if the new group name is already being used 
		** as a user or group name on the companion server.  
		*/
		select @gid_hacmp = uid
			from master.dbo.rmt_ha_sysusers
			where name = @grpname


		if (@gid_hacmp is not null)
		begin
			if ((@gid_hacmp < @@mingroupid and @gid_hacmp != 0) or 
				@gid_hacmp > @@maxgroupid)
			begin
				/*
				** 18773, "HA_LOG: HA consistency check 
				** fail in '%1!' on the companion server '%2!'"
				*/
				exec sp_getmessage 18773, @msg output
				print @msg, "sp_addgroup", @@hacmpservername

				/* 
				** 17241, "A user with the specified group 
				** name already exists."
				*/
				raiserror 17241
			end
			else
			begin
				/*
				** 18773, "HA_LOG: HA consistency check 
				** fail in '%1!' on the companion server '%2!'"
				*/
				exec sp_getmessage 18773, @msg output
				print @msg, "sp_addgroup", @@hacmpservername

		                /*
		                ** 17242, "A group with the specified name 
				** already exists."
				*/
		                raiserror 17242
			end
			
			return (1)
		end
		else
		begin
			/*
			**  Now get the group id for the new group on the 
			**  companion. It is the current maximum group
			**  number + 1.  If this is the first group use 
			**  the lowest possible group id -- @@mingroupid.
			*/
			select @gid_hacmp = max(uid)+1
			  from master.dbo.rmt_ha_sysusers
			  where gid = uid and gid <= @@maxgroupid

			/* No more group ids available */
			if @gid = @@maxgroupid + 1
			begin
				/*
				** 18773, "HA_LOG: HA consistency check 
				** fail in '%1!' on the companion server '%2!'"
				*/
				print @msg, "sp_addgroup", @@hacmpservername
				
				/*
				** 17244, "All group ids have been assigned. 
				** No more groups can be added at this time."
				*/
				raiserror 17244
				return (1)
			end

			/* This is the first group. */
			if (@gid_hacmp < @@mingroupid or @gid_hacmp is NULL)
				select @gid_hacmp = @@mingroupid 
		end
	end 

		

/*
**  Create the group.
*/

/* 
** This transaction also writes a log record for replicating the
** invocation of this procedure. If logexec() fails, the transaction
** is aborted.
**
** IMPORTANT: The name rs_logexec is significant and is used by
** Replication Server.
*/
begin transaction rs_logexec


if (@nHARSTClass = 1)
begin
	exec @rtn_code = sp_halockclustertables "sp_addgroup"
	if (@rtn_code != 0)
		goto clean_all
end


	insert into sysusers (uid, suid, gid, name, environ)
		values (@gid, -2, @gid, @grpname, "")

	if (@@error != 0)
	begin
		rollback tran rs_logexec
		return (1)
	end
		
	if (@nHARSTClass = 1)
	begin
		insert into master.dbo.rmt_ha_sysusers 
				(uid, suid, gid, name, environ)
                	 values (@gid_hacmp, -2, @gid_hacmp, @grpname, "")
		if ((@@error != 0) or (@@transtate = 3))
		begin
			rollback tran rs_logexec
			return (1)
		end

		select @sqlbuf = "declare @dummy int select @dummy = logexec()"
		exec sp_remotesql "SYB_HACMP", @sqlbuf
	end

	
	/*
	** Write the log record to replicate this invocation 
	** of the stored procedure.
	*/
	if (logexec() != 1)
	begin
		/*
		** 17756, "The execution of the stored procedure '%1!'
		** 	   in database '%2!' was aborted because there
		** 	   was an error in writing the replication log
		**	   record."
		*/
		select @dbname = db_name()
		raiserror 17756, "sp_addgroup", @dbname
				
		rollback transaction rs_logexec
		return(1)
	end

commit transaction rs_logexec

/*
** 17243, "New group added."  
*/
exec sp_getmessage 17243,  @msg out
print @msg

return (0)

clean_all:
	rollback transaction rs_logexec
	return (1)

go
exec sp_procxmode 'sp_addgroup', 'anymode'
go
grant execute on sp_addgroup to public
go
exec sp_procxmode 'sp_addgroup', 'rep_current'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_dropgroup')
begin
	drop procedure sp_dropgroup
end
go
print "Installing sp_dropgroup"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/dropgroup */

/*
** Messages for "sp_dropgroup"          17486
**
** 17289, "Set your curwrite to the hurdle of current database."
** 17333, "No group with the specified name exists." 
** 17486, "Can't drop the group 'public'."
** 17487, "You cannot drop group because it owns objects in database."
** 17488, "Group has members.  It must be empty before it can be dropped."
** 17489, "Group has been dropped."
** 17756, "The execution of the stored procedure '%1!' in database
**         '%2!' was aborted because there was an error in writing the
**         replication log record."
** 18075, "Set your maxwrite label correctly."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
**
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	After that, you need to add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
**
*/

create procedure sp_dropgroup
@grpname varchar(255)		/* group to be dropped */
as

declare @gid int		/* group id of the group to be dropped */
declare @msg varchar(1024)
declare @dummy int
declare @dbname varchar(255)
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @gid_hacmp int
declare @sqlbuf varchar(255)
declare @rtn_code int

select @nHARSTClass = ha_getrestrictionclass("sp_dropgroup")
if (@nHARSTClass = -1)
        return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 3)
begin
	if (db_id() = 1)
		/* We only synch the user information for 'master' database */
		select @nHARSTClass = 1
	else
		select @nHARSTClass = 0
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_dropgroup', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if @@trancount = 0
begin
	set chained off
end

set transaction isolation level 1

/*
**  Only the Database Owner (DBO) or
**  Accounts with SA or SSO role can execute it.
**  Call proc_role() with the required SA role.
*/
if (user_id() != 1)
begin
	if (charindex("sa_role", show_role()) = 0 and
	    charindex("sso_role", show_role()) = 0)
	begin
		select @dummy = proc_role("sa_role")
		select @dummy = proc_role("sso_role")
		return (1)
	end
end

if (charindex("sa_role", show_role()) > 0)
	select @dummy = proc_role("sa_role")

if (charindex("sso_role", show_role()) > 0)
	select @dummy = proc_role("sso_role")

/*
**  See if the group exists.
*/
select @gid = uid from sysusers
where name = @grpname
and ((uid between @@mingroupid and @@maxgroupid) or uid = 0)
and not exists (select name from master.dbo.syssrvroles where name = @grpname)

if @gid is NULL
begin
	/*
	** 17333, "No group with the specified name exists." 
	*/
	raiserror 17333
	return (1)
end

/*
**  Can't drop the group public.
*/
if @gid = 0
begin
	/*
	** 17486, "Can't drop the group 'public'."
	*/
	raiserror 17486
	return (1)
end

/*
**  Check to see if the group owns anything.  If so, return.
*/
if exists (select * from sysobjects where uid = @gid)
begin
	/*
	** 17487, "You cannot drop group because it owns objects in database."
	*/
	raiserror 17487

	/*
	**  Show what is owned by the group.
	*/
	select s.name, s.type, owner = u.name
		from sysobjects s, sysusers u
			where s.id = @gid
				and u.uid = @gid
	return (1)
end


/*
**  Check to see that nobody is in the group.  If so, return.
*/
if (select count(*) from sysusers
where gid = @gid and (uid < @@mingroupid or uid > @@maxgroupid)) != 0
begin
	/*
	** 17488, "Group has members.  It must be empty before it can be dropped."
	*/
	raiserror 17488

	/*
	**  Show who is in the group.
	*/
	select name from sysusers
	where gid = @gid and (uid < @@mingroupid or uid > @@maxgroupid)
	
	return (1)
end


if (@nHARSTClass = 1)
begin
	/* we need to do HA consistency checking before drop the group */
	
	/*
	**  See if the group exists on the companion server.
	*/
	select @gid_hacmp = uid from master.dbo.rmt_ha_sysusers
		where name = @grpname and
		((uid between @@mingroupid and @@maxgroupid) or uid = 0) and
			not exists (select name from 
					master.dbo.rmt_ha_syssrvroles
						where name = @grpname)
	if (@gid_hacmp is NULL)
	begin
		dbcc istraceon (2230)

		/* Tolerant inconsistency */
		if (@@error != 0)
		begin
			select @msg = "HA_LOG: HA consistency check failure in '"
					+ "sp_dropgroup" + 
					"' on the companion server '" + 
					@@hacmpservername + "'"
			dbcc printolog (@msg)

			select @msg = null
			select @msg = "No group with the specified name exists."
			dbcc printolog (@msg)
			
			select @msg = null
			select @nHARSTClass = 0
			goto out_of_HA_checking
		end

		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_dropgroup", @@hacmpservername

		/* 17333, "No group with the specified name exists." */
		raiserror 17333
		
		return (1)
	end

	/* Check to see if the group owns anything.  If so, return.  */
	if exists (select 1
		from master.dbo.rmt_ha_sysobjects
                           where uid = @gid_hacmp)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_dropgroup", @@hacmpservername

		/*
		** 17487, "You cannot drop group because it owns 
		** objects in database."
		*/
		raiserror 17487

		return (1)
	end

	/*
	**  Check to see that nobody is in the group.  If so, return.
	*/
	if exists (select 1
		from master.dbo.rmt_ha_sysusers
			where gid = @gid_hacmp
			and ((uid != 0 and uid < @@mingroupid) or 
			(uid > @@maxgroupid)))
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_dropgroup", @@hacmpservername

		/*
		** 17488, "Group has members.  It must be empty before 
		** it can be dropped."
		*/
		raiserror 17488

		return (1)
	end
end


out_of_HA_checking:

/*
**  Drop the group.
**  Also drop any references to the group in the sysprotects table.
*/
begin transaction rs_logexec


if (@nHARSTClass = 1)
begin
	exec @rtn_code = sp_halockclustertables "sp_dropgroup"
	if (@rtn_code != 0)
		goto clean_all
end


	delete from sysusers
		where uid = @gid

	if (@@error != 0)
	begin
		rollback tran rs_logexec
		return(1)
	end

	if (@nHARSTClass = 1)
	begin
		delete from master.dbo.rmt_ha_sysusers
			where uid = @gid_hacmp
		if ((@@error != 0) or (@@transtate = 3))
		begin
			rollback tran rs_logexec
			return(1)
		end
	end


	delete from sysprotects
		where uid = @gid


	if (@@error != 0)
	begin
		rollback tran rs_logexec 
		return(1)
	end

	if (@nHARSTClass = 1)
	begin
		delete from master.dbo.rmt_ha_sysprotects
			where uid = @gid_hacmp
		if ((@@error != 0) or (@@transtate = 3))
		begin
			rollback tran rs_logexec 
			return(1)
		end
	end
 

/*
** Write the log record to replicate this invocation 
** of the stored procedure.
*/
if (logexec() != 1)
begin
	/*
	** 17756, "The execution of the stored procedure '%1!' in
	**         database '%2!' was aborted because there was an
	**         error in writing the replication log record."
	*/
	select @dbname = db_name()
	raiserror 17756, "sp_dropgroup", @dbname
			
	rollback transaction rs_logexec
	return(1)
end


if (@nHARSTClass = 1)
begin
	select @sqlbuf = "declare @dummy int select @dummy = logexec()"
	exec sp_remotesql "SYB_HACMP", @sqlbuf
end


commit transaction rs_logexec

/*
** 17489, "Group has been dropped."
*/
exec sp_getmessage 17489, @msg output
print @msg

return (0)

clean_all:
	rollback transaction rs_logexec
	return (1)
go
exec sp_procxmode 'sp_dropgroup', 'anymode'
go
grant execute on sp_dropgroup to public
go
exec sp_procxmode 'sp_dropgroup', 'rep_current'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_changegroup')
begin
	drop procedure sp_changegroup
end
go
print "Installing sp_changegroup"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/changegroup */

/*
** Messages for "sp_changegroup"        17370
**
** 17289, "Set your curwrite to the hurdle of current database."
** 17333, "No such group exists."
**      (is now: "No group with the specified name exists.")
** 17232, "No such user exists."
**      (is now: "No user with the specified name exists in the current
** database.")
** 17370, "Group changed."
** 17756, "The execution of the stored procedure '%1!' in database
**         '%2!' was aborted because there was an error in writing the
**         replication log record."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18776, "Please also run stored procedure '%1!' on the companion server '%2!'."
** 18792, "Unable to find a group with name '%1!' and id '%2!' in sysusers."
** 18793, "Unable to find a user with name '%1!' and id '%2!' in sysusers."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	After that, you need to add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_changegroup
@grpname varchar(30),			/* group name */
@username varchar(30)			/* user name to add to group */
as

declare @gid int			/* group id */
declare @uid int			/* user id */
declare @msg varchar(1024)
declare @id  int			/* object id */
declare @grantee int			/* grantee */
declare @action	smallint		/* action (i.e select, insert) */
declare @protecttype tinyint		/* grant/revoke/option */
declare @columns varbinary (133)		/* column priv bit map */
declare @grantor int			/* grantor */
declare @gcolumns varbinary (133)       /* group column privileges */
declare @pcolumns varbinary (133)	/* public column privileges */
declare @aggrprivs tinyint		/* object level privs of group and public */
declare @aggrcolumns varbinary (133)	/* aggregate of group and public privileges */
declare @col_count smallint
declare @dummy int
declare @dbname varchar(30)
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @gid_hacmp int
declare @sqlbuf varchar(255)
declare @rtn_code int

select @nHARSTClass = ha_getrestrictionclass("sp_changegroup")
if (@nHARSTClass = -1)
        return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 3)
begin
	if (db_id() = 1)
		/* We only synch the user information for 'master' database */
		select @nHARSTClass = 1
	else
		select @nHARSTClass = 0
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_changegroup', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if @@trancount = 0
begin
	set chained off
end

set transaction isolation level 1

/*
**  Only the Database Owner (DBO) or
**  Accounts with SA or SSO role can execute it.
**  Call proc_role() with the required SA role.
*/
if (user_id() != 1)
begin
	if (charindex("sa_role", show_role()) = 0 and
	    charindex("sso_role", show_role()) = 0)
	begin
		select @dummy = proc_role("sa_role")
		select @dummy = proc_role("sso_role")
		return (1)
	end
end

if (charindex("sa_role", show_role()) > 0)
	select @dummy = proc_role("sa_role")

if (charindex("sso_role", show_role()) > 0)
	select @dummy = proc_role("sso_role")

/*
**  See if the group name exists.
*/
select @gid = uid from sysusers
where name = @grpname
and (uid = gid)
and not exists (select name from master.dbo.syssrvroles where name = @grpname)

/*
**  If no such group, quit.
*/
if @gid is NULL
begin
	/* 17333, "No group with the specified name exists." */
	raiserror 17333
	return (1)
end

/*
**  See if the user name exists.
*/
select @uid = uid from sysusers
where name = @username
and ((uid >= @@minuserid and uid < @@mingroupid and uid != 0) 
or uid > @@maxgroupid)

/*
**  If no such user in the database, quit.
*/
if @uid is NULL
begin

	/*
	** 17232, "No such user exists."
	*/
	raiserror 17232
	return (1)
end

/*
** At this stage everything is consistent with respect to parameters.
** Now we need to update the GRANTS/REVOKES to the user with respect to
** the new group
*/

begin transaction rs_logexec

/* 
** cursor to find tuples in sysprotect for which grantee is @uid 
*/
declare priv_curs cursor for 
	select id, uid, action, protecttype, columns, grantor
	from sysprotects
	where uid = @uid
	for update

/*
** open the cursor and start fetching from it
*/

open priv_curs

fetch priv_curs into @id, @grantee, @action, @protecttype, @columns, @grantor

/* loop for all qualifying rows */
while (@@sqlstatus != 2)
begin
     if (@@sqlstatus = 1)
     begin
	 /* error in fetching from the cursor */
	raiserror 17333
	rollback transaction rs_logexec
	return (1)
     end

     /*
     ** 193 is SELECT, 197 is UPDATE, 151 is REFERENCES. These are column
     ** level privileges 
     */
     if (((@action != 193) and (@action != 197)) and (@action != 151))
     begin
	  /*
	  ** these are object level privileges 
	  ** Note that grant with grant can't be given to group/PUBLIC thus
	  ** not considered  
          */
	  if (@protecttype = 1)
	  begin
	       /* it is a grant row  */
	       /* initialize aggregate privs */
	       select @aggrprivs = 0

	       /*
	       ** check if this grant is available to public
               */
	       if (exists (select * from sysprotects
		           where (id = @id) and
				 (uid = 0) and
				 (action = @action) and
				 (protecttype = @protecttype) and
				 (grantor = @grantor)))
	       begin
		     select @aggrprivs = 1		    
	       end

	       
	       if (@aggrprivs = 1)
	       begin
		    /* the grant of this privilege is available thru PUBLIC
		       check if there is a revoke to the new group */
	            if (exists (select * from sysprotects
		                where (id = @id) and
				      (uid = @gid) and
				      (action = @action) and
				      (protecttype = 2) and
				      (grantor = @grantor)))
		    begin
			  /* the revoke from group nullifies the grant from 
			     PUBLIC */
			  select @aggrprivs = 0
		    end
	       end
	       else
	       begin
		    /* the privilege was not available thru PUBLIC, check if
		       it is available thru group */
	            if (exists (select * from sysprotects
		                where (id = @id) and
				      (uid = @gid) and
				      (action = @action) and
				      (protecttype = 1) and
				      (grantor = @grantor)))
		    begin
			 /* the privilege is inherited from the group */
			 select @aggrprivs = 1
		    end
	       end


	       /* delete the grant to the user, if inherited due to the 
		  membership in the group or public */

	       if (@aggrprivs = 1)
		begin
			delete from sysprotects where current of priv_curs
	 	end 
	  end
	  else if (@protecttype = 2)
	  begin
	      /* it is a revoke */
	       if ((exists (select * from sysprotects
		           where (id = @id) and
			 	 (uid = @gid) and
				 (action = @action) and
				 (protecttype = @protecttype) and
				 (grantor = @grantor)))
	          or 
		  (not exists (select * from sysprotects
			   where (id = @id) and
				 (uid = @gid or uid = 0) and
				 (action = @action) and
				 (protecttype = 1) and	
				 (grantor = @grantor))))
	       begin
		    /* the privilege is already revoked from the group or there is no
		       explicit grant of this privilege to either group or public, so
		       this revoke row not needed */
			delete from sysprotects where current of priv_curs

		end
	end	
      end
      else
      begin
	   /* column level privileges */
           /* initialize column privilege map for public and group */
	   select @pcolumns = 0x00
	   select @gcolumns = 0x00

           /* get the number of columns in this table. It is only used for
           ** column level privileges 
	   */
           select @col_count = count (*)
           from syscolumns
           where id = @id

	   /* find the column level privileges to PUBLIC */
	   if (exists (select * from sysprotects
		       where (id = @id) and
			     (uid = 0) and
			     (action = @action) and
			     (protecttype = 1) and
		 	     (grantor = @grantor)))
	   begin
		select @pcolumns = columns from sysprotects
		where (id = @id) and
		      (uid = 0) and
		      (action = @action) and
		      (protecttype = 1) and
		      (grantor = @grantor)
	   end

	   /* find the column level privilege to the new GROUP */
	   if (exists (select * from sysprotects
		       where (id = @id) and
			     (uid = @gid) and
			     (action = @action) and
			     (protecttype = 1) and
			     (grantor = @grantor)))
	   begin
		select @gcolumns = columns from sysprotects
		where (id = @id) and
		      (uid = @gid) and
		      (action = @action) and
		      (protecttype = 1) and
		      (grantor = @grantor)
	   end
	      
	  /* find the union of column privileges from public as
	  ** new group  
	  */
	  exec sybsystemprocs.dbo.syb_aux_privunion @pcolumns, @gcolumns, @col_count, @aggrcolumns output

	  /* find if there is a revoke row for the above privilege 
	  ** in the group 
          */
	  select @gcolumns = 0x00
          if (exists (select * from sysprotects
	  	      where (id = @id) and
			    (uid = @gid) and
			    (action = @action) and
			    (protecttype = 2) and
			    (grantor = @grantor)))
	  begin
	       select @gcolumns = columns from sysprotects
	       where (id = @id) and
		     (uid = @gid) and
		     (action = @action) and
		     (protecttype = 2) and
		     (grantor = @grantor)

	  end

          /* subtract the revoke to columns from the group. In order to subtract,
	     exor operation will do as the revoke column bit can only be for columns
	     for which the user has inherited grant */

          exec sybsystemprocs.dbo.syb_aux_privexor @aggrcolumns, @gcolumns, @col_count, @aggrcolumns output

          /* at this stage, aggrcolumns contains the effective column privileges 
	     that are inherited */

	  if (@protecttype = 1)
	  begin
	       /* we encountered an explicit user specific grant row */
	       exec sybsystemprocs.dbo.syb_aux_privnots @aggrcolumns, @col_count, @aggrcolumns output

	       exec sybsystemprocs.dbo.syb_aux_privsand @columns, @aggrcolumns, @col_count, @columns output


	       if (@columns = 0x00)
	       begin
		     /* delete the grant row if no column is left. This implies that
			all explicit user grants were also inherited due to the user's
			membership in the group or PUBLIC */
		     delete sysprotects where current of priv_curs


	       end
	       else
	       begin
		    /* update the list of columns in the grant */
		    update sysprotects set columns = @columns
		    where current of priv_curs
	       end
	  end
	  else if (@protecttype = 2)
	  begin
	       /* it is a revoke row */
	       exec sybsystemprocs.dbo.syb_aux_privsand @columns, @aggrcolumns, @col_count, @columns output
	       /* We only keep those revoke bits for which there is an inherited
		  grant from the user's membership in the group or PUBLIC */
	       if (@columns = 0x00)
	       begin
		     /* delete the revoke row if no column is left */
		     delete sysprotects where current of priv_curs

	       end
	       else
	       begin
		    /* update the list of columns in the revoke */
		    update sysprotects set columns = @columns
		    where current of priv_curs
	       end
	  end
      end
      /*
      ** get the next qualifying tuple 
      */
      fetch priv_curs into @id, @grantee, @action, @protecttype, @columns, @grantor
end	
	
/*
**  Everything is consistent so change the group.
*/
update sysusers
	set gid = @gid
		from sysusers
	where uid = @uid

/*
** Write the log record to replicate this invocation 
** of the stored procedure.
*/
if (logexec() != 1)
begin
	/*
	** 17756, "The execution of the stored procedure '%1!' in
	**         database '%2!' was aborted because there was an
	**         error in writing the replication log record."
	*/
	select @dbname = db_name()
	raiserror 17756, "sp_changegroup", @dbname
			
	rollback transaction rs_logexec
	return(1)
end

commit transaction rs_logexec

/*
**  We need to invalidate the protection cache since objects have
**  changed ownership.  This command will invalidate the current
**  protection cache so when protections are checked the new and
**  correct protections will be used.
*/
grant all to null
/*
** 17370, "Group changed."
*/
exec sp_getmessage 17370, @msg output
print @msg


if (@nHARSTClass = 1)
begin
	/*
	** 18776, "Please also run stored procedure '%1!' on the companion 
	** server '%2!'."
	*/
	exec sp_getmessage 18776, @msg output
	print @msg, "sp_changegroup", @@hacmpservername
end


return (0)
go
exec sp_procxmode 'sp_changegroup', 'anymode'
go
grant execute on sp_changegroup to public
go
exec sp_procxmode 'sp_changegroup', 'rep_current'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_adduser')
begin
	drop procedure sp_adduser
end
go
print "Installing sp_adduser"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/adduser */

/*
** Messages for "sp_adduser"            17330
**
** 17240, "'" + @name_in_db + "' is not a valid name." 
** 17231, "No login with the specified name exists." 
** 17330, "A user with the same name already exists in the database."
** 17331, "User already has a login under a different name."
** 17332, "User already has alias access to the database."
** 17333, "No group with the specified name exists." 
** 17334, "All user ids have been assigned."
** 17335, "New user added."
** 17336, "Setting curwrite label to data_low for inserts into sysusers
**	   table failed."
** 17289, "Set your curwrite to the hurdle of current database."
** 17756, "The execution of the stored procedure '%1!' in database
**         '%2!' was aborted because there was an error in writing the
**         replication log record."
** 17265, "A role with the specified name '%1!' already exists in this Server."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '% 1!' on the companion server '%2!'"
** 18778, "A login with Login name '%1!' AND login id '%2!' could not be found in syslogins."
** 18796, "A user with name '%1!' or login id '%2!' already exists in sysusers."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	After that, you need to add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_adduser
@loginame varchar(255),			/* user's login name in syslogins */
@name_in_db varchar(255) = NULL,	/* user's name to add to current db */ 
@grpname varchar(255) = NULL		/* group to put new user in */
as

declare @suid int			/* user's system id */
declare @grpid int			/* group id of group to put user in */
declare @uid int			/* new user's id */
declare @msg varchar(1024)
declare @dummy int
declare @dbname varchar(255)
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int
declare @maxlen	  int

select @uid = NULL
select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass	int
declare @errmsg		varchar(1024)
declare @sqlbuf		varchar(255)
declare @rtn_code	int
declare @uid_hacmp int
declare @grpid_hacmp int

select @nHARSTClass = ha_getrestrictionclass("sp_adduser")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 3)
begin
	if (db_id() = 1)
		/* We only synch the user information for 'master' database */
		select @nHARSTClass = 1
	else
		select @nHARSTClass = 0
end

/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_adduser', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if @@trancount = 0
begin
	set chained off
end

set transaction isolation level 1

/*
**  Only the Database Owner (DBO) or
**  Accounts with SA or SSO role can execute it.
**  Call proc_role() with the required SA role.
*/
if (user_id() != 1)
begin
	if (charindex("sa_role", show_role()) = 0 and
	    charindex("sso_role", show_role()) = 0)
	begin
		select @dummy = proc_role("sa_role")
		select @dummy = proc_role("sso_role")
		return (1)
	end
end

if (charindex("sa_role", show_role()) > 0)
	select @dummy = proc_role("sa_role")
if (charindex("sso_role", show_role()) > 0)
	select @dummy = proc_role("sso_role")

/*
**  If no new user name is given, use the login name.
*/
if @name_in_db is NULL
	select @name_in_db = @loginame

/*
**  Check to see that the @name_in_db is valid.
*/
if (@name_in_db is not null)
begin
	select @maxlen = length from syscolumns
	where id = object_id("sysusers") and name = "name"

	if valid_name(@name_in_db, @maxlen) = 0
	begin
		/*
		** 17240, "'" + @name_in_db + "' is not a valid name." 
		*/
		raiserror 17240, @name_in_db
		return (1)
	end
end

/*
**  The name guest is a special case.  If it doesn't have a login it
**  can still be a valid user.  We'll catch it here and special case it.
*/
if @loginame = "guest" and not exists
	(select name
		from master.dbo.syslogins (index ncsyslogins)
			where name = @loginame)
begin
	if exists (select *
			from sysusers (index ncsysusers1)
		   where name = @loginame)
	begin
		/*
		** 17330, "A user with the same name already exists in the database."
		*/
		raiserror 17330
		return (1)
	end


	if (@nHARSTClass = 1)
	begin
		/* 
		** Do context consistency checking. Make sure "guest" 
		** user does not exists when login is not present.
		*/
		if exists (select 1 from master.dbo.rmt_ha_sysusers 
					where name = @loginame)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in 
			** '%1!' on the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_adduser", @@hacmpservername
	
			/*
			** 17330, "A user with the same name already exists 
			** in the database."
			*/
			raiserror 17330

			return (1)
		end
	end


	/*
	**  Add the guest user and return.
	*/

	/*
	** This transaction also writes a log record for replicating the
	** invocation of this procedure. If logexec() fails, the transaction
	** is aborted.
	**
	** IMPORTANT: The name rs_logexec is significant and is used by
	** Replication Server.
	*/

	begin transaction rs_logexec


if (@nHARSTClass = 1)
begin
	exec @rtn_code = sp_halockclustertables "sp_adduser"
	if (@rtn_code != 0)
		goto clean_all
end


		insert into sysusers (uid, suid, gid, name)
			values (@@guestuserid, -1, 0, "guest")


		if (@@error != 0)
		begin
			rollback tran rs_logexec
			return (1)
		end

		if (@nHARSTClass = 1)
		begin
			insert into master.dbo.rmt_ha_sysusers 
					(uid, suid, gid, name)
				values (@@guestuserid, -1, 0, "guest")
			if ((@@error != 0) or (@@transtate = 3))
			begin
				rollback tran rs_logexec
				return (1)
			end
	
			select @sqlbuf = "declare @dummy int select @dummy = logexec()"
			exec sp_remotesql "SYB_HACMP", @sqlbuf
		end


		/*
		** Write the log record to replicate this invocation 
		** of the stored procedure.
		*/
		if (logexec() != 1)
		begin
			/*
			** 17756, "The execution of the stored procedure
			**         '%1!' in database '%2!' was aborted
			**	    because there was an error in writing
			**	    the replication log record."
			*/
			select @dbname = db_name()
			raiserror 17756, "sp_adduser", @dbname
					
			rollback transaction rs_logexec
			return(1)
		end

	commit transaction rs_logexec

	return (0)
end

/*
**  Check to see that the user has a login name.
**  We'll also initialize @grpid to 0 while we're here.
*/
select @suid = suid, @grpid = 0
	from master.dbo.syslogins (index ncsyslogins)
where name = @loginame

if @suid is NULL
begin
	/*
	** 17231, "No login with the specified name exists." 
	*/
	raiserror 17231
	return (1)
end

/*
**  Now check to see if the user already exists in the database.
**  This will also check if there is a role or group with @name_in_db
**  already in this database.
*/
if exists (select *
		   from sysusers (index ncsysusers1)
	   where name = @name_in_db)
begin
	/*
	** 17330, "A user with the same name already exists in the database."
	*/
	raiserror 17330
	return (1)
end

/*
**  See if the user already has an account under a different name.
**  That is, is the user's suid already in the sysusers table.
*/
if exists (select *
	   from sysusers (index sysusers)
	   where suid = @suid)
begin
	/*
	** 17331, "User already has a login under a different name."
	*/
	raiserror 17331
	return (1)
end

/*
**  See if the user is known in the database already with an alias.
**  That is, does the user's suid appear in the sysalternates table.
*/
if exists (select *
	   from sysalternates
	   where suid = @suid)
begin
	/*
	** 17332, "User already has alias access to the database."
	*/
	raiserror 17332
	return (1)
end

/*
** Make sure a role does not already exist with name.
*/
if exists (select *
	from master.dbo.syssrvroles
	where name = @name_in_db)
begin
	/*
	** 17265, "A role with the specified name '%1!' already exists in this
	**	   Server."
	*/
	raiserror 17265, @name_in_db
	return (1)
end

/*
**  If a group name is given, check to see that it is valid.
**  public group has id = 0
*/
if @grpname is not NULL
begin
	select @grpid = -1
	select @grpid = gid from sysusers
	  where name = @grpname 
		and ( (uid = 0) or 
		      (uid between @@mingroupid and @@maxgroupid))
		and not exists (select name from master.dbo.syssrvroles 
				  where name = @grpname)


	if @grpid = -1
	begin
		/*
		** 17333, "No group with the specified name exists." 
		*/
		raiserror 17333
		return (1)
	end
end

/*
**  Add the user to the sysusers table.
**  Check to see if the special user 'guest' (uid = 2) has already
**  been added.  If not, then the uid to use is 3, otherwise max(uid) + 1.
**  uid can go upto (@@mingroupid - 1) and then there will be a discontinuity 
**  in the range @@mingroupid to @@maxgroupid which are reserved for groups.  
**  We can continue assigning uids from (@@maxgroupid + 1) upto @@maxuserid.  
**  After reaching @@maxuserid, we can wrap around to the -ve space and 
**  assign uid in the range (@@invaliduserid - 1) to @@minuserid.   
*/
/* 
**  HA NOTE: Whenever the logic of uid generation is changed, please also
**	  change it same way to the @uid_hacmp
*/
select @uid = max(uid) from sysusers
where (uid > @@guestuserid and uid < @@mingroupid) 
or (uid > @@maxgroupid and uid <= @@maxuserid)

if @uid  is NULL
/* The first regular user has uid = 3 */
	select @uid = @@guestuserid + 1
else
begin
	if @uid = @@mingroupid - 1	
		/* If we step into group range, skip group values */
		select @uid = @@maxgroupid + 1	
	else
	begin
		if @uid <> @@maxuserid 
			select @uid = @uid + 1
		else
		begin
			/* @@maxuserid has been used up, check the -ve space */
			select @uid = min(uid) from sysusers
			where uid < @@invaliduserid AND uid >= @@minuserid
		
			if @uid is NULL
			/* the first negative uid is -2 */
				select @uid = @@invaliduserid - 1
			else
			begin
				if @uid <> @@minuserid
					select @uid = @uid - 1
				else
				begin
					/* 17334, All uids have been assigned */
					raiserror 17334
					return(1)
				end
			end
		end
	end
end


	if (@nHARSTClass = 1)
	begin
		/* HA consistency checking */

		/* Check to see that the user has a login name. */
		if not exists (select 1 from master.dbo.rmt_ha_syslogins 
				  	where name = @loginame and 
						suid = @suid)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in 
			** '%1!' on the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_adduser", @@hacmpservername

			/*
			** 18778, "A login with Login name '%1!' AND 
			** login id '%2!' could not be found in syslogins."
			*/
			exec sp_getmessage 18778, @msg output
			print @msg, @loginame, @suid

			return (1)
		end

		/*
		** Now check to see if the user already exists or any other
		** user with the local generated uid exists in the companion
		** database.
		** This will also check if there is a role or group with 
		** @name_in_db already in this database.
		*/
		if exists (select 1 
			from master.dbo.rmt_ha_sysusers where 
				name = @name_in_db or 
				suid = @suid)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in 
			** '%1!' on the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_adduser", @@hacmpservername

			/*
			** 18796, "A user with name '%1!' or 
			** login id '%2!' already exists in sysusers."
			*/
			exec sp_getmessage 18796, @msg output
                        print @msg, @name_in_db, @suid

			return (1)
		end

		/* Generate the uid for the sysusers on the companion server */
		select @uid_hacmp = @uid
		if exists (select 1 from master.dbo.rmt_ha_sysusers
				where uid = @uid_hacmp)
		begin
			select @uid_hacmp = max(uid) 
			  from master.dbo.rmt_ha_sysusers
			  where (uid > @@guestuserid and 
				 uid < @@mingroupid) or 
				(uid > @@maxgroupid and 
				 uid <= @@maxuserid)

			if @uid_hacmp is NULL
				/* The first regular user has uid = 3 */
				select @uid_hacmp = @@guestuserid + 1
			else
			begin
				if @uid_hacmp = @@mingroupid - 1	
					/* If we step into group range, 
					** skip group values 
					*/
					select @uid_hacmp = @@maxgroupid + 1	
				else
				begin
					if @uid_hacmp <> @@maxuserid 
						select @uid_hacmp = @uid_hacmp + 1
					else
					begin
						/* @@maxuserid has been used up,
						** check the -ve space 
						*/
						select @uid_hacmp = min(uid) 
						  from master.dbo.rmt_ha_sysusers
						  where uid < @@invaliduserid AND uid >= @@minuserid
		
						if @uid_hacmp is NULL
							/* the first negative uid is -2 */
							select @uid_hacmp = @@invaliduserid - 1
						else
						begin
							if @uid_hacmp <> @@minuserid
								select @uid_hacmp = @uid_hacmp - 1
							else
							begin
								/* 17334, All uids have been assigned */
								raiserror 17334
								return(1)
							end
						end
					end
				end
			end
		end

		/*
		** See if the user is known in the database already with an 
		** alias. That is, does the user's suid appear in the 
		** sysalternates table.
		*/
		if exists (select 1 from master.dbo.rmt_ha_sysalternates
						where suid = @suid)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in '%1!' on
			** the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_adduser", @@hacmpservername

		        /*
		        ** 17332, "User already has alias access to the 
			** database."
			*/
			raiserror 17332
			
			return (1)
		end

		/* Make sure a role does not already exist with this name. */
		if exists (select 1 from master.dbo.rmt_ha_syssrvroles
		        		where name = @name_in_db)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in '%1!' on
			** the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_adduser", @@hacmpservername

			/*
			** 17265, "A role with the specified name '%1!' 
			** already exists in this Server."
			*/
			raiserror 17265, @name_in_db
			
			return (1)
		end

		/*
		** If a group name is given, check to see that it is valid 
		** on the companion.  public group has id = 0
		*/
		if @grpname is not NULL
		begin
			select @grpid_hacmp = -1
			select @grpid_hacmp = gid
			  from master.dbo.rmt_ha_sysusers
			  where name = @grpname and ((uid = 0) or (uid between @@mingroupid and @@maxgroupid))
			  and not exists (select name 
					    from master.dbo.rmt_ha_syssrvroles 
					    where name = @grpname)
			if (@grpid_hacmp = -1)
			begin
				/*
				** 18773, "HA_LOG: HA consistency check failure 
				** in '%1!' on the companion server '%2!'"
				*/
				exec sp_getmessage 18773, @msg output
				print @msg, "sp_adduser", @@hacmpservername
			
				/* 
				** 17333, "No group with the specified name 
				** exists."
				*/
				exec sp_getmessage 17333, @msg output
				print @msg
				
				return(1)
			end
		end
		else
			/* initialize @grpid_hacmp here */
			select @grpid_hacmp = 0
	end


/* 
** This transaction also writes a log record for replicating the
** invocation of this procedure. If logexec() fails, the transaction
** is aborted.
**
** IMPORTANT: The name rs_logexec is significant and is used by
** Replication Server.
*/
begin transaction rs_logexec


if (@nHARSTClass = 1)
begin
	exec @rtn_code = sp_halockclustertables "sp_adduser"
	if (@rtn_code != 0)
		goto clean_all
end


	insert into sysusers (uid, suid, gid, name)
		values (@uid, @suid, @grpid, @name_in_db)

        if (@@error != 0)
	begin
		rollback tran rs_logexec
		return (1)
	end
	
	if (@nHARSTClass = 1)
        begin
	        insert into master.dbo.rmt_ha_sysusers (uid, suid, gid, name)
	                values (@uid_hacmp, @suid, @grpid_hacmp, @name_in_db)
                if ((@@error != 0) or (@@transtate = 3))
                begin
                        rollback tran rs_logexec
                        return (1)
                end

		select @sqlbuf = "declare @dummy int select @dummy = logexec()"
		exec sp_remotesql "SYB_HACMP", @sqlbuf
        end


	/*
	** Write the log record to replicate this invocation 
	** of the stored procedure.
	*/
	if (logexec() != 1)
	begin
		/*
		** 17756, "The execution of the stored procedure '%1!'
		** 	   in database '%2!' was aborted because there
		** 	   was an error in writing the replication log
		**	   record."
		*/
		select @dbname = db_name()
		raiserror 17756, "sp_adduser", @dbname
				
		rollback transaction rs_logexec
		return(1)
	end

commit transaction rs_logexec

/*
** 17335, "New user added."
*/
exec sp_getmessage 17335, @msg output
print @msg

return (0)

clean_all:
	rollback transaction rs_logexec
	return (1)
go
exec sp_procxmode 'sp_adduser', 'anymode'
go
grant execute on sp_adduser to public
go
exec sp_procxmode 'sp_adduser', 'rep_current'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_dropuser')
begin
	drop procedure sp_dropuser
end
go
print "Installing sp_dropuser"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/defaultlanguage */

/*
** Messages for "sp_dropuser"           17543
**
** 17232, "No user with the specified name exists in the current database."
** 17289, "Set your curwrite to the hurdle of current database."
** 17431, "true"
** 17432, "false"
** 17543, "You cannot drop the 'database owner'."
** 17544, "You cannot drop the 'guest' user from master database or a temporary
**         database."
** 17545, "You cannot drop user because user '%1!' owns objects in database."
** 17546, "You cannot drop user because user '%1!' owns types in database."
** 17547, "The dependent aliases were also dropped."
** 17548, "User has been dropped from current database."
** 17549, "You cannot drop user because user '%1!'  owns grantable
**         privileges and granted them to other users.  The user
** 	   has granted the following privileges:"
** 17673, "All"
** 17756, "The execution of the stored procedure '%1!' in database
**         '%2!' was aborted because there was an error in writing the
**         replication log record."
** 18033, "You cannot drop user because user '%1!' owns thresholds in database."
** 18053, "User '%1!' was granted grantable privileges by the following users:"
** 18075, "Set your maxwrite label correctly."
** 18554, "You cannot drop user '%1!' because stored proc '%2!' owned by it 
**	   is bound to an execution class. Use sp_unbindexeclass before 
**	   dropping user."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18797, "Unable to find a user with name '%1!' and login id '%2!' in sysusers."
** 18815, "You cannot drop user '%1!' because it still owns objects, types, thresholds, privileges, and/or execution classes on the companion server '%2!'.  Issue stored procedure '%3!' on server '%4!' for details."
** 19941, "You cannot drop the user because the suid value for user '%1!' is
**        not unique in the database."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	After that, you need to add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_dropuser
@name_in_db varchar(255)			/* user name to drop */
as

declare @suid int			/* suid of the user */
declare @uid int			/* uid of the user */
declare @objectcount int		/* count of objects user owns */
declare @typecount int			/* count of types user owns */
declare @grantcount int			/* count of grants user made */
declare	@userdropped int		/* flag to indicate user was dropped */
declare @threshcount int		/* count of thresholds bound by user */
declare @spexebndcount int		/* cnt of user owned sp exe bindings */
declare @sp_name varchar(255)		/* name of stored proc */
declare @msg varchar(1024)
declare @msg_all   varchar(30)		/* msg for "all" equivalent */
declare @msg_true  varchar(30)		/* msg for "true" equivalent */
declare @msg_false varchar(30)		/* msg for "false" equivalent */
declare @dummy	int
declare @dbname varchar(255)
declare @tempdb_mask   int	/* All database status bit for a tempdb */
declare @isatempdb int			/* is database a temporary database */
declare @err1 int			/* temp. variable to store @@error */

declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0


/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @sqlbuf varchar(255)
declare @rtn_code int
declare @uid_hacmp smallint

select @isatempdb = 0			/* initialize variable */

select @nHARSTClass = ha_getrestrictionclass("sp_dropuser")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 3)
begin
	if (db_id() = 1)
		/* We only synch the user information for 'master' database */
		select @nHARSTClass = 1
	else
		select @nHARSTClass = 0
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_dropuser', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if @@trancount = 0
begin
	set chained off
end

set transaction isolation level 1

/*
**  Only the Database Owner (DBO) or
**  Accounts with SA or SSO role can execute it.
**  Call proc_role() with the required SA role.
*/
if (user_id() != 1)
begin
	if (charindex("sa_role", show_role()) = 0 and
	    charindex("sso_role", show_role()) = 0)
	begin
		select @dummy = proc_role("sa_role")
		select @dummy = proc_role("sso_role")
		return(1)
	end
end

if (charindex("sa_role", show_role()) > 0)
	select @dummy = proc_role("sa_role")

if (charindex("sso_role", show_role()) > 0)
	select @dummy = proc_role("sso_role")

/*
**  See if the user exists in the database.
*/
select @uid = uid, @suid = suid from sysusers
  where name = @name_in_db and 
	((uid < @@mingroupid and uid != 0) or (uid > @@maxgroupid))

/*
**  No such user so return.
*/
if @uid is NULL
begin
	/*
	** 17232, "No user with the specified name exists in the current database."
	*/
	raiserror 17232
	return (1)
end


if (@nHARSTClass = 1)
begin
	select @uid_hacmp = uid from master.dbo.rmt_ha_sysusers
	  where name = @name_in_db and ((uid < @@mingroupid and uid != 0) or
					(uid > @@maxgroupid))
	if @uid_hacmp is NULL
	begin
		dbcc istraceon (2230)	
		
		/* Tolerant inconsistency */
		if (@@error != 0)
		begin
			select @msg = "HA_LOG: HA consistency check failure in '"
					 + "sp_dropuser" + 
					"' on the companion server '" + 
					@@hacmpservername + "'"
			dbcc printolog (@msg)

			select @msg = null
			select @msg = "No user with the specified name exists in the current database"
			dbcc printolog (@msg)
			
			select @nHARSTClass = 0
			goto out_of_HA_checking
		end

		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_dropuser", @@hacmpservername

		/* 
		** 17232, "No user with the specified name exists in the 
		** current database"
		*/
		raiserror 17232
		return (1)
	end
end


out_of_HA_checking:

/*
**  Big trouble if dbo (uid = 1) is dropped so check.
*/
if @uid = 1
begin
	/*
	** 17543, "You cannot drop the 'database owner'."
	*/
	raiserror 17543
	return (1)
end

/*
** Check to see if we are dealing with a temporary database.
*/
select @tempdb_mask = number
	from master.dbo.spt_values
	where type = "D3" and name = "TEMPDB STATUS MASK"

if (db_id() = 2) or exists (select * from master..sysdatabases 
		       where dbid = db_id() 
		       and (status3 & @tempdb_mask) != 0) 
begin
	select @isatempdb = 1
end

/*
**  Trouble if guest gets dropped from master or tempdb, so check.
*/
if (@name_in_db = "guest" and (db_id() = 1 or @isatempdb = 1))
begin
	/*
	** 17544, "You cannot drop the 'guest' user from master or tempdb."
	*/
	raiserror 17544
	return(1)
end

/*
**  If the user owns any objects or datatypes and we're not
**  forcing the drop, return without doing anything.
*/
select @objectcount = count(*)
	   from sysobjects
		   where uid = @uid
select @typecount = count(*)
	from systypes
		where uid = @uid
select @grantcount = count(*)
	from sysprotects
		where grantor = @uid
			and id not in (select id from sysobjects
						where uid = @uid)
select @threshcount = count(*)
	from systhresholds
		where suid = @suid

select @spexebndcount = count(*)
	from sysattributes
		where (class = 6 and object_type = 'PR' and object_info1 = @uid)

if @objectcount > 0 or @typecount > 0 or @grantcount > 0 or @threshcount > 0 or
		@spexebndcount > 0
begin
	if @objectcount > 0
	begin
		/*
		** 17545, "You cannot drop user because user '%1!' owns objects in database."
		*/
		raiserror 17545, @name_in_db
		select name, type
			from sysobjects
				where uid = @uid
	end

	if @typecount > 0
	begin
		/*
		** 17546, "You cannot drop user because user '%1!' owns types in database."
		*/
		raiserror 17546, @name_in_db
		select user_type = a.name, physical_type = b.name
			from systypes a, systypes b
				where a.uid = @uid
					and a.type = b.type
					and b.usertype < 100
	end

	if @grantcount > 0
	begin

		/*
		** 17431, "true"
		** 17432, "false"
		*/
		exec sp_getmessage 17431, @msg_true output
		exec sp_getmessage 17432, @msg_false output
		/* 17673, "All" */
		exec sp_getmessage 17673, @msg_all out

		/* create and populate temp tables so that we can map 
		** column bit map to names 
		*/
		create table #sysprotects1 (id int, uid int, 
					    action smallint,
					    protecttype tinyint,
					    grantor int, number int)

		create table #sysprotects2 (id int, col_count smallint)

		insert into #sysprotects2 (id, col_count)
			select id, count (*)
			from syscolumns
			group by id

		insert into #sysprotects1 (id, uid, action, protecttype,
			grantor, number)
			select distinct
				p.id, p.uid, p.action, p.protecttype,
				p.grantor, c.number
				from sysprotects p, master.dbo.spt_values c
				where (~isnull (convert(tinyint, substring(p.columns, c.low, 1)), 0) & c.high != 0
					and c.number <= (select col_count from #sysprotects2 where id = p.id))
					and c.type = "P"
					and c.number <= 1024
					and p.columns is not null
					and convert(tinyint, substring(p.columns, 1, 1)) & 0x1 != 0
					and (convert(tinyint, substring(p.columns, 1, 1)) & 0xfe != 0
						or substring(p.columns, 2, 1) is not null)

		insert into #sysprotects1 (id, uid, action, protecttype,
			grantor, number)
			select distinct
				p.id, p.uid, p.action, p.protecttype,
				p.grantor, c.number
				from sysprotects p, master.dbo.spt_values c
				where convert(tinyint, substring(isnull(p.columns, 0x1), c.low, 1))
					& c.high != 0
					and c.type = "P"
					and c.number <= 1024
					and (p.columns is null
						or convert(tinyint, substring(p.columns, 1, 1)) & 0x1 = 0
						or (convert(tinyint, substring(p.columns, 1, 1)) & 0xfe = 0
							and substring(p.columns, 2, 1) is null))

		/* Set nocount on to avoid intermingling of output */
		set nocount on

		/*
		** 17549, "You cannot drop user because user '%1!' owns grantable
		**         privileges and granted them to other users.  The user
		** 	   has granted the following privileges:"
		*/
		raiserror 17549, @name_in_db
		print " "

		select grantee = u.name, 
			object = o.name, 
			column = substring(isnull(col_name(p.id, p.number), 
						  @msg_all), 1, 10),
			privilege = s.name
		from sysusers u, sysobjects o, #sysprotects1 p, 
		     master.dbo.spt_values s
		where p.grantor = @uid and p.uid = u.uid and p.protecttype < 2
	 	     and p.id = o.id and s.number = p.action 
		     and s.name is not NULL
		     and s.type = 'T'
		order by grantee, object, privilege

		/*
		** 18053, "User '%1!' was granted grantable privileges by the
		**         following users:"
		*/
		exec sp_getmessage 18053, @msg output
		print " "
		print @msg, @name_in_db
		
		select distinct grantor = u.name
		from sysusers u, sysprotects p
		where p.uid = @uid and u.uid = p.grantor and p.protecttype = 0
		order by grantor
	end

	if @threshcount > 0
	begin
		/*
		** 18033, "You cannot drop user because user '%1!' owns thresholds in database."
		*/
		raiserror 18033, @name_in_db
		select "Segment name" = g.name, "Free pages" = t.free_space
			from syssegments g, systhresholds t
				where t.suid = @suid
				  and t.segment = g.segment
	end

	if @spexebndcount > 0
	begin
		select @sp_name = object_cinfo from sysattributes
		where (class = 6 and object_type = 'PR' and object_info1 =@uid)
		/*
		** 18554, "You cannot drop user '%1!' because stored proc '%2!'
		**	 owned by it is bound to an execution class. Use 
		**	 sp_unbindexeclass before dropping user."
		*/
		raiserror 18554, @name_in_db, @sp_name
	end
	return (1)
end

/*
** Check if userid appears in sysprocesses. In that case somebody
** is still using it so we can not remove it.
*/
if exists (select * from master.dbo.sysprocesses where uid = @uid
			and dbid = db_id())
begin
	/*
	** 17915, "Warning: the specified account is currently active."
	*/
	exec sp_getmessage 17915, @msg output
	print @msg

	/*
	** 17918, "Nothing changed."
	*/
	exec sp_getmessage 17918, @msg output
	print @msg
	return (1)
end

/*
**  Drop the user.
**  Also drop any references to the user in the sysprotects table.
**  If anyone is aliased to the user, drop them also.
**
** IMPORTANT: The name rs_logexec is significant. It is used by 
** Replication Server.
*/


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */
	
	if not exists (select 1 from master.dbo.rmt_ha_sysusers
		       where name = @name_in_db and suid = @suid and
			(  (uid < @@mingroupid and uid != 0)
			 or (uid > @@maxgroupid)) )
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_dropuser", @@hacmpservername
		
		/*
		** 18797, "Unable to find a user with name '%1!'
		** and login id '%2!'."
		*/
                exec sp_getmessage 18797, @msg output
                print @msg, @name_in_db, @suid
 
		return(1)
	end
	
	/*
	**  If the user owns any objects or datatypes and we're not
	**  forcing the drop, return without doing anything.
	*/
	select @objectcount = count(*)
	   	from master.dbo.rmt_ha_sysobjects where uid = @uid_hacmp

	select @typecount = count(*) 
		from master.dbo.rmt_ha_systypes where uid = @uid_hacmp

	select @threshcount = count(*)
		from master.dbo.rmt_ha_systhresholds where suid = @suid

	select @spexebndcount = count(*)
		from master.dbo.rmt_ha_sysattributes
			where (class = 6 and object_type = 'PR' 
				and object_info1 = @uid_hacmp)

	select @grantcount = count(*)
		from master.dbo.rmt_ha_sysprotects
			where grantor = @uid_hacmp and id not in 
				(select id from master.dbo.rmt_ha_sysobjects
						where uid = @uid_hacmp)

	if @objectcount > 0 or @typecount > 0 or 
			@grantcount > 0 or @threshcount > 0 
						or @spexebndcount > 0
	begin
		/*
		** 18815, You cannot drop user '%1!' because it still 
		** owns objects, types, thresholds, privileges, and/or 
		** execution classes on the companion server '%2!'. 
		** Issue stored procedure '%3!' on server '%4!' for details.
		*/
		exec sp_getmessage 18815, @msg output
		print @msg, @name_in_db, @@hacmpservername, "sp_dropuser",
			@@hacmpservername

		return(1)
	end
end


begin transaction rs_logexec


if (@nHARSTClass = 1)
begin
	exec @rtn_code = sp_halockclustertables "sp_dropuser"
	if (@rtn_code != 0)
		goto clean_all
end


	delete from sysusers
		where suid = @suid
	select @err1 = @@error, @userdropped = @@rowcount


	if ((@@error != 0) or (@err1 != 0))
		goto clean_all

	if (@nHARSTClass = 1)
	begin
		delete from master.dbo.rmt_ha_sysusers where suid = @suid
		if ((@@error != 0) or (@@transtate = 3))
			goto clean_all
	end


	delete from sysprotects
		where uid = @uid


	if (@@error != 0)
		goto clean_all
	if (@nHARSTClass = 1)
	begin
		delete from master.dbo.rmt_ha_sysprotects where uid = @uid_hacmp
		if ((@@error != 0) or (@@transtate = 3))
			goto clean_all
	end

	
	/*
	**  Drop any dependent aliases.
	*/
	if exists (select *
			from sysalternates
				where altsuid = @suid)
	begin
		delete from sysalternates
			where altsuid = @suid


		if (@@error != 0)
			goto clean_all

		if (@nHARSTClass = 1)
		begin
			delete master.dbo.rmt_ha_sysalternates
				where altsuid = @suid
			if ((@@error != 0) or (@@transtate = 3))
				goto clean_all
		end

		/*
		** 17547, "The dependent aliases were also dropped."
		*/
		exec sp_getmessage 17547, @msg output
		print @msg
	end

	/* 
	**  Delete entries from sysattributes
	*/
	delete from sysattributes
		where object_type = "U"
		and object = @uid


	if (@@error != 0)
		goto clean_all

	if (@nHARSTClass = 1)
	begin
		delete master.dbo.rmt_ha_sysattributes
			where object_type = "U"
				and object = @uid_hacmp
		if ((@@error != 0) or (@@transtate = 3))
			goto clean_all
	end


        /* Delete entries from sysencryptkeys */

        if exists (select * from sysencryptkeys
                        where uid = @uid)
        begin
                delete from sysencryptkeys
                        where uid = @uid
        end


        if (@@error != 0)
                goto clean_all

        if (@nHARSTClass = 1)
        begin
                if exists (select * from master.dbo.rmt_ha_sysencryptkeys
                                where uid = @uid)
                begin
                        delete master.dbo.rmt_ha_sysencryptkeys
                                where uid = @uid
                end
                if ((@@error != 0) or (@@transtate = 3))
                        goto clean_all
        end


	if @userdropped != 1
	begin
		/*
		** 19941, "You cannot drop the user because the suid value for
		** user '%1!' is not unique in the database."
		*/
		raiserror 19941, @name_in_db

		goto clean_all
	end

	/*
	** Write the log record to replicate this invocation 
	** of the stored procedure.
	*/
	if (logexec() != 1)
	begin
		/*
		** 17756, "The execution of the stored procedure '%1!'
		** 	   in database '%2!' was aborted because there
		** 	   was an error in writing the replication log
		**	   record."
		*/
		select @dbname = db_name()
		raiserror 17756, "sp_dropuser", @dbname
				
		rollback transaction rs_logexec
		return(1)
	end


if (@nHARSTClass = 1)
begin
	select @sqlbuf = "declare @dummy int select @dummy = logexec()"
	exec sp_remotesql "SYB_HACMP", @sqlbuf
end


commit transaction rs_logexec

print_msg:

/*
** 17548, "User has been dropped from current database."
*/
exec sp_getmessage 17548, @msg output
print @msg

return (0)

clean_all:
	rollback transaction rs_logexec
	return (1)
go
exec sp_procxmode 'sp_dropuser', 'anymode'
go
grant execute on sp_dropuser to public
go
exec sp_procxmode 'sp_dropuser', 'rep_current'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_remoteoption')
begin
	drop procedure sp_remoteoption
end
go
print "Installing sp_remoteoption"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/remoteoption */

/*
** Messages for "sp_remoteoption"       17770
**
** 17513, "There is no remote user '%1!' mapped to local user '%2!' from
**	the remote server '%3!'."
** 17260, "Can't run %1! from within a transaction."
** 17770, "Settable remote login options."
** 17771, "There is no remote user '%1!' mapped to local user '%2!' on
**	remote server '%3!'."
** 17772, "Usage: sp_remoteoption [remoteserver, loginame, remotename,
**	optname, {true | false}]"
** 17773, "Remote login option doesn't exist or can't be set by user."
** 17774, "Run sp_remoteoption with no parameters to see options."
** 17775, "Remote login option is not unique."
** 17777, "Option '%1!' turned on."
** 17778, "Option '%1!' turned off."
** 17431, "true"
** 17432, "false"
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins."
** 18780, "Synchronization will not occur because server '%1!' is the companion server."
** 18782 "Unable to find a server with name '%1!' and id '%2!'."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_remoteoption
@remoteserver varchar(255) = NULL,	/* server name to change */
@loginame varchar(255) = NULL,		/* user's remote name */
@remotename varchar(255) = NULL,		/* user's local user name */
@optname varchar(20) = NULL,		/* option name to turn on/off */
@optvalue varchar(10) = NULL		/* true or false */
as

declare @statvalue 	smallint	/* number of option */
declare @optcount 	int		/* number of options like @optname */
declare	@msg		varchar(1024)
declare @suid		int
declare @rname  	varchar(255)
declare @lname  	varchar(255)
declare @true		varchar(10)
declare @false  	varchar(10)
declare @sptlang	int
declare @whichone	int		/* Which language */
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int
declare @hacmpsrv_netname varchar(255)
declare @remoteserver_netname varchar(255)
declare @srvid int
declare @rtn_code int

select @nHARSTClass = ha_getrestrictionclass("sp_remoteoption")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 1)
begin
	if ((@remoteserver = @@hacmpservername) OR (@remoteserver = "SYB_HACMP"))
	begin
		/*
		** 18780, "Synchronization will not occur because server 
		** '%1!' is the companion server."
		*/
		exec sp_getmessage 18780, @msg output
		print @msg, "sp_remoteoption", @remoteserver

		select @nHARSTClass = 0
	end
	else
	begin
		select @hacmpsrv_netname = srvnetname
		from master.dbo.sysservers
		where srvname = @@hacmpservername

		select @remoteserver_netname = srvnetname
		from master.dbo.sysservers
		where srvname = @remoteserver

		if (@hacmpsrv_netname = @remoteserver_netname)
		begin
			/*
			** 18780, "Synchronization will not occur 
			** because server '%1!' is the companion server."
			*/
			exec sp_getmessage 18780, @msg output
			print @msg, @remoteserver

			select @nHARSTClass = 0
		end
	end
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_remoteoption', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if @@trancount = 0
begin
	set chained off
end

set transaction isolation level 1

/* check if user has sso role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/

if (proc_role("sso_role") = 0)
	return (1)

select @sptlang = 0, @whichone = 0

if @@langid != 0
begin
	if not exists (
		select * from master.dbo.sysmessages where error
		between 17070 and 17079
		and langid = @@langid)
	    select @sptlang = 0
end

/*
**  If no @server given, just list the possible remote login options.
**  Only certain status bits may be set or cleared.  
**	   settable                	    not settable
**      ------------------------------  --------------------------
**	trusted (1)
*/
if @remoteserver is null
begin
	/*
	** 17770, "Settable remote login options."
	*/
	exec sp_getmessage 17770, @msg output
	print @msg
	if @sptlang = 0
	    exec sp_autoformat @fulltabname = "master.dbo.spt_values",
		@selectlist = "remotelogin_option = name",
		@whereclause = "where type = 'F' and number in (1, 1) and number > 0",
		@orderby = "order by name"
	else
	begin
	    select remotelogin_option = name, description
	    into #remoption1rs	
		from master.dbo.spt_values, master.dbo.sysmessages
			where type = "F"
				and number in (1, 1)
				and number > 0
				and msgnum = error
				and error between 17070 and 17079
				and langid = @sptlang
	    exec sp_autoformat @fulltabname = #remoption1rs,
		@orderby = "order by remotelogin_option"	
	    drop table #remoption1rs
	end
	return (0)
end

/*
**  If @loginame is NULL then we want to set @suid = -1. Otherwise get
**  it real value.
*/
if @loginame is null
	select @suid = -1
else select @suid = suser_id(@loginame)

/*
**  Verify the server name, local, and remote names. 
*/
if not exists (select *
		from master.dbo.sysremotelogins r, master.dbo.sysservers s
			where r.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and r.remoteusername = @remotename
				and r.suid = @suid)
begin
	/*
	** 17771, "There is no remote user '%1!' mapped to local user '%2!' on
	**	remote server '%3!'."
	*/
	select @rname = isnull(@remotename, "NULL")
	select @lname = isnull(@loginame, "NULL")
	raiserror 17771, @rname, @lname, @remoteserver
	return (1)
end

/*
**  Check remaining parameters.
*/
/* 17431, "true" */
exec sp_getmessage 17431, @true out
/* 17432, "false" */
exec sp_getmessage 17432, @false out
if @optname is NULL or lower(@optvalue) not in 
	("true", "false", @true, @false) or @optvalue is null
begin
	/*
	** 17772, "Usage: sp_remoteoption [remoteserver, loginame, remotename,
	**	optname, {true | false}]"
	*/
	raiserror 17772
	return (1)
end

/*
**  Use @optname and try to find the right option.
**  If there isn't just one, print appropriate diagnostics and return.
*/
select @optcount = count(*)
 	   from master.dbo.spt_values
		where name like "%" + @optname + "%" and type = "F"
			and number in (1, 1)
			and number > 0

/*
** If option not found, and language not english, then check some more
*/
if @optcount = 0 and @sptlang != 0
begin
    select @optcount = count(*)
 	   from master.dbo.spt_values, master.dbo.sysmessages
		where description like "%" + @optname + "%" and type = "F"
			and number in (1, 1)
			and number > 0
			and error between 17070 and 17079
			and msgnum = error
			and langid = @sptlang
    select @whichone = 1
end

/*
**  If no option, show the user what the options are.
*/
if @optcount = 0
begin
	/*
	** 17773, "Remote login option doesn't exist or can't be set by user."
	*/
	raiserror 17773
	/*
	** 17774, "Run sp_remoteoption with no parameters to see options."
	*/
	exec sp_getmessage 17774, @msg output
	print @msg
	return (1)
end

/*
**  If more than one option like @optname, show the duplicates and return.
*/
if @optcount > 1
begin
	/*
	** 17775, "Remote login option is not unique."
	*/
	raiserror 17775

	if @sptlang = 0
	begin
	    select duplicate_option = name
	    into #remoption2rs   	
		from master.dbo.spt_values
			where name like "%" + @optname + "%"
				and type = "F"
				and number in (1, 1)
				and number > 0
	    exec sp_autoformat @fulltabname = #remoption2rs
	    drop table #remoption2rs
	end
	else
	begin
	    select duplicate_option = name, description
	    into #remoption3rs  	
		from master.dbo.spt_values, master.dbo.sysmessages
			where 
				(name like "%" + @optname + "%" 
				or description like "%" + @optname + "%")
				and type = "F"
				and number in (1, 1)
				and number > 0
				and error between 17070 and 17079
				and msgnum = error
				and langid = @sptlang
	    exec sp_autoformat @fulltabname = #remoption3rs
	    drop table #remoption3rs
	end
      return (1)
end

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction."
	*/
	raiserror 17260, "sp_remoteoption"
	return (1)
end

/*
**  Get the number which is the bit value to set
*/
if @whichone = 0
    select @statvalue = number
 	   from master.dbo.spt_values
		where name like "%" + @optname + "%" and type = "F"
			and number in (1, 1)
			and number > 0
else
    select @statvalue = number
 	   from master.dbo.spt_values, master.dbo.sysmessages
		where description like "%" + @optname + "%" 
			and type = "F"
			and number in (1, 1)
			and number > 0
			and error between 17070 and 17079
			and msgnum = error
			and langid = @sptlang


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */

	if (@suid != -1)
	begin
		if not exists (select 1 from master.dbo.rmt_ha_syslogins
				where name = @loginame and suid = @suid)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure in '%1!' on
			** the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_remoteoption", @@hacmpservername

			/*
			** 18778, "Unable to find login '%1!' with id '%2!' 
			** in syslogins."
			*/
			exec sp_getmessage 18778, @msg output
			print @msg, @loginame, @suid

			return (1)
		end
	end
	
	select @srvid = srvid from master.dbo.sysservers
	where srvname = @remoteserver
	if not exists (select 1 from master.dbo.rmt_ha_sysservers
			where srvname = @remoteserver and srvid = @srvid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_remoteoption", @@hacmpservername

		/*
		** 18782 "Unable to find a server with name '%1!' and id '%2!'."
		*/
		exec sp_getmessage 18782, @msg output
                print @msg, @remoteserver, @srvid

		return (1)
	end
	
	/*
	** We need to make sure that the remote companion server
	** has the similar set of ids for the remote user and the
	** server
	*/
	if not exists (select 1 from 
		master.dbo.rmt_ha_sysremotelogins r, 
		master.dbo.rmt_ha_sysservers s where 
			r.remoteserverid = s.srvid and 
			s.srvname = @remoteserver and 
			r.remoteusername = @remotename and 
			r.suid = @suid) 
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_remoteoption", @@hacmpservername

		select @rname = isnull(@remotename, "NULL")
		select @lname = isnull(@loginame, "NULL")
		raiserror 17771, @rname, @lname, @remoteserver

		return(1)
	end

	begin tran ha_dynsyn

	exec @rtn_code = sp_halockclustertables "sp_remoteoption"
	if (@rtn_code != 0)
		goto clean_all
end


/*
**  Now update sysremotelogins.
*/
if lower(@optvalue) in ("true", @true)
begin
	update master.dbo.sysremotelogins
		set status = status | @statvalue
		from master.dbo.sysremotelogins r, master.dbo.sysservers s
			where r.remoteserverid = s.srvid
				and s.srvname = @remoteserver
				and r.remoteusername = @remotename
				and r.suid = @suid


	if (@@error != 0)
		goto clean_all

	if (@nHARSTClass = 1)
	begin
		update master.dbo.rmt_ha_sysremotelogins
		set status = status | @statvalue
		from master.dbo.rmt_ha_sysremotelogins r, 
			master.dbo.rmt_ha_sysservers s
		where r.remoteserverid = s.srvid
			and s.srvname = @remoteserver
                                and r.remoteusername = @remotename
                                and r.suid = @suid

		if @@error != 0
			goto clean_all
	end

	

	/*
	** 17777, "Option '%1!' turned on."
	*/
	exec sp_getmessage 17777, @msg output
	print @msg, @optname


	if (@nHARSTClass = 1)
		commit tran ha_dynsyn

	return (0)
end

/*
**  We want to turn it off.
*/
else
begin
	update master.dbo.sysremotelogins
	set status = status & ~@statvalue
	from master.dbo.sysremotelogins r, master.dbo.sysservers s
	where r.remoteserverid = s.srvid
		and s.srvname = @remoteserver
		and r.remoteusername = @remotename
		and r.suid = @suid


        if (@@error != 0)
		goto clean_all

	if (@nHARSTClass = 1)
	begin
		update master.dbo.rmt_ha_sysremotelogins
		set status = status & ~@statvalue from 
			master.dbo.rmt_ha_sysremotelogins r, 
			master.dbo.rmt_ha_sysservers s where 
			r.remoteserverid = s.srvid and 
			s.srvname = @remoteserver and 
			r.remoteusername = @remotename and 
			r.suid = @suid

		if (@@error != 0)
        		goto clean_all
        end

	

	/*
	** 17778, "Option '%1!' turned off."
	*/
	exec sp_getmessage 17778, @msg output
	print @msg, @optname


	if (@nHARSTClass = 1)
		commit tran ha_dynsyn


	return (0)
end

return (0)


clean_all:
if (@nHARSTClass = 1)
	rollback tran ha_dynsyn
return(1)

go
exec sp_procxmode 'sp_remoteoption', 'anymode'
go
grant execute on sp_remoteoption to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_serveroption')
begin
	drop procedure sp_serveroption
end
go
print "Installing sp_serveroption"
go

/* Sccsid = "%M% generic/sproc/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/serveroption */

/*
** Messages for "sp_serveroption"       17800
**
** 17260, "Can't run %1! from within a transaction." 
** 17800, "No such server -- run sp_helpserver to list servers."
** 17801, "Usage: sp_serveroption [server, {{security mechanism, mechname} | {server cost, value} | 
**	{optname, {true | false}}}]"
** 17802, "Server option doesn't exist or can't be set by user."
** 17803, "Run sp_serveroption with no parameters to see options."
** 17804, "Server option is not unique."
** 17806, "Option can be set for remote servers only -- not the local server."
** 17807, "Settable server options."
** 17809, "Confidentiality, integrity, and mutual authentication are \
**	   valid with rpc security model B only."
** 17431, "true"
** 17432, "false"
** 18076, "Could not set curwrite to object level. Set your maxwrite label correctly."
** 18686, "Server option 'server logins' cannot be set when @@servername is null"
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on companion server '%2!'"
** 18780, "Server '%1!' is the companion server, therefore, synchronization is d
isallowed."
** 18782, "Unable to find a server with name '%1!' and id '%2!'."
** 18890, "Only the 'external engine auto start' option can be enabled for the 
** ejb class of servers."
** 19255, "The option '%s' can be set for '%s' server class only." 
** 19661, "Server '%1!' is not a cluster instance, can not set server option."
** 19662, "Server name '%1!' doesn't match with its netname '%2!', can not set server option."
** 19663, "Server '%1!' is a cluster instance, can not unset server option."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_serveroption
@server varchar(255) = NULL,		/* server name to change */
@optname varchar(30) = NULL,		/* option name to turn on/off */
@optvalue varchar(20) = NULL		/* true or false */
as

declare @srvid int			/* id of the server */
declare @inst_id int			/* cluster instance id */ 
declare @netname varchar(255)		/* server net name */
declare @srvstatus int			/* value of sysservers.srvstatus */
declare @srvstatus2 unsigned int        /* value of sysservers.srvstatus2 */
declare @srvclass smallint		/* class of the server */
declare @model_a_value smallint		/* value of security model A */
declare @model_b_value smallint		/* value of security model B */
declare @model_b1_value smallint	/* value of use msg confidentiality */
declare @model_b2_value smallint	/* value of use msg integrity */
declare @model_b3_value smallint	/* value of mutual authentication */
declare @statvalue smallint		/* number of option for srvstatus */
declare @statvalue2 unsigned int	/* number of option for srvstatus2 */
declare @optcount int			/* number of options like @optname */
declare @msg varchar(1024) 
declare @true varchar(30) 
declare @false varchar(30) 
declare @status int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int
declare @rowlimit int
declare	@outstr	varchar(255),	/* for SDC dbcc set_scope */
	@scope	varchar(16)	/* for SDC dbcc set_scope */

select @HA_CERTIFIED = 0


select @status = 0


/* Dynamic synchronization related variables declaration and initialization */
declare @str_srvid		varchar(11)
declare @sqlbuf 		varchar(255)
declare @nHARSTClass		int
declare @hacmpsrv_netname	varchar (32)
declare @remoteserver_netname	varchar (32)
declare @rtn_code	int

select @nHARSTClass = ha_getrestrictionclass("sp_serveroption")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 1)
begin
        if ((@@hacmpservername = @server) OR (@server = "SYB_HACMP"))
	begin
		/*
		**  18780, "Server '%1!' is the companion server, 
		** synchronization is disallowed."
		*/
		exec sp_getmessage 18780, @msg output
		print @msg, @server
		select @nHARSTClass = 0
	end
        else
	begin
                select @hacmpsrv_netname = srvnetname
                from master.dbo.sysservers
                where srvname = @@hacmpservername

                select @remoteserver_netname = srvnetname
                from master.dbo.sysservers
                where srvname = @server

                if (@hacmpsrv_netname = @remoteserver_netname)
		begin
			/*
			**  18780, "Server '%1!' is the companion server,
			** synchronization is disallowed."
			*/
			exec sp_getmessage 18780, @msg output
			print @msg, @server
			select @nHARSTClass = 0
		end
        end
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_serveroption', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
begin
	/* 
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_serveroption"
	return (1)
end

if @@trancount = 0
begin
	set chained off
end

set transaction isolation level 1

/*
**  If no @server given, just list the possible server options.
**  Only certain status bits may be set or cleared.  
**  The default is to allow timeouts (bit 0 is clear) and to
**  perform no network password encryption (bit 1 is clear).
**	   settable                	    not settable
**      ------------------------------  --------------------------
**    0    timeouts
**    2    net password encryption
**    4    readonly
**    8    rpc security model A
**    16   rpc security model B
**    32   cis hafailover
**    64   use message confidentiality
**    128  use message integrity
**    256  mutual authentication
**    512  server logins
**    1024 external engine auto start
**    4096 negotiated logins
**	   security mechanism
**	   server cost
**
**  srvstatus2:
**
**	   settable                	    not settable
**      ------------------------------  --------------------------
**    1    relocated joins
**    2    enable login redirection	
**    4	   cluster instance
**    8    incompatible sort order
**
**
**  Notice that options "security mechanism" and "server cost"
**  are not represented by a bit of srvstatus and therefore
**  are no corresponding entries in spt_values for them.
**  Select the options from spt_values unioned with these options
**  into a temp table for use in this procedure.
*/
select @rowlimit = @@setrowcount	
set rowcount 0

select name into #server_options
		from master.dbo.spt_values where 
                        (type = "A" and number not in (-1, 1)) or type = "A2"
	union
	select "server cost"
	union
	select "security mechanism"

set rowcount @rowlimit

if @server is null
begin
	/* 17807, "Settable server options." */
	exec sp_getmessage 17807, @msg out
	print @msg
	select "" = name from #server_options order by 1
	return (0)
end

/*
**  Verify the server name and get the @srvid
*/
select @srvid = srvid
	from master.dbo.sysservers
		where srvname = @server

/*
**  If @server not found, say so. 
*/
if @srvid is NULL
begin
	/*
	** 17800, "No such server -- run sp_helpserver to list servers."
	*/
	raiserror 17800
	return (1)
end

/*
** Make sure only the 'external engine auto start option' can be used if the
** class of servers belong to the ASEJB class
*/
if exists (select 1 from master.dbo.sysservers where 
		srvname = @server and srvclass = 10)
begin
	if @optname not like "%external engine auto%"
	begin
		/*
		** 18890, "Only the 'external engine auto start' option can 
		** be enabled for the ejb class of servers."
		*/
		raiserror 18890
		return (1)
	end
end
else
begin
	/*
	** The server is not an EJB Server. 
	** The 'external engine auto start' option can only be set for EJB Servers. For all
	** other classes of servers, this is considered to be an invalid option.
	*/
	if @optname like "%external engine auto%"
	begin
		/*
		** 19255, "The option '%s' can be set for '%s' server class only."
		*/
		raiserror 19255, "external engine auto start", "EJB"
		return (1)
	end
end


if (@nHARSTClass = 1)
begin
	if not exists (select 1 from 
			master.dbo.rmt_ha_sysservers where
			srvid = @srvid and srvname = @server)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_serveroption", @@hacmpservername
		
		/*
		** 18782, "Unable to find a server with name '%1!' 
		** and id '%2!'."
		*/
		exec sp_getmessage 18782, @msg output
                print @msg, "sp_serveroption", srvname, srvid

		return (1)
	end
end
		

/*
**  Check remaining parameters.
**  Note that "security mechanism" and "server cost" take a value instead of true or false
*/
/* 17431, "true" */
exec sp_getmessage 17431, @true out
/* 17432, "false" */
exec sp_getmessage 17432, @false out
if @optname is NULL or
	( @optname not like "%security me%" and @optname not like "%server c%"
	and lower(@optvalue) not in
	("true", "false", @true, @false) ) or
        ( @optname not like "%security me%" and @optvalue is null )
begin
	/*
	** 17801, "Usage: sp_serveroption [server, {{security mechanism, mechname} | 
	**         {server cost, value} | {optname, {true | false}}}]"
	*/
	raiserror 17801
	return (1)
end

/*
**  Use @optname and try to find the right option.
**  If there isn't just one, print appropriate diagnostics and return.
*/
select @optcount = count(*)
 	   from #server_options
		where name like "%" + @optname + "%"

/*
**  If no option, show the user what the options are.
*/
if @optcount = 0
begin
	/*
	** 17802, "Server option doesn't exist or can't be set by user."
	*/
	raiserror 17802
	/*
	** 17803, "Run sp_serveroption with no parameters to see options."
	*/
	exec sp_getmessage 17803, @msg output
	print @msg
	return (1)
end

/*
**  If more than one option like @optname, show the duplicates and return.
*/
if @optcount > 1
begin
	/*
	** 17804, "Server option is not unique."
	*/
	raiserror 17804

	select duplicate_option = name
		from #server_options
			where name like "%" + @optname + "%"

	return (1)
end

/*
**  Currently there are two options that can be set -- no timeouts and
**  net password encryption -- and both only apply to remote servers.  
**  If the current server is local then reject it.
*/
if @srvid = 0
begin
	/*
	** 17806, "Option can be set for remote servers only -- not the local server."
	*/
	raiserror 17806
	return (1)
end


if (@nHARSTClass = 1)
begin
	begin tran ha_dynsyn
	exec @rtn_code = sp_halockclustertables "sp_serveroption"
	if (@rtn_code != 0)
		goto clean_all
end


if @optname like "%security me%"
begin
	if (proc_role("sso_role") < 1)
		return(1)
 
	update master.dbo.sysservers
		set srvsecmech = @optvalue
		where srvid = @srvid


	if (@@error != 0)
		goto clean_all

        if (@nHARSTClass = 1)
        begin
        	update master.dbo.rmt_ha_sysservers
                set srvsecmech = @optvalue where srvid = @srvid

	        if (@@error != 0)
			goto clean_all

		commit tran ha_dynsyn
        end
	

	return (0)
end

/*
** Update the server cost
*/
if @optname like "%server c%"
begin
	/*
	** Changing the server cost requires SA role
	*/
	if (proc_role("sa_role") < 1)
		goto clean_all

	update master.dbo.sysservers
		set srvcost = convert(smallint, @optvalue)
		where srvid = @srvid


	if (@@error != 0)
		goto clean_all

        if (@nHARSTClass = 1)
        begin
        	update master.dbo.rmt_ha_sysservers
                	set srvcost = convert(smallint, @optvalue) 
			where srvid = @srvid

	        if (@@error != 0)
			goto clean_all

		/*
		** Update the srvdes
		*/
		select @str_srvid = convert(char(10), @srvid)
		select @sqlbuf = "dbcc cis ('srvdes', " + @str_srvid + ")"
		exec sp_remotesql "SYB_HACMP", @sqlbuf

		commit tran ha_dynsyn
        end
	

	/*
	** Update the srvdes
	** For SDC, update cluster-wide in-memory SRVDES with data from
	** just-updated SYSSERVERS table. Before dbcc cis, the dbcc
	** command scope needs to be set to cluster.
	*/
	if (@@clustermode = "shared disk cluster")
	begin
		select @scope = NULL
		select @outstr = "dbcc set_scope_in_cluster('scope')"
		if (charindex("instance", @outstr) != 0)
		begin
			/* save the scope to be restored later */
			select @scope = "instance"
			dbcc set_scope_in_cluster('cluster')
		end
	end

	dbcc cis ("srvdes", @srvid)

	/* restore dbcc command scope */
	if (@@clustermode = "shared disk cluster")
	begin
		if (@scope = "instance")
		begin
			dbcc set_scope_in_cluster('instance')
		end
	end

	return (0)
end

/*
**  Get the number which is the bit value to set in srvstatus2
*/
select @statvalue2 = number
 	   from master.dbo.spt_values
		where name like "%" + @optname + "%" and type = "A2"
			and number > 0

/*
** Update serveroption in srvstatus2 field
**
** 	statvalue2	serveroption
**	---------	------------
**	   1		<reserved for "relocated joins" in 15.0.2>
**	   2		enable login redirection
**	   4		cluster instance
**
*/
if (@statvalue2 in (2, 4))
begin
	if (proc_role("sa_role") < 1)
		goto clean_all

        select @srvstatus2 = isnull(srvstatus2, 0) from master.dbo.sysservers
	        where srvid = @srvid 

        if lower(@optvalue) in ("true", @true)
        begin
		if (@statvalue2 = 4)
		begin
			select @inst_id = instance_id(@server)
			if @inst_id is NULL
			begin
				/*
				** 19661, "Server '%1!' is not a cluster instance, 
				** can not set server option."
				*/
				exec sp_getmessage 19661, @msg output
				print @msg, @server
				goto clean_all
			end
			select @netname=srvnetname from master.dbo.sysservers
				where srvid = @srvid
			if (@server != @netname)
			begin
				/*
				** 19662, "Server name '%1!' doesn't match with its netname '%2!', 
				** can not set server option."
				*/
				exec sp_getmessage 19662, @msg output
				print @msg, @server, @netname
				goto clean_all
			end
		end
		update master.dbo.sysservers
			set srvstatus2 = @srvstatus2 | @statvalue2
				where srvid = @srvid

        	if (@@error != 0)
		        goto clean_all

                if (@nHARSTClass = 1)
                begin
        	        update master.dbo.rmt_ha_sysservers
                	        set srvstatus2 = @srvstatus2 | @statvalue2
			        where srvid = @srvid

	                if (@@error != 0)
			        goto clean_all

		        /*
		        ** Update the srvdes
		        */
		        select @str_srvid = convert(char(10), @srvid)
		        select @sqlbuf = "dbcc cis ('srvdes', " + @str_srvid + ")"
		        exec sp_remotesql "SYB_HACMP", @sqlbuf

		        commit tran ha_dynsyn
                end

        end
        else
        begin
		if (@statvalue2 = 4)
		begin
			select @inst_id = instance_id(@server)
			if @inst_id is not NULL
			begin
				/*
				** 19663, "Server '%1!' is a cluster instance, 
				** can not unset server option."
				*/
				exec sp_getmessage 19663, @msg output
				print @msg, @server
				goto clean_all
			end
		end
                update master.dbo.sysservers
			set srvstatus2 = @srvstatus2 & ~@statvalue2
				where srvid = @srvid

                if (@@error != 0)
                        goto clean_all

                if (@nHARSTClass = 1)
                begin
                        update master.dbo.rmt_ha_sysservers
                                set srvstatus2 = @srvstatus2 & ~@statvalue2
                                        where srvid = @srvid

                        if (@@error != 0)
		                goto clean_all

	                /*
	                ** Update the srvdes
	                */
	                select @str_srvid = convert(char(10), @srvid)
	                select @sqlbuf = "dbcc cis ('srvdes', " + @str_srvid + ")"
	                exec sp_remotesql "SYB_HACMP", @sqlbuf

	                commit tran ha_dynsyn
                end

        end

	/*
	** Update the srvdes
	** For SDC, update cluster-wide in-memory SRVDES with data from
	** just-updated SYSSERVERS table. Before dbcc cis, the dbcc
	** command scope needs to be set to cluster.
	*/
	if (@@clustermode = "shared disk cluster")
	begin
		select @scope = NULL
		select @outstr = "dbcc set_scope_in_cluster('scope')"
		if (charindex("instance", @outstr) != 0)
		begin
			/* save the scope to be restored later */
			select @scope = "instance"
			dbcc set_scope_in_cluster('cluster')
		end
	end

	dbcc cis ("srvdes", @srvid)

	/* restore dbcc command scope */
	if (@@clustermode = "shared disk cluster")
	begin
		if (@scope = "instance")
		begin
			dbcc set_scope_in_cluster('instance')
		end
	end

        return (0)
end

/*
** Update srvstatus2 field values
**    1    relocated joins 
**    8    incompatible sort order
*/
if (@optname like "%rel%" or @optname like "%inc%")
begin
	/*
	**  Get the number which is the bit value to set
	*/
	select @statvalue2 = number
		   from master.dbo.spt_values
			where name like "%" + @optname + "%" and type = "A2"
				and number > 0
	/*
	** Changing 'relocated joins' or 'incompatible sort order' requires SA role
	*/
	if (proc_role("sa_role") < 1)
		goto clean_all

        select @srvstatus2 = isnull(srvstatus2, 0) from master.dbo.sysservers
	        where srvid = @srvid 

        if lower(@optvalue) in ("true", @true)
        begin
		update master.dbo.sysservers
			set srvstatus2 = @srvstatus2 | @statvalue2
				where srvid = @srvid

        	if (@@error != 0)
		        goto clean_all

                if (@nHARSTClass = 1)
                begin
        	        update master.dbo.rmt_ha_sysservers
                	        set srvstatus2 = @srvstatus2 | @statvalue2
			        where srvid = @srvid

	                if (@@error != 0)
			        goto clean_all

		        /*
		        ** Update the srvdes
		        */
		        select @str_srvid = convert(char(10), @srvid)
		        select @sqlbuf = "dbcc cis ('srvdes', " + @str_srvid + ")"
		        exec sp_remotesql "SYB_HACMP", @sqlbuf

		        commit tran ha_dynsyn
                end

        end
        else
        begin
                update master.dbo.sysservers
			set srvstatus2 = @srvstatus2 & ~@statvalue2
				where srvid = @srvid

                if (@@error != 0)
                        goto clean_all

                if (@nHARSTClass = 1)
                begin
                        update master.dbo.rmt_ha_sysservers
                                set srvstatus2 = @srvstatus2 & ~@statvalue2
                                        where srvid = @srvid

                        if (@@error != 0)
		                goto clean_all

	                /*
	                ** Update the srvdes
	                */
	                select @str_srvid = convert(char(10), @srvid)
	                select @sqlbuf = "dbcc cis ('srvdes', " + @str_srvid + ")"
	                exec sp_remotesql "SYB_HACMP", @sqlbuf

	                commit tran ha_dynsyn
                end

        end

	/*
	** Update the srvdes
	*/
	dbcc cis ("srvdes", @srvid)

        return (0)
end


/*
**  Get the number which is the bit value to set
*/
select @statvalue = number
 	   from master.dbo.spt_values
		where name like "%" + @optname + "%" and type = "A"
			and number > 0

/*
** OMNI: If we're setting server logins, dissallow
** when @@servername is null
*/
if @statvalue = 512 and @@servername is NULL
begin
	/*
	** 18686, "Server option 'server logins' cannot be set 
	**	when @@servername is null"
	*/
	exec sp_getmessage 18686, @msg output
	print @msg
	goto clean_all
end
 
/* 
** Check for SSO options:
**
** value       : 2    net password encryption
** value       : 8    rpc security model A
** value       : 16   rpc security model B
** value       : 64   use message confidentiality
** value       : 128  use message integrity
** value       : 256  mutual authentication
** value       : 512  server logins
** value       : 4096 negotiated logins
*/
if (@statvalue in (2, 8, 16, 64, 128, 256, 512, 4096))
begin
        if (proc_role("sso_role") < 1)
                goto clean_all
end


/*
** Check for HA options 
**
** value       : 32   cis hafailover
*/
else if( @statvalue in (32))
begin
        if (proc_role("ha_role") < 1)
                goto clean_all
end

/*
** For any other option check for SA role
** 
** Currently the following are left
**
** value       : 0    timeouts
** value       : 4    readonly
** value       : 1024 external engine auto start
*/
else 
begin
	if (proc_role("sa_role") < 1)
		goto clean_all
end


select @model_a_value = number from master.dbo.spt_values
	where type = "A" and name = "rpc security model A"
select @model_b_value = number from master.dbo.spt_values
	where type = "A" and name = "rpc security model B"
select @model_b1_value = number from master.dbo.spt_values
	where type = "A" and name = "use message confidentiality"
select @model_b2_value = number from master.dbo.spt_values
	where type = "A" and name = "use message integrity"
select @model_b3_value = number from master.dbo.spt_values
	where type = "A" and name = "mutual authentication"

select @srvstatus = srvstatus from master.dbo.sysservers
	where srvid = @srvid 

if ( (@statvalue = 64 or @statvalue = 128 or @statvalue = 256) )
begin
	if ( (@srvstatus & @model_b_value) = 0 )
	begin
		/*
		** <msgnum> confidentiality, integrity, and mutual
		** authentication are valid with rpc security model B only.
		*/
		raiserror 17809
		goto clean_all
	end
end

/*
**  Now update sysservers.
**  The timeouts option is handled a little strangely since the default
**  is timeouts.  Therefore timeouts = true means to clear the bit
**  and timeouts = false means to set the bit.
*/



if lower(@optvalue) in ("true", @true)
begin
	if (@statvalue = 1)
	begin
		update master.dbo.sysservers
			set srvstatus = srvstatus & ~@statvalue
				where srvid = @srvid

		if (@@error != 0) goto clean_all

	end
	else
	begin
		if ( @statvalue = 8 or @statvalue = 16 or @statvalue = 32 )
		begin
			/*
			** confidentiality, integrity, and mutual authentication
			** are reset whenever "rpc security model X" is reset.
			** Also because models A, B, and C are mtutally
			** exclusive, when when one of them is turned on,
			** other two will be turned off.
			*/
			update master.dbo.sysservers
				set srvstatus = srvstatus & ~@model_b1_value
					where srvid = @srvid

			if (@@error != 0) goto clean_all


			update master.dbo.sysservers
				set srvstatus = srvstatus & ~@model_b2_value
					where srvid = @srvid
		
			if (@@error != 0) goto clean_all


			update master.dbo.sysservers
				set srvstatus = srvstatus & ~@model_b3_value
					where srvid = @srvid

			if (@@error != 0) goto clean_all


			update master.dbo.sysservers
				set srvstatus = srvstatus & ~@model_a_value
					where srvid = @srvid

			if (@@error != 0) goto clean_all


			update master.dbo.sysservers
				set srvstatus = srvstatus & ~@model_b_value
					where srvid = @srvid

			if (@@error != 0) goto clean_all

		end
		update master.dbo.sysservers
			set srvstatus = srvstatus | @statvalue
				where srvid = @srvid

		if (@@error != 0) goto clean_all

	end
end

/*
**  We want to turn it off.
*/
else
begin
	if @statvalue = 1
	begin
		update master.dbo.sysservers
			set srvstatus = srvstatus | @statvalue
				where srvid = @srvid

		if (@@error != 0) goto clean_all

	end
	else
	begin
		if ( @statvalue = 8 or @statvalue = 16 or @statvalue = 32 )
		begin
			/* model A is the default */
			update master.dbo.sysservers
				set srvstatus = srvstatus | @model_a_value
				where srvid = @srvid

			if (@@error != 0) goto clean_all

                end

		update master.dbo.sysservers
			set srvstatus = srvstatus & ~@statvalue
				where srvid = @srvid

		if (@@error != 0) goto clean_all


		if (@statvalue = 16)	
		/* 
		** if model B bit is turned off then turn off 
		** b1, b2, and b3 too.
		*/
		begin
			update master.dbo.sysservers
				set srvstatus = srvstatus & ~@model_b1_value
					where srvid = @srvid

			if (@@error != 0) goto clean_all


			update master.dbo.sysservers
				set srvstatus = srvstatus & ~@model_b2_value
					where srvid = @srvid

			if (@@error != 0) goto clean_all


			update master.dbo.sysservers
				set srvstatus = srvstatus & ~@model_b3_value
					where srvid = @srvid

			if (@@error != 0) goto clean_all

		end
	end
end



if (@nHARSTClass = 1)
begin
	if (lower(@optvalue) in ("true", @true))
	begin
		if (@statvalue = 1)
		begin
			update master.dbo.rmt_ha_sysservers
				set srvstatus = srvstatus & ~@statvalue
					where srvid = @srvid
			if (@@error != 0) goto clean_all
		end
		else
		begin
			if ( @statvalue = 8 or @statvalue = 16 or @statvalue = 32 )
			begin
				/*
				** confidentiality, integrity, and mutual authentication
				** are reset whenever "rpc security model X" is reset.
				** Also because models A, B, and C are mtutally
				** exclusive, when when one of them is turned on,
				** other two will be turned off.
				*/
				update master.dbo.rmt_ha_sysservers
				set srvstatus = srvstatus & ~@model_b1_value
					where srvid = @srvid
				if (@@error != 0) goto clean_all

				update master.dbo.rmt_ha_sysservers
				set srvstatus = srvstatus & ~@model_b2_value
					where srvid = @srvid
				if (@@error != 0) goto clean_all

				update master.dbo.rmt_ha_sysservers
				set srvstatus = srvstatus & ~@model_b3_value
					where srvid = @srvid
				if (@@error != 0) goto clean_all

				update master.dbo.rmt_ha_sysservers
				set srvstatus = srvstatus & ~@model_a_value
					where srvid = @srvid
				if (@@error != 0) goto clean_all

				update master.dbo.rmt_ha_sysservers
				set srvstatus = srvstatus & ~@model_b_value
					where srvid = @srvid
				if (@@error != 0) goto clean_all
			end
			update master.dbo.rmt_ha_sysservers
			set srvstatus = srvstatus | @statvalue
				where srvid = @srvid
			if (@@error != 0) goto clean_all
		end
	end

	/*  We want to turn it off. */
	else
		begin
		if (@statvalue = 1)
		begin
			update master.dbo.rmt_ha_sysservers
			set srvstatus = srvstatus | @statvalue
				where srvid = @srvid
			if (@@error != 0) goto clean_all
			
		end
		else
		begin
			if ( @statvalue = 8 or @statvalue = 16 or @statvalue = 32 )
			begin
				/* model A is the default */
				update master.dbo.rmt_ha_sysservers
				set srvstatus = srvstatus | @model_a_value
				where srvid = @srvid
				if (@@error != 0) goto clean_all
	                end
			update master.dbo.rmt_ha_sysservers
			set srvstatus = srvstatus & ~@statvalue
				where srvid = @srvid
			if (@@error != 0) goto clean_all

			if (@statvalue = 16)	
			/* 
			** if model B bit is turned off then turn off 
			** b1, b2, and b3 too.
			*/
			begin
				update master.dbo.rmt_ha_sysservers
				set srvstatus = srvstatus & ~@model_b1_value
					where srvid = @srvid
				if (@@error != 0) goto clean_all

				update master.dbo.rmt_ha_sysservers
				set srvstatus = srvstatus & ~@model_b2_value
					where srvid = @srvid
				if (@@error != 0) goto clean_all

				update master.dbo.rmt_ha_sysservers
				set srvstatus = srvstatus & ~@model_b3_value
					where srvid = @srvid
				if (@@error != 0) goto clean_all
			end
		end
	end

	/*
	** OMNI: If net password encryption, readonly, hafailover, server login or
	** negotiated logins option is specified, update the srvdes
	*/
	if @statvalue in (2,4,32,512,4096)
	begin
		select @str_srvid = convert(char(10), @srvid)
		select @sqlbuf = "dbcc cis ('srvdes', " + @str_srvid + ")"
		exec sp_remotesql "SYB_HACMP", @sqlbuf
	end

	commit tran ha_dynsyn
end
	


/*
** OMNI: If net password encryption, readonly, hafailover, server login or
** negotiated logins option is specified, update the srvdes
*/
if @statvalue in (2,4,32,512,4096)
begin
	/*
	** For SDC, update cluster-wide in-memory SRVDES with data from
	** just-updated SYSSERVERS table. Before dbcc cis, the dbcc
	** command scope needs to be set to cluster.
	*/
	if (@@clustermode = "shared disk cluster")
	begin
		select @scope = NULL
		select @outstr = "dbcc set_scope_in_cluster('scope')"
		if (charindex("instance", @outstr) != 0)
		begin
			/* save the scope to be restored later */
			select @scope = "instance"
			dbcc set_scope_in_cluster('cluster')
		end
	end

	dbcc cis ("srvdes", @srvid)

	/* restore dbcc command scope */
	if (@@clustermode = "shared disk cluster")
	begin
		if (@scope = "instance")
		begin
			dbcc set_scope_in_cluster('instance')
		end
	end
end

return (0)

clean_all:


	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn


return (1)
go
exec sp_procxmode 'sp_serveroption', 'anymode'
go
grant execute on sp_serveroption to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_changedbowner')
begin
	drop procedure sp_changedbowner
end
go
print "Installing sp_changedbowner"
go

/*
** Generated by spgenmsgs.pl on Mon Nov  6 11:22:17 2006 
*/
/*
** raiserror Messages for changedbowner [Total 5]
**
** 17231, "No login with the specified name exists."
** 17361, "Can't change the owner of the master, model, tempdb or sybsystemprocs database."
** 17362, "The proposed new db owner already is a user in the database or owns the database."
** 17363, "The proposed new db owner already is aliased in the database."
** 17368, "Your curwrite label needs to be set correctly before you attempt to change the database owner."

*/
/*
** sp_getmessage Messages for changedbowner [Total 5]
**
** 17364, "The dependent aliases were mapped to the new dbo."
** 17365, "The dependent aliases were dropped."
** 17366, "Database owner changed."
** 17431, "true"
** 19575, "Warning: The stored procedure '%1!' may not execute; check database owner's threshold authorization."
*/
/*
** End spgenmsgs.pl output.
*/
/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/changedbowner */
 
/*
** Messages for "sp_changedbowner"      17360
**
** 17231, "No login with the specified name exists."
** 17361, "Can't change the owner of the master, model, tempdb or sybsystemprocs  database."
** 17362, "The proposed new db owner already is a user in the database or owns the database."
** 17363, "The proposed new db owner already is aliased in the database."
** 17364, "The dependent aliases were mapped to the new dbo."
** 17365, "The dependent aliases were dropped."
** 17366, "Database owner changed."
** 17431, "true"
** 17368, "Your curwrite label needs to be set correctly before you attempt to change the database owner."
** 19857, "Can't change the owner of the master, model, sybsystemprocs, tempdb or local system temporary databases."
*/

create procedure sp_changedbowner --{
@loginame varchar(30),         /* login to become dbo */
@map      varchar(10) = NULL   /* True to map aliases, else drop  */
as

declare @suid		int
declare @oldsuid	int
declare @msg		varchar(1024)
declare @true		varchar(10)
declare @dbname		varchar(255)
declare @HA_CERTIFIED	tinyint   /* Is the SP HA certified ? */
declare @retstat	int

declare @currauth	varbinary(255)
declare @proc_name	varchar(255)
declare @count		int
declare @coord_override	int

select @HA_CERTIFIED = 0

/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int
declare @hasproxydb     int

select @nHARSTClass = ha_getrestrictionclass("sp_changedbowner")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_changedbowner', @HA_CERTIFIED
if (@retstat != 0)
	return (1)

if @@trancount = 0
begin
	set chained off
end

set transaction isolation level 1

/* check if user has sa role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/

if (proc_role("sa_role") = 0)
	return (1)

/*
**  Can't change the owner of the master, model, tempdb or sybsystemprocs  database.
*/
if db_name() in ( "master", "tempdb", "model", "sybsystemprocs" ) 
begin
	if @@clustermode = "shared disk cluster"
	begin
		/*
		** 19857, "Can't change the owner of the master, model, 
		** sybsystemprocs, tempdb or local system temporary 
		** databases."
		*/
		raiserror 19857 
	end

	else
	begin
		/*
		** 17361, "Can't change the owner of the master, model, 
		** tempdb or sybsystemprocs  database."
		*/
		raiserror 17361
	end

	return(1)
end

/*
** In SDC, can't change the owner of the local system tempdb either.
*/
if @@clustermode = "shared disk cluster"  
begin
	declare @localsystempdbbit int
	select @localsystempdbbit = number
		from master.dbo.spt_values
		where type = "D3" and name = "local system temp db"

   	if exists (select 1 from master.dbo.sysdatabases 
			where dbid = db_id() and 
		(status3 & @localsystempdbbit) = @localsystempdbbit)
	begin
		/*
		** 19857, "Can't change the owner of the master, model, 
		** sybsystemprocs, tempdb or local system temporary 
		** databases."
		*/
		raiserror 19857 
		return(1)
	end
end

/*
**  Make sure that @loginame exists and has a login.
*/
select @suid = suid
	from master.dbo.syslogins
		where name = @loginame

if @suid is NULL
begin
	/*
	** 17231, "No login with the specified name exists."
	*/
	raiserror 17231
	return(1)
end

/*
**  Make sure that @loginame isn't already a user or alias in the database.
*/
if exists (select *
		from sysusers
			where suid = @suid)
begin
	/*
	** 17362, "The proposed new db owner already is a user in the database or owns the database."
	*/
	raiserror 17362
	return(1)
end
if exists (select *
		from sysalternates
			where suid = @suid)
begin
	/*
	** 17363, "The proposed new db owner already is aliased in the database."
	*/
	raiserror 17363
	return(1)
end

/* 
** find old (current) dbo's suid
*/
select @oldsuid = suid
	from sysusers
		where uid = 1

/*
** Allow IMDB/RDDB to be the coordinator of a multi-db transaction.
** We need this override because we are about to update current database
** and the master database in the same transaction.
*/
select @coord_override = 0
if exists (select * from master.dbo.sysdatabases
			where dbid = db_id()
			and durability != 1)
begin
	/* 
	** If the switch is not turned ON in session or serverwide, 
	** turn it ON and remember that we turned it ON here
	*/
	if (switchprop("allow_nondurable_db_as_coorddb") = 0)
	begin
		select @coord_override = 1
		set switch on allow_nondurable_db_as_coorddb 
			with override, no_info
	end
end

begin transaction

/*
**  Now change the suid of the owner of the database to the suid of @loginame.
*/
update sysusers
	set suid = @suid
		where uid = 1

/*
** if the user requested that aliases be mapped to new dbo, do that.
*/
/* 17431, "true" */
exec sp_getmessage 17431, @true out
if lower(@map) in ("true", @true)
begin

	if exists (select *
			from sysalternates
				where altsuid = @oldsuid)
	begin
		update sysalternates
			set altsuid = @suid
				where altsuid = @oldsuid

		/*
		** 17364, "The dependent aliases were mapped to the new dbo."
		*/
		exec sp_getmessage 17364, @msg output
		print @msg
	end
end
/* else drop the aliases to the old dbo */
else
begin

	if exists (select *
			from sysalternates
				where altsuid = @oldsuid)
	begin
		delete from sysalternates
			where altsuid = @oldsuid

		/*
		** 17365, "The dependent aliases were dropped."
		*/
		exec sp_getmessage 17365, @msg output
		print @msg
	end
end

/*
**  Reflect the new owner of the database in master.dbo.sysdatabases.
*/
update master.dbo.sysdatabases
	set suid = @suid
		where dbid = db_id()

/* Update owner of the associated thresholds in systhreshods table */
begin
         if exists (select * 
                         from systhresholds
                              where suid = @oldsuid)
         begin 
                 update systhresholds
                       set suid = @suid
                           where suid = @oldsuid
         end
end
	
commit transaction

/* Disable the override if we enabled it earlier */
if (@coord_override = 1)
begin
	select @coord_override = 0
	set switch off allow_nondurable_db_as_coorddb with no_info
end

/* 
** To check if the new owner has all the roles the "currauth" 
** specifies. If he does not have all the roles required, 
** this change may cause the stored procedure UN-EXECUTABLE 
** later when the threshold is crossed. So we raise a 
** warning error.
*/
begin
         declare auth_procname cursor
             for select currauth, proc_name from systhresholds
                  where suid = @suid
             for read only
         
         open auth_procname
         
         fetch auth_procname into @currauth, @proc_name
         while @@sqlstatus <> 2
		begin
			select @count = count(*)
			from master..syssrvroles a,
                           systhresholds b,
                           master.dbo.spt_values c
			where c.type = "P"
                           and c.number = a.srid
                           and c.low <= datalength(b.currauth)
                           and convert(tinyint, 
				substring(currauth, c.low, 1)) 
				& c.high != 0
                           and a.srid not in 
                                  ( select srid
                                    from master..sysloginroles
                                    where suid = @suid)

			/*
			** If the new dbo does not have all the 
			** roles specified in the current 
			** authorization bitmask "currauth",
			** we print an warning message 
			*/

			if @count > 0
			begin		
				/* 
				** 19575, "Warning: The stored 
				** procedure '%1!' may not execute; 
				** check database owner's threshold 
				** authorization."
				*/
				exec sp_getmessage 19575, @msg output
				print @msg, @proc_name
			end
			fetch  auth_procname into @currauth, @proc_name
		end
	close auth_procname
	deallocate cursor auth_procname
end

/*
** Update the dbinfo and dbtable uid fields for this database.
*/
select @dbname = db_name()
dbcc dbrepair(@dbname, "updowner")

/*
** 17366, "Database owner changed."
*/
exec sp_getmessage 17366, @msg output
print @msg

return (0)

--} /* End of create stored proc. */
go
exec sp_procxmode 'sp_changedbowner', 'anymode'
go
grant execute on sp_changedbowner to public
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_renamedb')
begin
	drop procedure sp_renamedb
end
go
print "Installing sp_renamedb"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/renamedb */

/*
** Messages for "sp_renamedb"           17790
**
** 17260, "Can't run %1! from within a transaction." 
** 17590, "The specified database does not exist."
** 17240, "'%1!' is not a valid name."
** 17791, "A database with the new name already exists."
** 17792, "The databases master, model, tempdb, sybsecurity, sybsystemprocs and mounted_sybsystemprocs cannot be renamed."
** 17793, "System Administrator (SA) must set database '%1!' to single-user mode with sp_dboption before using '%2!'."
** 17794, "Database is renamed and in single-user mode."
** 17795, "System Administrator (SA) must reset it to multi-user mode with sp_dboption."
** 17902, "You cannot run stored procedure '%1!' from a low durability database."
** 18850, "HA Error: Database '%1!' is a system proxy database. You must execute sp_renamedb on the primary server first."
** 18851, "HA Error: You must be in the master database in order to run '%1!' against a system proxy database."
** 18843, "Please check the System Administration Guide to determine how to %1! the corresponding proxy or real database on the companion server '%2!'."
*/



/*
** IMPORTANT NOTE:
** This stored procedure uses the built-in function db_id() in the
** where clause of a select query. If you intend to change this query
** or use the object_id() or db_id() builtin in this procedure, please read the
** READ.ME file in the $DBMS/generic/sproc directory to ensure that the rules
** pertaining to object-id's and db-id's outlined there, are followed.
*/

create procedure sp_renamedb
@dbname sysname(30),			/* old (current) db name */
@newname sysname(30)			/* new name we want to call it */
as

declare @msg varchar(1024)
declare @bitdesc varchar(30)		/* bit description for the db */
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int
declare @maxobjlen int
declare @rollback int

select @HA_CERTIFIED = 0


/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int
declare @hasproxydb     int
declare @isproxydb	int
declare @dbstatus	int

select @nHARSTClass = ha_getrestrictionclass("sp_renamedb")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_renamedb', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_renamedb"
	return (1)
end
else
begin
	set chained off
end

set transaction isolation level 1

/* check if user has sa role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/

if (proc_role("sa_role") = 0)
	return (1)

/*
**  Make sure the database exists.
*/
if not exists (select *
		from master.dbo.sysdatabases
			where name = @dbname)
begin
	/*
	** 17590, "The specified database does not exist."
	*/
	raiserror 17590
	return (1)
end

/*
**  Make sure that the @newname db doesn't already exist.
*/
if exists (select *
		from master.dbo.sysdatabases
			where name = @newname)
begin
	/*
	** 17791, "A database with the new name already exists."
	*/
	raiserror 17791
	return (1)
end

/*
**  Check to see that the @newname is valid.
*/
select @maxobjlen = length from master.dbo.syscolumns 
	where id = object_id("master.dbo.sysdatabases")
	and name = 'name'

if valid_name(@newname,@maxobjlen) = 0
begin
	/*
	** 17240, "'%1!' is not a valid name."
	*/
	raiserror 17240, @newname
	return (1)
end

/*
**  Don't allow the names of master, tempdb, and model to be changed.
*/
if @dbname in ("master", "model", "tempdb", "sybsecurity", "sybsystemprocs", "mounted_sybsystemprocs")
begin
	/*
	** 17792, "The databases master, model, tempdb, sybsecurity, 
	** sybsystemprocs and mounted_sybsystemprocs cannot be renamed."
	*/
	raiserror 17792
	return (1)
end


/* 
** Check single user bit (4096) 
** Database must be in single user mode to necessitate the rid update in the
** database's DBTABLE
*/ 
select @bitdesc = null 
select @bitdesc = v.name
        from master.dbo.spt_values v, master.dbo.sysdatabases d 
                where d.dbid = db_id(@dbname) 
                        and v.type = "D" 
                        and d.status & v.number = 4096 
if @bitdesc is null 
begin 
	/*
	** 17793, "System Administrator (SA) must set database '%1!' to single-user mode with sp_dboption before using '%2!'."
	*/
	raiserror 17793, @dbname, "sp_renamedb"
        return(1)  
end  


		
/* Initialize variables */
select @dbstatus = status3 
  from master.dbo.sysdatabases
  where name = @dbname

select @isproxydb = @dbstatus & 2
select @hasproxydb = @dbstatus & 4

/*
**  Make sure that the @newname db doesn't already exist on the companion.
*/
if (@nHARSTClass = 3)
begin
	/*
	** When the HA cluster is configured with no proxydb option,
	** it is our job to verify the name unique.
	*/
	if (@@crthaproxy = 0)
	begin
		if exists (select 1
			from master.dbo.rmt_ha_sysdatabases
			where name = @newname)
		begin
			/*
			** 18773, "HA_LOG: HA consistency check failure 
			** in '%1!' on the companion server '%2!'"
			*/
			raiserror 18773, "sp_renamedb", @@hacmpservername

			/*
			** 17791, "A database with the new name already exists."
			*/
			raiserror 17791
              
			return (1)
		end
	end
	else /* @@crthaproxy = 1 */
	begin
		/*
		** If a system proxy database is being renamed, we must be 
		** running in the master database and the database on the 
		** primary server must have already been renamed.
		*/
		if (@isproxydb != 0)
		begin
			if db_name() != "master"
			begin
				/*
				** 18851, "HA Error: You must be in the 
				** master database in order to run '%1!' 
				** against a system proxy database."
				*/
				raiserror 18851, "sp_renamedb"
				return(1)
			end

			if not exists (select 1 
					from master.dbo.rmt_ha_sysdatabases 
					where name = @newname)
			begin
				/*
				** 18850, "HA Error: Database '%1!' is a 
				** system proxy database. You must execute 
				** sp_renamedb on the primary server first."
				*/
				raiserror 18850, @dbname
				return(1)
			end
		end
	end
end


/* 
** This stored procedure can not be executed from a low durablity database
** as the changes made by follwoing 'dbcc chgdbname' can not be undone
** as the execution will not come back to stored procedure when error 
** 3952 happens. So we check if we are in a low durability database before
** starting execution of the stored procedure.
*/
if db_attr(db_name(), "durability") != 'full'
begin
	raiserror 17902, "sp_renamedb"
	return (1)
end

/*
**  Update the dbinfo in the sysindexes row for syslogs of the database
**  whose name is being changed. Also the dbtable structure for the db
**  in question is updated with the new name.
**
**  NOTE: the following dbcc command relies on the above commands executing.
**	  Using this command outside of this procedure can cause a host of
**  	  perfidious problems.
*/
dbcc chgdbname (@dbname, @newname)

if @@error = 0
begin
	select @rollback = 1
	begin tran rename_db
	update master.dbo.syslogins
		set dbname = @newname 
			where dbname = @dbname
	if @@error = 0
	begin
		update master.dbo.sysdatabases
			set name = @newname
				where name = @dbname
		if @@error = 0
		begin
			commit tran rename_db
			set @rollback = @@error
		end
	end
	
	if @rollback != 0
	begin
		rollback tran rename_db
		dbcc chgdbname (@newname, @dbname)
		return(1)
	end
end
else
	return (1)

/*
** 17794, "Database is renamed and in single-user mode."
*/
exec sp_getmessage 17794, @msg output
print @msg

/*
** 17795, "System Administrator (SA) must reset it to multi-user mode with sp_dboption."
*/
exec sp_getmessage 17795, @msg output
print @msg


if (@nHARSTClass = 3)
begin
	/*
	** If this is a system proxy database, update the default location
	** name, and remap the proxy tables. If any of these operations
	** fail, the database is still renamed.
	*/
	if (@isproxydb != 0)
	begin
		update master.dbo.sysdatabases
		  set def_remote_loc = @@hacmpservername + "." + @newname + ".."

		  where name = @newname

		alter database @newname for proxy_update
	end

	if (@hasproxydb != 0)
	begin
		/*
		** 18843, Please check the System Administration Guide to
		** determine how to %1! the corresponding proxy or real
		** database on the companion server '%2!'.
		*/
		exec sp_getmessage 18843, @msg output
		print @msg, "rename", @@hacmpservername
	end
end


return (0)
go
exec sp_procxmode 'sp_renamedb', 'anymode'
go
grant execute on sp_renamedb to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_addtype')
begin
	drop procedure sp_addtype
end
go
print "Installing sp_addtype"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */

/*
** Messages for "sp_addtype"            17300
**
** 17300, "Usage: sp_addtype name, 'datatype' [,null | nonull | identity]"
** 17301, "'%1!' is not a valid type name."
** 17302, "A type with the specified name already exists."
** 17303, "Physical datatype does not exist."
** 17304, "User-defined datatypes based on the 'timestamp' datatype are not allowed."
** 17305, "Physical datatype does not allow nulls."
** 17306, "Physical type is fixed length. You cannot specify the length."
** 17307, "You must specify a length with this physical type.
** 17308, "Illegal length specified -- must be between 1 and %1!."
** 17309, "Type added."
** 17751, "Illegal precision specified -- must be between 1 and 38."
** 17752, "Illegal scale specified -- must be less than precision and positive."
** 17754, "Illegal precision specified -- must be between 1 and 48."

** 17756, "The execution of the stored procedure '%1!' in database
** 	   '%2!' was aborted because there was an error in writing the
** 	   replication log record."
** 18302, "User '%1!' is not a valid user in the '%2!' database."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18786, "A type with name '%1!' or id '%2!' already exists."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	After that, you need to add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_addtype
@typename varchar(255),		/* name of user-defined type */
@phystype varchar(80),		/* physical system type of user-defined type */
@nulltype varchar(8) = "1"	/* default is database 'allow null' default */
as

declare @len int		/* length of user type */
declare @type tinyint		/* typeid of physical type */
declare @tlen int		/* length of physical type */
declare @typeid smallint	/* user typeid of physical type */
declare @var bit		/* is physical type variable length? */
declare @nonull bit		/* default is to allow NO NULLs */
declare @nullegal bit		/* does physical type allow NULLs? */
declare @msg varchar(1024)
declare @prec int		/* precision of the datatype */
declare @scale int		/* scale of the datatype */
declare @tprec tinyint		/* precision of the datatype read from systypes */
declare @tscale tinyint		/* scale of the datatype read from systypes */
declare @u_identity tinyint	/* does user type have identity property? */
declare @hierarchy tinyint	/* hierarchy level of the datatype */
declare @index int		/* index of blank char in the string of datatype*/
declare @rest varchar(80)	/* string that holds the temporay portion of the datatype.*/
declare @nulldefault int	/* 'allow null' database default */
declare @nationalchar int	/* national character type is specified */
declare @logexec int		/* For the logexec call */
declare @saved_phystype varchar(80) /* Saved @phystype parameter. This will be
				    ** restored before logging for replication.
				    ** This is necessary because @phystype is
				    ** modified.
				    */
declare @dbname varchar(255)
declare @uid    int
declare @insert_typeid smallint
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @MAXSYSTYPEID int	/* maximum user type id for a system type */
declare @retstat int
declare @maxlen		int


if @@trancount = 0
begin
	set chained off
end

select @HA_CERTIFIED = 0
select @MAXSYSTYPEID = 100      /* maximum user type id for a system type */



declare @nHARSTClass    int
declare @sqlbuf varchar(50)
declare @rtn_code	int
declare @typeid_hacmp smallint
declare @insert_typeid_hacmp smallint
declare @username	varchar(255)
declare @uid_hacmp	smallint

select @nHARSTClass = ha_getrestrictionclass("sp_addtype")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 3) 
begin
	if (db_id() != 1)
		/* We only synch the type information for 'master' DB */
		select @nHARSTClass = 0
	else
		select @nHARSTClass = 1
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_addtype', @HA_CERTIFIED
if (@retstat != 0)
        return (1)


set transaction isolation level 1
/*
**  Does the user type allow NULLs?  Now, the default is to 
**  use the 'allow null' option setting for the current database.
**  This is the same default the create table statement uses.
*/
if @nulltype = "1"
begin
	/*
	** Get database 'allow null default. @nulldefault = 0
	** means 'not null allowed' is database default.
	**
	** 17069, "allow nulls by default"
	**
	** Make sure not to get the internationalized message
	** by "us_english" parameter, even if client is using
	** an alternative language. This is because spt_values
	** has an us_english message only, even if an alternative
	** language is installed.
	*/

	exec sp_getmessage 17069, @msg output, "us_english"

	select @nulldefault = (a.number & b.status)
	from master.dbo.spt_values a, master.dbo.sysdatabases b
	where a.name = @msg and b.name = db_name()
	if (@nulldefault = 0)
		select @nonull = 1
	else
		select @nonull = 0
	select @u_identity = 0
end
else if lower(@nulltype) = "null" or @nulltype is null
begin
	select @nonull = 0
	select @u_identity = 0
end
else if lower(@nulltype) = "identity"
begin
	select @nonull = 1
	select @u_identity = 1
end
else if lower(@nulltype) in ("not null" , "nonull")
begin
	select @nonull = 1
	select @u_identity = 0
end
else
begin
	/*
	** 17300, "Usage: sp_addtype name, 'datatype' [,null | nonull | identity]"
	*/
	raiserror 17300
	return (1)
end

/*
**  Check to see that the @typename is valid.
*/
select @maxlen = length from syscolumns
	where id = object_id("systypes")
		and name = "name"

if valid_name(@typename,@maxlen) = 0
begin
	/*
	** 17301, "'%1!' is not a valid type name."
	*/
	raiserror 17301, @typename
	return (1)
end

/*
** Check to see if the type already exists. In addition to the 
** types in systypes we need to also check for their capitalized 
** version (for system types) and alternative names for system types
** such as integer for int.
*/
if exists (select *
		from systypes
		where name = @typename or
           	(name = lower(@typename) and usertype < @MAXSYSTYPEID) or
                (lower (@typename) in ('integer', 'character')))

begin
	/*
	** 17302, "A type with the specified name already exists."
	*/
	raiserror 17302
	return (1)
end

/* Save the original value of @phystype. We'll need it if we have
** to log this invocation for replication.
*/
select @saved_phystype = @phystype

/* Make physical typename all lower case to ensure case insensitivity. */
select @phystype = lower(@phystype)

/* initialize the length to be NULL first. */
select @len = NULL
/*
** If precision and scale were given with the type extract them
*/
if @phystype like "_%(_%,_%)"
begin
	select @prec = convert(int, substring(@phystype,
		charindex("(",@phystype) + 1,
		charindex(",",@phystype) - 1 - charindex("(",@phystype)))

	select @scale = convert(int, substring(@phystype,
		charindex(",",@phystype) + 1,
		charindex(")",@phystype) - 1 - charindex(",",@phystype)))
	/*
	** Extract the physical type name 
	*/
	select @phystype = substring(@phystype, 1,
		   charindex("(", @phystype) - 1)
end
else

/*
**  If a length was given with the user datatype, extract it.
**  This could also be the precision, at this time assume it's the length
**  we'll decide later whether it's the length or precision.
**  If the length is not specified, @len will be assigned to NULL by
**  the function convert(). Note that like "_%(%)" can match the string
**  of phystype(length) or phystype(), such as binary(8) or binary().
*/
if @phystype like "_%(%)"
begin
	select @len = convert(int, substring(@phystype,
		charindex("(",@phystype) + 1,
		charindex(")",@phystype) - 1 - charindex("(",@phystype)))

	/*
	** Extract the physical type name 
	*/
	select @phystype = substring(@phystype, 1,
		   charindex("(", @phystype) - 1)
end
else 

/*
** If the type is an unsigned int then we only allow "unsigned int"  
** not the systypes name uint.
*/
if (@phystype in ("uint", "usmallint", "ubigint", "uintn"))
begin
		/*
		** 17303, "Physical datatype does not exist."
		*/
			raiserror 17303
			return (1)
end

/*
** Now, squeezes all consective space characters in the datatype string 
** into one single space character. By doing this, sp_addtype can recognize
** datatype, such as "   national      char    varying".
*/
select @phystype = ltrim(rtrim(@phystype))
select @rest = @phystype
select @phystype = NULL
select @index = charindex(' ', @rest) 
while (@index != 0)
begin
	select @phystype = @phystype + substring(@rest, 1, @index -1) + ' '
	select @rest = ltrim(stuff(@rest, 1, @index, ''))
	select @index = charindex(' ', @rest)
end
select @phystype = rtrim(@phystype + @rest)

/* 
** Assgin value to @nationalchar before do the datatype mapping,
** this value will be used when calculate the actual storage length.
*/

if (@phystype in ("nchar", "nvarchar", "national char", "national character",
	"nchar varying", "national char varying", "national character varying"))
begin
	select @nationalchar = 1
end
else
begin
	select @nationalchar = 0
end

/*
**  Do the following datatypes mapping now.
**  "character"--> "char"; "nchar"--> "char"; 
**  "[national] char[acter] varying"--> "varchar"; "nchar varying"-->"varchar";
**  "dec" ---> "decimal";  "integer"---> "int"; "double precision" --> "float";
**  Map the default length of datatype "char" ,"varchar", "binary", "varbinary"
**  and their various synonyms to 1.
*/
if (@phystype in ("char", "character", "nchar", "national char", 
	"national character"))
begin
	select @phystype = "char"
	/*
	** If len is not specified, supply the default length to be 1.
	*/
	if (@len is NULL) select @len = 1	
end
else
if (@phystype in ("varchar", "nvarchar", "nchar varying", "char varying", 
   "character varying", "national char varying", "national character varying"))
begin
	select @phystype = "varchar"
	/*
	** If len is not specified, supply the default length to be 1.
	*/
	if (@len is NULL) select @len = 1	
end
else
if (@phystype in ("univarchar", "unichar varying", 
   "unicode character varying", "unicode char varying"))
begin
	select @phystype = "univarchar"
	/*
	** If len is not specified, supply the default length to be 1.
	*/
	if (@len is NULL) select @len = 1	
end
else
if (@phystype in ("unichar", "unicode char", "unicode character"))
begin
	select @phystype = "unichar"
	/*
	** If len is not specified, supply the default length to be 1.
	*/
	if (@len is NULL) select @len = 1	
end
else
if ((@phystype in ("binary", "varbinary")) and (@len is NULL))
	/*
	** If len is not specified, supply the default length to be 1.
	*/
	select @len = 1
else
if (@phystype = "unsigned integer") select @phystype = "uint"
else
if (@phystype = "unsigned int") select @phystype = "uint"
else
if (@phystype = "unsigned smallint") select @phystype = "usmallint"
else
if (@phystype = "unsigned bigint") select @phystype = "ubigint"
else
if (@phystype = "integer") select @phystype = "int"
else
if (@phystype = "double precision") select @phystype = "float"
else
if (@phystype = "dec") select @phystype = "decimal"
else
	/*
	** If len for float datatype is specified, then the range must
	** be between 1 to 48. If len specified is <= 15, map the type
	** to real, otherwise map the type to float.
	*/
if (@phystype = "float") and (@len is not NULL)
begin
	if (@len  < 1 or @len > 48)
	begin
		raiserror 17754
		return (1)
	end
	else
	begin
		if (@len < = 15) select @phystype = "real" 		
		select @len = NULL
	end
end

/*
**  Make sure that the physical type exists and get its characteristics.
**  DataServer physical types have a usertype < 100 and are owned by the
**  dbo (userid = 1).
**  Datatypes datetimn, decimaln, floatn, intn, moneyn, numericn, daten
**  bigdatetimen, bigtimen, and timen are not supported to users.
**  Those datatypes must be invisible to users.
*/
select @type = type, @tlen = length, @typeid = usertype,
	@var = variable, @nullegal = allownulls, @tprec = prec,
	@tscale = scale, @hierarchy = hierarchy
from systypes
	where usertype < 100 and name = @phystype and uid = 1
	  and @phystype not in ('datetimn', 'decimaln', 'floatn', 'timen',
				'intn', 'moneyn', 'numericn', 'daten',
				'bigdatetimen', 'bigtimen')

if @type is NULL
begin
	/*
	** 17303, "Physical datatype does not exist."
	*/
	raiserror 17303
	return (1)
end

/*
**  Disallow user-defined datatypes on timestamps.  This is done because
**  a timestamp is not a basic type but is really a binary.  There is,
**  therefore, no way to tell if a user-defined datatype is mapped to
**  a binary or a timestamp.  Timestamps can't have rules or defaults.
*/
if @phystype = "timestamp"
begin
	/*
	** 17304, "User-defined datatypes based on the 'timestamp' datatype are not allowed."
	*/
	raiserror 17304
	return (1)
end

/*
**  Check if the NULL status of the user type is consistent with the NULL status
**  of the physical type.  Here are the possible cases.
**
**		   physical type
**		  NULLs	  NONULLs
**	        -----------------
** user	NULLs	|  ok	|  no
** type NONULLs	|  ok	|  ok
*/
if @nonull = 0 and @nullegal = 0
begin
	/*
	** 17305, "Physical datatype does not allow nulls."
	*/
	raiserror 17305
	return (1)
end

/*
**  We'll use the variable @nullegal when we update the systypes table
**  so we need to set it to reflect if NULLs are allowed (@nonull = 0)
**  or NO NULLs are allowed (@nonull = 1).
*/
if @nonull = 0
begin
	select @nullegal = 1
end
else
begin
	select @nullegal = 0
end

/* Decide about precision, scale, length 
** First check fro NUMERIC, DECIMAL
*/
if (@typeid = 26) or (@typeid = 10) 
begin
	/* Type is NUMERIC or DECIMAL */
	
	if @len > 0
	begin
		/* Length is really the precision 
		** Since no scale is specified then scale
		** is minimum(Default, precision). Default = 4
		*/
		select @prec = @len
		select @scale = 0

	end
	else
	begin
		if (@prec is NULL)
		begin
			select @prec = 18
			select @scale = 0
		end
	end

	

	if (@prec > 38) or (@prec < 1)
	begin
		/*
		** 17751, "Illegal precision specified -- must be between 1 and 38."
		*/
		raiserror 17751
		return (1)
	end

	if (@scale > @prec) or (@scale < 0)
	begin
		/*
		** 17752, "Illegal scale specified -- must be less than precision 
		** 	   and positive."
		*/
		raiserror 17752
		return (1)
	end
	
	/* Compute length from precision */
	if (@prec <= 2)	
		select @len = 2
	
	if (@prec > 2) and (@prec <= 4)
		select @len = 3

	if (@prec > 4) and (@prec <= 7)
		select @len = 4

	if (@prec > 7) and (@prec <= 9)
		select @len = 5

	if (@prec > 9) and (@prec <= 12)
		select @len = 6

	if (@prec > 12) and (@prec <= 14)
		select @len = 7

	if (@prec > 14) and (@prec <= 16)
		select @len = 8

	if (@prec > 16) and (@prec <= 19)
		select @len = 9

	if (@prec > 19) and (@prec <= 21)
		select @len = 10

	if (@prec > 21) and (@prec <= 24)
		select @len = 11

	if (@prec > 24) and (@prec <= 26)
		select @len = 12

	if (@prec > 26) and (@prec <= 28)
		select @len = 13

	if (@prec > 28) and (@prec <= 31)
		select @len = 14

	if (@prec > 31) and (@prec <= 33)
		select @len = 15

	if (@prec > 33) and (@prec <= 36)
		select @len = 16

	if (@prec > 36) and (@prec <= 38)
		select @len = 17
end
else
begin
/*
**  Typeids 1 (char), 2 (varchar), 3 (binary), 4 (varbinary) 
**  24 (nchar), 25 (nvarchar), 34 (unichar), and 35 (univarchar)
**  only ones which allow a length to be specified.
*/
if @typeid > 4 and @typeid not in (24, 25, 34, 35) 
begin
	/*
	**  We can't use a length and we got one.
	*/
	if @len > 0
	begin
		/*
		** 17306, "Physical type is fixed length. You cannot specify the length."
		*/
		raiserror 17306
	   	return (1)
	end

	/*
	**  Use the fixed length of the physical type.
	*/
	select @len = @tlen
end
else
begin
	/*
	**  We need a length and we didn't get one.
	*/
	if @len is NULL
	begin
		/*
		** 17307, "You must specify a length with this physical type. 
		*/
		raiserror 17307
		return (1)
	end

	/*
	** If "nchar" or "nvarchar" is specified, caluculate the real length
	*/

	if @nationalchar = 1
		select @len = @len * @@ncharsize

	/*
	** If "unichar" or "univarchar", perform additinal checks
	*/
	if (@phystype in ("unichar", "univarchar"))
	begin
		select @len = @len * @@unicharsize

		if (@len <= 0 or @len > @@maxpagesize)
		begin
			/*
			** 17308, "Illegal length specified -- must be between 1 and %1!."
			*/
			select @len = @@maxpagesize / @@unicharsize
			raiserror 17308, @len
			return (1)
		end
	end
	else if @len <= 0 or @len > @@maxpagesize
	begin
		/*
		** 17308, "Illegal length specified -- must be between 1 and %1!."
		*/
		raiserror 17308, @@maxpagesize
		return (1)
	end

end
end

/* 
** Check to make sure only numeric(x,0), integer, smallint and tinyint
** types have identity property.
*/
if @u_identity = 1
begin
	if (@phystype = "numeric" and @scale != 0) or
	   (@phystype not in ("int", "smallint", "tinyint", 
		"bigint", "ubigint", "uint", "usmallint", "numeric"))
	begin
		/*
		** 17755, "User types with the identity property must be integer,
		**         smallint, tinyint or numeric with a scale of 0."
		*/
		raiserror 17755
		return(1)
	end
end


/*
**  Finally, get the maximum existing user type so we use it + 1 for this
**  new type.
*/
/*  Attention:
**	Please change the corresponding HA section when type ID generating
**	logic is changed here.
*/
select @typeid = max(usertype)
	from systypes

/*
**  There are no user defined types yet so use the first number (101).
*/
if @typeid < 100
	select @typeid = 100
else if (@typeid = 32767)
begin
	print "All usertype ids have been used up"
	return (1)
end

select @insert_typeid = @typeid + 1

select @uid = user_id()



/* 
** This transaction also writes a log record for replicating the
** invocation of this procedure. If logexec() fails, the transaction	
** is aborted.
**
** IMPORTANT: The name rs_logexec is significant and is used by
** Replication Server.
*/
begin transaction rs_logexec


if (@nHARSTClass = 1)
begin
	exec @rtn_code = sp_halockclustertables "sp_addtype"
	if (@rtn_code != 0)
		goto clean_all

	/*
	**  HA consistency checking
	*/
	if exists (select 1 from master.dbo.rmt_ha_systypes
		where name = @typename)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		raiserror 18773, "sp_addtype", @@hacmpservername

		/* 17302, "A type with the specified name already exists." */
                exec sp_getmessage 17302, @msg output
                print @msg
		
		goto clean_all
	end

	/*
	** Generate type id if @insert_typeid is not good for the companion 
	*/
	select @insert_typeid_hacmp = @insert_typeid
	if exists (select 1 from master.dbo.rmt_ha_systypes
			where usertype = @insert_typeid_hacmp)
	begin
		select @typeid_hacmp = max(usertype)
		  from master.dbo.rmt_ha_systypes
		if (@typeid_hacmp < 100)
			select @typeid_hacmp = 100
		else if (@typeid_hacmp = 32767)
		begin
			print "All usertype ids have been used up"
			goto clean_all
		end
		select @insert_typeid_hacmp = @typeid_hacmp + 1
	end

	/*
	** Verify that the current user is a valid user on the companion
	*/
	select @username = user_name()
	select @uid_hacmp = uid from master.dbo.rmt_ha_sysusers
		where name = @username
	if (@uid_hacmp is null)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		raiserror 18773, "sp_addtype", @@hacmpservername

                /* 
		** 18302, "User '%1!' is not a valid user in the '%2!' 
		** database."
		*/
		exec sp_getmessage 18302, @msg output
		print @msg, @username, "master"

		goto clean_all
	end
end


insert systypes (uid, variable, type, length, tdefault,
	domain, name, usertype, allownulls, prec, scale, ident,
	hierarchy, accessrule)
select @uid, @var, @type, @len, 0, 0, @typename, @insert_typeid, @nullegal,
@prec, @scale, @u_identity, @hierarchy, 0


		if (@@error != 0)
		begin
			rollback transaction rs_logexec
			return (1)
		end

		if (@nHARSTClass = 1)
		begin
			insert master.dbo.rmt_ha_systypes (uid, variable, 
				type, length, tdefault, domain, name, 
				usertype, allownulls, prec, scale, 
				ident, hierarchy, accessrule)
			    select @uid_hacmp, @var, @type, @len, 0, 0, 
				@typename, @insert_typeid_hacmp, @nullegal, 
				@prec, @scale, @u_identity, @hierarchy, 0
	
			if (@@error != 0)
			begin
				rollback transaction rs_logexec
				return (1)
			end
		end


/*
** The phystype parameter was changed so restore it's original value and
** write the log record to replicate this invocation.
*/
select @phystype = @saved_phystype

if (logexec() != 1)
begin
	/*
	** 17756, "The execution of the stored procedure '%1!' in
	** 	   database '%2!' was aborted because there was an
	** 	   error in writing the replication log record."
	*/
	select @dbname = db_name()
	raiserror 17756, "sp_addtype", @dbname
	
	rollback transaction rs_logexec
	return(1)
end


if (@nHARSTClass = 1)
begin
	select @sqlbuf = "declare @dummy int select @dummy = logexec()"
	exec sp_remotesql "SYB_HACMP", @sqlbuf
end


commit transaction rs_logexec

/*
** 17309, "Type added."
*/
exec sp_getmessage 17309, @msg output
print @msg

return (0)

clean_all:
	rollback transaction rs_logexec
	return (1)

go
exec sp_procxmode 'sp_addtype', 'anymode'
go
grant execute on sp_addtype to public
go
exec sp_procxmode 'sp_addtype', 'rep_current'
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_droptype')
begin
	drop procedure sp_droptype
end
go
print "Installing sp_droptype"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */
/*	4.8	1.1	06/14/90	sproc/src/defaultlanguage */

/*
** Messages for "sp_droptype"           17540
**
** 17540, "The type doesn't exist or you don't own it."
** 17541, "Type is being used. You cannot drop it."
** 17542, "Type has been dropped."
** 17704, "Curread label needs to dominate the database hurdle."
** 17756, "The execution of the stored procedure '%1!' in database
**         '%2!' was aborted because there was an error in writing the
**         replication log record."
** 17844, "You do not own a user datatype of that name."
** 18076, "Could not set curwrite to object level. Set your maxwrite label correctly."
** 18302, "User '%1!' is not a valid user in the '%2!' database."
** 18331, "Drop failed.  Your curwrite label must match the security label of the type.  Check systypes."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%
2!'"
** 18787, "The type with name '%1!' does not exists."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	After that, you need to add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_droptype
@typename varchar(255)			/* the user type to drop */
as

declare @typeid smallint		/* the typeid of the usertype to drop */
declare @msg    varchar(1024)
declare @dbname varchar(255)
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0


declare @nHARSTClass    int
declare @sqlbuf varchar(50)
declare @rtn_code	int
declare @typeid_hacmp	smallint
declare @zero		char	/* This will be '\0' in C */
declare @username	varchar(255)
declare @uid_hacmp	int

select @zero = char(0)
select @nHARSTClass = ha_getrestrictionclass("sp_droptype")
if (@nHARSTClass = -1)
	return (1)
select @HA_CERTIFIED = 1

if (@nHARSTClass = 3)
begin
	if (db_id() != 1)
		/* We only synch the type information for 'master' DB */
		select @nHARSTClass = 0
	else
		select @nHARSTClass = 1
end


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_droptype', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if @@trancount = 0
begin
	set chained off
end

set transaction isolation level 1

/*
**  Initialize @typeid so we can tell if we can't find it.
*/
select @typeid = 0

/*
**  Find the user type with @typename.  It must be a user type (usertype > 99)
**  and it must be owned by the person (or dbo) running the procedure.
*/
select @typeid = usertype
	from systypes
		where (uid = user_id() or user_id() = 1)
			and name = @typename
			and usertype > 99

if @typeid = 0
begin
	/*
	** 17540, "The type doesn't exist or you don't own it."
	*/
	raiserror 17540
	return (1)
end

/*
**  Check to see if the type is being used.  If it is, it can't be dropped.
*/
if exists (select *
		   from syscolumns
			   where usertype = @typeid)
begin
	/*
	** 17541, "Type is being used. You cannot drop it."
	*/
	raiserror 17541

	/*
	**  Show where it's being used.
	*/
	select object = o.name, type = o.type, owner = u.name, column = c.name,
		datatype = t.name
	from syscolumns c, systypes t, sysusers u, sysobjects o
		where c.usertype = @typeid
			and t.usertype = @typeid
			and o.uid = u.uid
			and c.id = o.id
	order by object, column

	return (1)
end


if (@nHARSTClass = 1)
begin
	/*  HA consistency checking */
	
	/*
	**  Find the user type with @typename.  It must 
	**  be a user type (usertype > 99)
	*/
	select @typeid_hacmp = usertype 
	  from master.dbo.rmt_ha_systypes
	  where  (name = @typename and usertype > 99)
	if (@typeid_hacmp is NULL)
	begin
		/* 
		** If trace flag 2230 is not set, we do not complain,
		** instead, error msg is directed to the error log.
		*/
		dbcc istraceon (2230)
		if (@@error != 0)
		begin
			select @msg = "HA_LOG: HA consistency check failure in ' " + "sp_droptype" + "' on the companion server '" + @@hacmpservername + "'"
                        dbcc printolog (@msg)

                        select @msg = "No type with the specified name exists in the current database" + @zero
                        dbcc printolog (@msg)

                        select @nHARSTClass = 0
                        goto out_of_HA_checking
                end

		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		raiserror 18773, "sp_droptype", @@hacmpservername

		/*
		** 18787, "The type with name '%1!' does not exist."
		*/
		exec sp_getmessage 18787, @msg output
                print @msg, @username

		return (1)
        end

	/* The current user must be a valid user on the companion */
	select @username = user_name()
	select @uid_hacmp = uid from master.dbo.rmt_ha_sysusers
		where name = @username
	if (@uid_hacmp is null)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		raiserror 18773, "sp_droptype", @@hacmpservername

		/*
		** 18302, "User '%1!' is not a valid user in the '%2!'
		** database."
		*/
		exec sp_getmessage 18302, @msg output
		print @msg, @username, "master"

		return (1)
        end
	
	/* 
	** Verify that the current user is the owner of this data type or 
	** dbo. 
	*/
	if not exists (select 1 from master.dbo.rmt_ha_systypes
			where name = @typename and 
				(uid = @uid_hacmp or user_id() = 1))
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		raiserror 18773, "sp_droptype", @@hacmpservername

		/*
		** 17844, "You do not own a user datatype of that name."
		*/
                exec sp_getmessage 17844, @msg output
                print @msg

		return (1)
	end

	/*
	**  Check to see if the type is being used.  If it is, 
	** it can't be dropped.
	*/
	if exists (select 1 from master.dbo.rmt_ha_syscolumns
		where usertype = @typeid_hacmp)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in '%1!' on
		** the companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_droptype", @@hacmpservername
		
		/*
		** 17541, "Type is being used. You cannot drop it."
		*/
		raiserror 17541
		
		return (1)
	end
end


out_of_HA_checking:

/*
**  Everything is consistent so drop the type.
*/

/* 
** This transaction also writes a log record for replicating the
** invocation of this procedure. If logexec() fails, the transaction	
** is aborted.
**
** IMPORTANT: The name rs_logexec is significant and is used by
** Replication Server.
*/
begin transaction rs_logexec


if (@nHARSTClass = 1)
begin
	exec @rtn_code = sp_halockclustertables "sp_droptype"
	if (@rtn_code != 0)
		goto clean_all
end


	delete from systypes
		where usertype = @typeid

	/*
	** Write the log record to replicate this invocation 
	** of the stored procedure.
	*/
	if (logexec() != 1)
	begin
		/*
		** 17756, "The execution of the stored procedure '%1!'
		** 	   in database '%2!' was aborted because there
		** 	   was an error in writing the replication log
		**	   record."
		*/
		select @dbname = db_name()
		raiserror 17756, "sp_droptype", @dbname
				
		rollback transaction rs_logexec
		return (1)
	end


if (@nHARSTClass = 1)
begin
	delete from master.dbo.rmt_ha_systypes
		where name = @typename

	if (@@error != 0)
		goto clean_all

	select @sqlbuf = "declare @dummy int select @dummy = logexec()"
	exec sp_remotesql "SYB_HACMP", @sqlbuf
end


commit transaction rs_logexec

/*
** 17542, "Type has been dropped."
*/
exec sp_getmessage 17542, @msg output
print @msg

return (0)

clean_all:
	rollback transaction rs_logexec
	return (1)
go
exec sp_procxmode 'sp_droptype', 'anymode'
go
grant execute on sp_droptype to public
go
exec sp_procxmode 'sp_droptype', 'rep_current'
go
dump tran master with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_add_time_range')
begin
	drop procedure sp_add_time_range
end
go
print "Installing sp_add_time_range"
go

/* Sccsid = "%Z% generic/sproc/%M% %I% %G%" */

/*
** Messages for "sp_add_time_range"
**
** 17260, "Can't run %1! from within a transaction."
** 17261, "Only the System Administrator (SA) may execute thi
s procedure."
** 18182, "Timerange name must be non-NULL."
** 18183, "Starting day must be non-NULL."
** 18184, "Ending day must be non-NULL."
** 18185, "Starting time must be non-NULL."
** 18186, "Unknown startday %1!."
** 18187, "Unknown endday %1!."
** 18188, "Range '%1!' already exists."
** 18189, "Unknown starting time value %1!."
** 18190, "Unknown ending time value %1!."
** 18191, "Ending time must be later in the day than starting time."
** 18192, "New time range created. ID number is %1!."
** 18219, "Ending time must be non-NULL."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on companion server '%2!'"
** 18819, "Time range '%1!' or id '%2!' already exists in systimeranges."
** 18881, "Unable to generate %1! for HA use. Please refer to documentation for details."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_add_time_range
@name		varchar(255),	/* range name */
@startday	varchar(30),	/* first day of range */
@endday		varchar(30),	/* last day of range */
@starttime	varchar(30),	/* time of day when range begins */
@endtime	varchar(30)	/* time of day when range ends */
as

declare	@msg		varchar(1024)
declare	@curmaxid	int
declare	@newmaxid	int
declare	@start_dt	datetime
declare	@end_dt		datetime
declare	@startdaynum	int
declare	@enddaynum	int
declare @curcount	int
declare @searchcount	int
declare @rtn_code	int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @sqlbuf varchar(255)
declare @error_save int
declare @set_cis_rpc_handling int

select @nHARSTClass = ha_getrestrictionclass("sp_add_time_range")
if (@nHARSTClass = -1)
        return (1)

select @error_save = 0
select @set_cis_rpc_handling = 0
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_add_time_range', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if (proc_role("sa_role") = 0)
begin
	/*
	** 17261, "Only the System Administrator (SA) may execute this procedure."
	*/
	raiserror 17261
	return (1)
end

if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_add_time_range"
	return (1)
end

/* Validate all parameters */

select @name = rtrim(@name)

if (@name is null)
begin
	/*
	** 18182, "Timerange name must be non-NULL."
	*/
	raiserror 18182
	return (1)
end

if (@startday is null)
begin
	/*
	** 18183, "Starting day must be non-NULL."
	*/
	raiserror 18183
	return(1)
end

if (@endday is null)
begin
	/*
	** 18184, "Ending day must be non-NULL."
	*/
	raiserror 18184
	return(1)
end

if (@starttime is null)
begin
	/*
	** 18185, "Starting time must be non-NULL."
	*/
	raiserror 18185
	return(1)
end

if (@endtime is null)
begin
	/*
	** 18219, "Ending time must be non-NULL."
	*/
	raiserror 18219
	return(1)
end

if exists (select * 
	from master.dbo.systimeranges
		where upper(name) = upper(@name))
begin
	/*
	** 18188, "Range '%1!' already exists."
	*/
	raiserror 18188, @name
	return(1)
end

/* Get the start day's number based on the day name */
select @startdaynum = daytonum(@startday) 

if (@startdaynum = -1)
begin
	/*
	** 18186, "Unknown startday %1!."
	*/
	raiserror 18186, @startday
	return(1)
end

/* Get the end day's number based on the day name */
select @enddaynum = daytonum(@endday) 

if (@enddaynum = -1)
begin
	/*
	** 18187, "Unknown endday %1!."
	*/
	raiserror 18187, @endday
	return(1)
end

/* Make sure the time params are valid times */
select @start_dt = convert(datetime, @starttime)
select @end_dt = convert(datetime, @endtime)
if (@start_dt is null)
begin
	/*
	** 18189, "Unknown starting time value %1!."
	*/
	raiserror 18189, @starttime
	return(1)
end
if (@end_dt is null)
begin
	/*
	** 18190, "Unknown ending time value %1!."
	*/
	raiserror 18190, @endtime
	return(1)
end

/* Make sure the time params are in the right order.
** The exception is when endtime is 00:00, which can
** be taken to mean midnight.
*/
if ((datepart(hour, @end_dt) != 0) or
    (datepart(minute, @end_dt) != 0) or
    (datepart(second, @end_dt) != 0)) and
   (@start_dt > @end_dt)
begin
	/*
	** 18191, "Ending time must be later in the day than starting time."
	*/
	raiserror 18191
	return(1)
end

exec @rtn_code = sp_gen_timerange_id @newmaxid output
if (@rtn_code != 0)
	return (1)


if (@nHARSTClass = 1)
begin
	if exists (select 1 from master.dbo.rmt_ha_systimeranges
		where upper(name) = upper(@name))
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		raiserror 18773, "sp_add_time_range", @@hacmpservername

		/*
		** 18188, "Range '%1!' already exists."
		*/
		exec sp_getmessage 18188, @msg
		print @msg, @name
		
		return(1)
	end

	/* Generate a cluster acceptable timerange id */
	if exists (select 1 from master.dbo.rmt_ha_systimeranges
		where id = @newmaxid)
	begin
		if (@@cis_rpc_handling = 0)
		begin
			set cis_rpc_handling on
			select @set_cis_rpc_handling = 1
		end

		exec @rtn_code = SYB_HACMP.sybsystemprocs.dbo.sp_gen_timerange_id
                                        @newmaxid output
		select @error_save = @@error

		if (@set_cis_rpc_handling = 1)
			set cis_rpc_handling off

		if ((@rtn_code != 0) or (@error_save != 0))
			return (1)

                if exists (select 1 from master.dbo.systimeranges
                        where id = @newmaxid)
                begin
			/*
			** 18881, "Unable to generate %1! for HA use. 
			** Please refer to documentation for details."
			*/
			raiserror 18881, "timerange id"
			return (1)
		end
	end


	begin tran ha_dynsyn
	exec @rtn_code = sp_halockclustertables "sp_add_time_range"
	if (@rtn_code != 0)
		goto clean_all
end


/* Insert! */
insert master.dbo.systimeranges values(@name, @newmaxid, @startdaynum, @enddaynum, @starttime, @endtime)


if (@@error != 0)
	goto clean_all

if (@nHARSTClass = 1)
begin
	insert master.dbo.rmt_ha_systimeranges 
		values(@name, @newmaxid, @startdaynum, @enddaynum, 
			@starttime, @endtime)
	if (@@error != 0)
		goto clean_all

	select @sqlbuf = "dbcc waketimerange"
 	exec sp_remotesql "SYB_HACMP", @sqlbuf

	commit tran ha_dynsyn
end


dbcc waketimerange

/*
** 18192, "New time range created. ID number is %1!."
*/
exec sp_getmessage 18192, @msg output
print @msg, @newmaxid
return(0)

clean_all:


	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn


	return (1)
go
exec sp_procxmode 'sp_add_time_range', 'anymode'
go
grant execute on sp_add_time_range to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_drop_time_range')
begin
	drop procedure sp_drop_time_range
end
go
print "Installing sp_drop_time_range"
go

/* Sccsid = "%Z% generic/sproc/%M% %I% %G%" */

/*
** Messages for "sp_drop_time_range"
**
** 17260, "Can't run %1! from within a transaction."
** 17261, "Only the System Administrator (SA) may execute this procedure."
** 18182, "Timerange name must be non-NULL."
** 18194, "`at all times' range may not be dropped."
** 18195, "There are still limits using this range."
** 18196, "Time range '%1!' dropped."
** 18199, "Unknown time range name '%1!'."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on companion server '%2!'"
** 18779, "Unable to find the time range '%1!' with id '%2!' in systimeranges."
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_drop_time_range
@name		varchar(255)	/* name of range to be dropped */
as

declare	@msg		varchar(1024)
declare	@rangeid	int
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @sqlbuf varchar(255)
declare @rtn_code int

select @nHARSTClass = ha_getrestrictionclass("sp_drop_time_range")
if (@nHARSTClass = -1)
        return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_drop_time_range', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if (proc_role("sa_role") = 0)
begin
	/*
	** 17261, "Only the System Administrator (SA) may execute this procedure."
	*/
	raiserror 17261
	return (1)
end

if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_drop_time_range"
	return (1)
end

/* range name must be non-null */

select @name = rtrim(@name)

if (@name is null)
begin
	/*
	** 18182, "Timerange name must be non-NULL."
	*/
	raiserror 18182
	return (1)
end

if not exists (
	select * from master.dbo.systimeranges
		where upper(name) = upper(@name))
begin
	/*
	** 18199, "Unknown time range name '%1!'."
	*/
	raiserror 18199, @name
	return (1)
end

/* Get the id # associated with the range */
select @rangeid = id from master.dbo.systimeranges
	where upper(name) = upper(@name)

/* "at all times" cannot be dropped */
if (@rangeid = 1)
begin
	/*
	** 18194, "`at all times' range may not be dropped."
	*/
	raiserror 18194
	return (1)
end

/* Make sure there aren't any limits still using this range */
if exists (select * from master.dbo.sysresourcelimits
		where rangeid = @rangeid)
begin
	/*
	** 18195, "There are still limits using this range."
	*/
	raiserror 18195
	select * from master.dbo.sysresourcelimits 
		where rangeid = @rangeid
	return(1)
end


if (@nHARSTClass = 1)
begin
	/* HA consistency checking */

	if not exists (select 1 from master.dbo.rmt_ha_systimeranges
		where upper(name) = upper(@name) and id = @rangeid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_drop_time_range", @@hacmpservername

		/*
		** 18779, "Unable to find the time range '%1!' with 
		** id '%2!' in systimeranges."
		*/
		exec sp_getmessage 18779, @msg output
                print @msg, @name, @rangeid

		return (1)
	end

	/* Make sure there aren't any limits still using this range */
	if exists (select 1 from master.dbo.rmt_ha_sysresourcelimits
		where rangeid = @rangeid)
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_drop_time_range", @@hacmpservername

		/*
		** 18195, "There are still limits using this range."
		*/
		raiserror 18195
		select * from master.dbo.rmt_ha_sysresourcelimits
			where rangeid = @rangeid

		return(1)
	end

	begin tran ha_dynsyn
	exec @rtn_code = sp_halockclustertables "sp_drop_time_range"
	if (@rtn_code != 0)
		goto clean_all
end


/* Delete! */
delete master.dbo.systimeranges
	where upper(name) = upper(@name)


if (@@error != 0)
	goto clean_all

if (@nHARSTClass = 1)
begin
	delete master.dbo.rmt_ha_systimeranges
		where upper(name) = upper(@name)

	if (@@error != 0)
		goto clean_all

	select @sqlbuf = "dbcc waketimerange"
 	exec sp_remotesql "SYB_HACMP", @sqlbuf

	commit tran ha_dynsyn
end


dbcc waketimerange
/*
** 18196, "Time range '%1!' dropped."
*/
exec sp_getmessage 18196, @msg output
print @msg, @name

return(0)

clean_all:

	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn

	return (1)
go
exec sp_procxmode 'sp_drop_time_range', 'anymode'
go
grant execute on sp_drop_time_range to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_modify_time_range')
begin
	drop procedure sp_modify_time_range
end
go
print "Installing sp_modify_time_range"
go

/* Sccsid = "%Z% generic/sproc/%M% %I% %G%" */

/*
** Messages for "sp_modify_time_range"
**
** 17260, "Can't run %1! from within a transaction."
** 17261, "Only the System Administrator (SA) may execute this procedure."
** 18182, "Timerange name must be non-NULL."
** 18186, "Unknown startday %1!."
** 18187, "Unknown endday %1!."
** 18189, "Unknown starting time value %1!."
** 18190, "Unknown ending time value %1!."
** 18191, "Ending time must be later in the day than starting time."
** 18197, "At least one of the starting day, ending day, starting time, or ending time must be non-NULL."
** 18199, "Unknown time range name '%1!'."
** 18200, "at all times' range may not be modified."
** 18201, "Modification would cause overlap with range %1!."
** 18773, "HA_LOG: HA consistency check failure in stored procedure '%1!' on companion server '%2!'"
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_modify_time_range
@name		varchar(255) = NULL,	/* range name */
@startday	varchar(30) = NULL,	/* first day of range */
@endday		varchar(30) = NULL,	/* last day of range */
@starttime	varchar(30) = NULL,	/* starting time */
@endtime	varchar(30) = NULL	/* ending time */
as

declare	@range_being_modified	smallint
declare	@current_range	smallint
declare	@start_dt	datetime
declare	@end_dt		datetime
declare	@cur_start_dt	datetime
declare	@cur_end_dt	datetime
declare	@startdaynum	int
declare	@enddaynum	int
declare	@cur_startdaynum	int
declare	@cur_enddaynum	int
declare @tmp_starttime	varchar(30)
declare @tmp_endtime	varchar(30)
declare @msg		varchar(1024)
declare @HA_CERTIFIED tinyint   /* Is the SP HA certified ? */
declare @retstat  int


select @HA_CERTIFIED = 0



/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass int
declare @sqlbuf varchar(255)
declare @rtn_code int

select @nHARSTClass = ha_getrestrictionclass("sp_modify_time_range")
if (@nHARSTClass = -1)
        return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_modify_time_range', @HA_CERTIFIED
if (@retstat != 0)
        return (1)

if (proc_role("sa_role") = 0)
begin
	/*
	** 17261, "Only the System Administrator (SA) may execute this procedure."
	*/
	raiserror 17261
	return (1)
end

if @@trancount > 0
begin
	/*
	** 17260, "Can't run %1! from within a transaction." 
	*/
	raiserror 17260, "sp_modify_time_range"
	return (1)
end

/* Make sure we have at least the minimum of args */
if (@startday is null) and (@endday is null) and (@starttime is null) and (@endtime is null)
begin
	/*
	** 18197, "At least one of the starting day, ending day, starting time, or ending time must be non-NULL."
	*/
	raiserror 18197
	return(1)
end

/* Has a valid range name been specified? */

select @name = rtrim(@name)

if (@name is null)
begin
	/*
	** 18182, "Timerange name must be non-NULL."
	*/
	raiserror 18182
	return(1)
end
else
begin
	if not exists(select * from master.dbo.systimeranges
			where upper(name) = upper(@name))
	begin
		/*
		** 18199, "Unknown time range name '%1!'."
		*/
		raiserror 18199, @name
		return(1)
	end
	select @range_being_modified = id from master.dbo.systimeranges
		where upper(name) = upper(@name)
end

/* "at all times" cannot be modified */
if (@range_being_modified = 1)
begin
	/*
	** 18200, "at all times' range may not be modified."
	*/
	raiserror 18200
	return (1)
end

/* Get the start day's number based on the day name */
if (@startday is not null)
	select @startdaynum = daytonum(@startday) 
else
	select @startdaynum = startday from master.dbo.systimeranges
		where upper(name) = upper(@name)

if (@startdaynum = -1)
begin
	/*
	** 18186, "Unknown startday %1!."
	*/
	raiserror 18186, @startday
	return(1)
end

/* Get the end day's number based on the day name */
if (@endday is not null)
	select @enddaynum = daytonum(@endday) 
else
	select @enddaynum = endday from master.dbo.systimeranges
		where upper(name) = upper(@name)

if (@enddaynum = -1)
begin
	/*
	** 18187, "Unknown endday %1!."
	*/
	raiserror 18187, @endday
	return(1)
end

/* If we're modifying the start time, convert it to datetime
** so we can do arithmetic 
*/
if (@starttime is not null)
begin
	select @start_dt = convert(datetime, @starttime)
	if (@start_dt is null)
	begin
		/*
		** 18189, "Unknown starting time value %1!."
		*/
		raiserror 18189, @starttime
		return(1)
	end
end
else
	select @start_dt = convert(datetime, starttime)
		from master.dbo.systimeranges
			where upper(name) = upper(@name)

/* If we're modifying the end time, convert it to datetime
** so we can do arithmetic 
*/
if (@endtime is not null)
begin
	select @end_dt = convert(datetime, @endtime)
	if (@end_dt is null)
	begin
		/*
		** 18190, "Unknown ending time value %1!."
		*/
		raiserror 18190, @endtime
		return(1)
	end
end
else
	select @end_dt = convert(datetime, endtime)
		from master.dbo.systimeranges
			where upper(name) = upper(@name)

/* Make sure the start and end times are in the right order.
** The exception is when endtime is 00:00, which can
** be taken to mean midnight.
*/
if ((datepart(hour, @end_dt) != 0) or
    (datepart(minute, @end_dt) != 0) or
    (datepart(second, @end_dt) != 0)) and
   (@start_dt > @end_dt)
begin
	/*
	** 18191, "Ending time must be later in the day than starting time."
	*/
	raiserror 18191
	return(1)
end

/* Cursor result: ranges used by user/applications with at least
** 1 limit defined during @range_being_modified
*/
declare c1 cursor for 
select distinct rangeid from master.dbo.sysresourcelimits a
	where exists (select * from master.dbo.sysresourcelimits b
	where ((a.name = b.name) or (a.name is null) or (b.name is null)) and
	((a.appname = b.appname) or (a.appname is null) or (b.appname is null)) and
	(b.rangeid = @range_being_modified))
/*
order by name, appname
*/

open c1

fetch c1 into @current_range

/* We need to peruse the cursor results to see if modifying
** this range would cause a limit overlap for any given
** user/application.
*/
while (@@sqlstatus != 2)
begin

	if (@current_range != @range_being_modified)
	begin

		/* Get the start and end days for current range */
		select @cur_startdaynum = startday from 
			master.dbo.systimeranges
			where id = @current_range
		select @cur_enddaynum = endday from 
			master.dbo.systimeranges
			where id = @current_range

		/* Get the start and end times for current range */
		select @tmp_starttime = starttime from 
			master.dbo.systimeranges
			where id = @current_range
		select @tmp_endtime = endtime from 
			master.dbo.systimeranges
			where id = @current_range
		select @cur_start_dt = convert(datetime, @tmp_starttime)
		select @cur_end_dt = convert(datetime, @tmp_endtime)

		/* See if the modified range overlaps with any other
		** range used by limits for this user/application
		** (excepting limits defined for the exact
		** same timerange).
		*/

		/* This is the non-wrapping case, for starttime.
		** If (the current range doesn't wrap around the
		** end of the week)
		** and
		** (the days of the modified range
		** overlap with the current range)
		** and 
		** (the starttime of the modified range is after
		** the starttime of the current range)
		** and 
		** (the endtime of the modified range is before
		** the endtime of the current range, with 00:00
		** being taken as midnight)
		** then we have an overlap, so raise an error
		** and return.
		*/
		if 
		(@cur_startdaynum <= @cur_enddaynum) 
		and 
		(((@startdaynum >= @cur_startdaynum) and
		  (@startdaynum <= @cur_enddaynum)) or
		 ((@enddaynum >= @cur_startdaynum) and
		  (@enddaynum <= @cur_enddaynum)) or
		 ((@startdaynum <= @cur_startdaynum) and
		  (@enddaynum >= @cur_enddaynum)))
		and
		(@start_dt >= @cur_start_dt) 
		and 
		((@start_dt < @cur_end_dt) or
		 ((datepart(hour, @cur_end_dt) = 0) and
		  (datepart(minute, @cur_end_dt) = 0) and
		  (datepart(second, @cur_end_dt) = 0)))
		begin
			/*
			** 18201, "Modification would cause overlap with range %1!."
			*/
			raiserror 18201, @current_range
			close c1
			return(1)
		end

		/* This is the wrapping case, for starttime.
		*/
		if
		(@cur_startdaynum > @cur_enddaynum) 
		and
		((@startdaynum >= @cur_startdaynum) or
		 (@startdaynum <= @cur_enddaynum) or
		 (@enddaynum >= @cur_startdaynum) or
		 (@enddaynum <= @cur_enddaynum)) 
		and
		(@start_dt >= @cur_start_dt) 
		and 
		((@start_dt < @cur_end_dt) or
		 ((datepart(hour, @cur_end_dt) = 0) and
		  (datepart(minute, @cur_end_dt) = 0) and
		  (datepart(second, @cur_end_dt) = 0)))
		begin
			/*
			** 18201, "Modification would cause overlap with range %1!."
			*/
			raiserror 18201, @current_range
			close c1
			return(1)
		end
			
		/* This is the non-wrapping case, for endtime.
		** If (the current range doesn't wrap around the
		** end of the week)
		** and
		** (the days of the modified range
		** overlap with the current range)
		** and 
		** (the endtime of the modified range is before
		** the endtime of the current range, with 00:00
		** being taken as midnight)
		** and 
		** (the endtime of the modified range is after
		** the starttime of the current range)
		** then we have an overlap, so raise an error
		** and return.
		*/
		if 
		(@cur_startdaynum <= @cur_enddaynum) 
		and 
		(((@startdaynum >= @cur_startdaynum) and
		  (@startdaynum <= @cur_enddaynum)) or
		 ((@enddaynum >= @cur_startdaynum) and
		  (@enddaynum <= @cur_enddaynum)) or
		 ((@startdaynum <= @cur_startdaynum) and
		  (@enddaynum >= @cur_enddaynum)))
		and
		((@end_dt <= @cur_end_dt) or 
		 ((datepart(hour, @cur_end_dt) = 0) and
		  (datepart(minute, @cur_end_dt) = 0) and
		  (datepart(second, @cur_end_dt) = 0)))
		and 
		(@end_dt > @cur_start_dt)
		begin
			/*
			** 18201, "Modification would cause overlap with range %1!."
			*/
			raiserror 18201, @current_range
			close c1
			return(1)
		end

		/* This is the wrapping case, for endtime.
		*/
		if 
		(@cur_startdaynum > @cur_enddaynum) 
		and
		((@startdaynum >= @cur_startdaynum) or
		 (@startdaynum <= @cur_enddaynum) or
		 (@enddaynum >= @cur_startdaynum) or
		 (@enddaynum <= @cur_enddaynum)) 
		and
		((@end_dt <= @cur_end_dt) or 
		 ((datepart(hour, @cur_end_dt) = 0) and
		  (datepart(minute, @cur_end_dt) = 0) and
		  (datepart(second, @cur_end_dt) = 0)))
		and 
		(@end_dt > @cur_start_dt)
		begin
			/*
			** 18201, "Modification would cause overlap with range %1!."
			*/
			raiserror 18201, @current_range
			close c1
			return(1)
		end

		/* This is the non-wrapping case, where
		** the modified range completely
		** covers the current range.
		*/
		if
		(@cur_startdaynum <= @cur_enddaynum) 
		and
		(((@startdaynum >= @cur_startdaynum) and
		  (@startdaynum <= @cur_enddaynum)) or
		 ((@enddaynum >= @cur_startdaynum) and
		  (@enddaynum <= @cur_enddaynum)) or
		 ((@startdaynum <= @cur_startdaynum) and
		  (@enddaynum >= @cur_enddaynum)))
		and
		(@start_dt < @cur_start_dt) 
		and 
		( ((@end_dt > @cur_end_dt) and
		  ((datepart(hour, @cur_end_dt) != 0) or
		   (datepart(minute, @cur_end_dt) != 0) or
		   (datepart(second, @cur_end_dt) != 0)))
		  or
		  ((datepart(hour, @end_dt) = 0) and
		   (datepart(minute, @end_dt) = 0) and
		   (datepart(second, @end_dt) = 0)) )
		begin
			/*
			** 18201, "Modification would cause overlap with range %1!."
			*/
			raiserror 18201, @current_range
			close c1
			return(1)
		end
			
		/* This is the wrapping case, where
		** the modified range completely
		** covers the current range.
		*/
		if
		(@cur_startdaynum > @cur_enddaynum) 
		and
		((@startdaynum >= @cur_startdaynum) or
		 (@startdaynum <= @cur_enddaynum) or
		 (@enddaynum >= @cur_startdaynum) or
		 (@enddaynum <= @cur_enddaynum)) 
		and
		(@start_dt < @cur_start_dt) 
		and 
		( ((@end_dt > @cur_end_dt) and
		  ((datepart(hour, @cur_end_dt) != 0) or
		   (datepart(minute, @cur_end_dt) != 0) or
		   (datepart(second, @cur_end_dt) != 0)))
		  or
		  ((datepart(hour, @end_dt) = 0) and
		   (datepart(minute, @end_dt) = 0) and
		   (datepart(second, @end_dt) = 0)) )
		begin
			/*
			** 18201, "Modification would cause overlap with range %1!."
			*/
			raiserror 18201, @current_range
			close c1
			return(1)
		end
			
	end

	fetch c1 into @current_range
end

close c1

/* Can we even find a range to modify? */
if (select count(*) from master.dbo.systimeranges
	where upper(name) = upper(@name)) = 0
begin
	/*
	** 18242, "No such time range found in systimeranges."
	*/
	raiserror 18242
	return(1)
end


if (@nHARSTClass = 1)
begin
	if not exists (select 1 from master.dbo.rmt_ha_systimeranges
		where upper (name) = upper(@name))
	begin
		/*
		** 18773, "HA_LOG: HA consistency check failure in stored
		** procedure '%1!' on companion server '%2!'"
		*/
		exec sp_getmessage 18773, @msg output
		print @msg, "sp_modify_time_range", @@hacmpservername

		/*
		** 18199, "Unknown time range name '%1!'."
		*/
		raiserror 18199, @name

		return(1)
	end

	begin tran ha_dynsyn
	exec @rtn_code = sp_halockclustertables "sp_modify_time_range"
	if (@rtn_code != 0)
		goto clean_all
end


/* Update! */
if (@startday is not null)
begin
	update master.dbo.systimeranges
	set startday = @startdaynum where upper(name) = upper(@name)


	if (@@error != 0)
		goto clean_all


end

if (@endday is not null)
begin
	update master.dbo.systimeranges
	set endday = @enddaynum where upper(name) = upper(@name)


if (@@error != 0)
        goto clean_all


end

if (@starttime is not null)
begin
	update master.dbo.systimeranges
	set starttime = @starttime where upper(name) = upper(@name)


if (@@error != 0)
        goto clean_all


end

if (@endtime is not null)
begin
	update master.dbo.systimeranges
	set endtime = @endtime where upper(name) = upper(@name)
end


if (@@error != 0)
        goto clean_all

if (@nHARSTClass = 1)
begin
	if (@startday is not null)
	begin
		update master.dbo.rmt_ha_systimeranges
		set startday = @startdaynum 
		where upper(name) = upper(@name)

		if (@@error != 0)
			goto clean_all
	end

	if (@endday is not null)
	begin
		update master.dbo.rmt_ha_systimeranges
		set endday = @enddaynum 
		where upper(name) = upper(@name)
		
		if (@@error != 0)
			goto clean_all
	end

	if (@starttime is not null)
	begin
		update master.dbo.rmt_ha_systimeranges
		set starttime = @starttime 
		where upper(name) = upper(@name)

		if (@@error != 0)
			goto clean_all
	end

	if (@endtime is not null)
	begin
		update master.dbo.rmt_ha_systimeranges
		set endtime = @endtime 
		where upper(name) = upper(@name)

		if (@@error != 0)
			goto clean_all
	end
	select @sqlbuf = "dbcc waketimerange"
 	exec sp_remotesql "SYB_HACMP", @sqlbuf

	commit tran ha_dynsyn
end

dbcc waketimerange

return(0)

clean_all:

	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn

	return (1)
go
exec sp_procxmode 'sp_modify_time_range', 'anymode'
go
grant execute on sp_modify_time_range to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_maplogin')
begin
	drop procedure sp_maplogin
end
go
print "Installing sp_maplogin"
go

/* Sccsid = "%Z% generic/sproc/src/%M% %I% %G%" */

/*
** Messages for "sp_maplogin"    
**
** 17260, "Can't run '%1!' from within a transaction."
** 18294, "User '%1!' is not a local user -- request denied."
** 18773, "HA_LOG: HA consistency check failure in '%1!' on the companion server '%2!'"
** 18778, "Unable to find login '%1!' with id '%2!' in syslogins."
** 19257, "The authentication mechanism '%1!' is not valid."
** 19256, "Client authentication mapping updated."
** 19259, "Warning. Authentication mechanism '%1!' is not enabled."
** 19445, "External name '%1!' is already a local login -- map request denied."
** 19447, "User '%1!' allows only '%2!' authentication mechanism to be used -- request denied."
** 19450, "A mapping with authentication mechanism '%1!' is not allowed, only action 'drop' is permitted."
** 19453, "Cannot define a mapping for ALL authentications and ALL logins -- map request denied.
** 19940, "Client authentication mapping overwritten. Previous values were @authentication_mech='%1!', @client_name='%2!' and @login_name='%3!'.
*/

/* 
** IMPORTANT: Please read the following instructions before
**   making changes to this stored procedure.
**
**	To make this stored procedure compatible with High Availability (HA),
**	changes to certain system tables must be propagated 
**	to the companion server under some conditions.
**	The tables include (but are not limited to):
**		syslogins, sysservers, sysattributes, systimeranges,
**		sysresourcelimits, sysalternates, sysdatabases,
**		syslanguages, sysremotelogins, sysloginroles,
**		sysalternates (master DB only), systypes (master DB only),
**		sysusers (master DB only), sysprotects (master DB only)
**	please refer to the HA documentation for detail.
**
**	Here is what you need to do: 
**	For each insert/update/delete statement, add three sections to
**	-- start HA transaction prior to the statement
**	-- add the statement
**	-- add HA synchronization code to propagate the change to the companion
**
**	For example, if you are adding 
**		insert master.dbo.syslogins ......
**	the code should look like:
**	1. Before that SQL statement:
**		
**		if (@nHARSTClass = 1)
**			begin tran ha_dynsyn
**		
**	2. Now, the SQL statement:
**		insert master.dbo.syslogins ......
**	3. Add a HA synchronization section right after the SQL statement:
**		
**		if (@@error != 0)
**			goto clean_all
**		if (@nHARSTClass = 1)
**		begin
**			insert master.dbo.rmt_ha_syslogins ......
**			if (@@error != 0)
**				goto clean_all
**			
**			commit tran ha_dynsyn
**		end
**		
**
**	You may need to do similar change for each built-in function you
**	want to add.
**
**	Finally, add a separate part at a place where it can not
**	be reached by the normal execution path:
**	clean_all:
**		
**			if (@nHARSTClass = 1)
**				rollback tran ha_dynsyn
**		
**		return (1)
*/

create procedure sp_maplogin
	@authmethod	varchar(30) = NULL,	/* Authentication mechanism */
	@externname	varchar(255) = NULL,	/* client user name */
	@loginame	varchar(255) = NULL	/* user's local name */
AS
BEGIN

DECLARE	@msg		varchar(1024),
	@authid		int,
	@any_authid	int,			/* LOGIN_ANY auth id */
	@syslog_authid	int,			/* syslogin auth id */
	@syslog_authmch	varchar(30),		/* syslogin auth mech name */
	@suid		int,
	@login_class	smallint,		/* omni's attribute  class */
	@attrib		smallint,		/* attr. id for ext. login */
	@action		smallint,
	@dummy		int,
	@HA_CERTIFIED	tinyint,   /* Is the SP HA certified ? */
	@retstat	int,
	@config		int,
	@del		int,
	@auth_mech      varchar(30),
	@client_name    varchar(255),
	@login_name     varchar(255)
	
/*
** Only a user with sso_role can add extern login mappings
*/
	if (proc_role("sso_role") < 1)
		return 1

	select @HA_CERTIFIED = 0
	select @retstat = 0


/* Dynamic synchronization related variables declaration and initialization */

	declare @nHARSTClass    int
	declare @set_cis_rpc_handling int
	declare @error_save	int

	select @set_cis_rpc_handling = 0
	select @error_save = 0

	select @nHARSTClass = ha_getrestrictionclass("sp_maplogin")
	if (@nHARSTClass = -1)
		return (1)

	select @HA_CERTIFIED = 1



/* check to see if we are using HA specific SP for a HA enabled server */
	exec @retstat = sp_ha_check_certified 'sp_maplogin', @HA_CERTIFIED
	if (@retstat != 0)
        	return (1)

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
	if @@trancount > 0
	BEGIN
		/*		
		** 17260 Can't run '%1!' from within a transaction.
		*/
		raiserror 17260, "sp_maplogin"
		return 1
	END

/* 
** We cannot define any mapping for all authentications
** and all logins
*/
	if ((@authmethod is null or upper(@authmethod) = 'ANY') 
		and (@externname is null or upper(@externname) = 'ANY'))
	BEGIN
		/*		
		** 19453  "Cannot define a mapping for ALL authentications 
		** and ALL logins -- map request denied.
		*/
		raiserror 19453
		return 1
	END

/*
** Check that the auth method is valid. NULL means ALL.
*/
	if (@authmethod is null)
		select @authmethod = 'ANY'

        /*
        ** Check whether authentication mechanism specified is valid or not.
        ** 'AUTH_DEFAULT' and 'AUTH_MASK' are new values added in spt_values
        ** used to obtain value of default ('ANY') authmech or authentication
        ** mask respectively. They are not valid names that the user can
        ** specify as authentication mechanism.
        */
	select	@authid = low, @config = number
		from master.dbo.spt_values
		where type = 'ua' and upper(name) = upper(@authmethod)
		and upper(name) not in ('AUTH_DEFAULT', 'AUTH_MASK')

	if @@rowcount = 0 
	BEGIN
		/*		
		** 19257  "The authentication mechanism '%1!' is not valid .
		*/
		raiserror 19257, @authmethod
		return (1)
	END

/*
** Check that the authentication method is enabled. The configuration option
** is in spt_values.number.
** For SMP or SDC, look up syscurconfigs for local instance.
*/
	if (@config != 0) and not exists(select 1
		from master.dbo.syscurconfigs a

		where a.config = @config and a.value != 0)

	BEGIN
		/*
		** 19259, "Warning. Authentication mechanism '%1!' is not enabled."
		*/
		exec sp_getmessage 19259, @msg output
		print @msg, @authmethod
	END

	select @del = 0
	
/*
** Check the login name/action
*/
	if upper(@loginame) = "CREATE LOGIN"
		select @suid = -3
	else if (upper(@loginame) = 'DROP')
		select @del = 1
	else
	BEGIN
/*
** Check that the @loginame is valid.
*/
		/*
		**  Set a mask with all the authentication bits using
		** 'AUTH_MASK'
		*/
		select	@any_authid = low
			from master.dbo.spt_values
			where type = 'ua' and upper(name) = 'AUTH_MASK'

		select @suid = suid, @syslog_authid = (status & @any_authid)
			from master.dbo.syslogins
			where name = @loginame
		if @@rowcount = 0  
		BEGIN
			/*		
			** 18294 "User '%1!' is not a local user -- 
			** request denied."
			*/
			raiserror 18294, @loginame
			return (1)
		END

		/* authid of 0 means ANY, set it the local var to this value. */
		if @syslog_authid = 0
			select @syslog_authid = @any_authid

/*
**  Check the authentication mechanism for a login and authentication
**  mechanism parameter to sp_maplogin do not conflict.  There should
**  be at least one bit matching in the two masks representing the
**  authentication mechanism.
**
**  The bitmask for auth mech NONE/NULL has already been mapped to ANY.
*/

		if (@syslog_authid & @authid) = 0
		BEGIN
			select	@syslog_authmch = name
				from master.dbo.spt_values
				where type = 'ua' and low = @syslog_authid
				and upper(name) not in ('AUTH_DEFAULT',
				'AUTH_MASK')
			/*		
			** 19447 "User '%1!' allows only '%2!' authentication 
			** mechanism to be used -- request denied."
			*/
			raiserror 19447, @loginame, @syslog_authmch
			return (1)
		END
	END

	if (@externname is null or upper(@externname) = 'ANY')
	BEGIN
		select @externname = '*'
	END

	if (@externname != '*' and @del = 0)
	BEGIN
/*
**  Check that an explicit value of @externname is not already a local login
*/
		if exists (select 1 
			from master.dbo.syslogins 
			where name = @externname)
		BEGIN
			/*		
			** 19445 "External name '%1!' is already a local 
			** login -- map request denied."
			*/
			raiserror 19445, @externname
			return (1)
		END
	END
/*
** Check if the ASE authentication mechanism is used for the mapping.
** New behavior in ASE 12.5.4 prevents local logins from being mapped
** to other local logins, making most actions with ASE auth mech invalid.
** The only allowed action allowed for ASE is 'drop', to aid in removing any
** mappings that may have been added in earlier releases.
*/
	if (upper(@authmethod) = "ASE") and (@del = 0)
	BEGIN
		/*		
		** 19450  "A mapping with authentication mechanism '%1!' is
		** not allowed, only action 'drop' is permitted."
		*/
		raiserror 19450, @authmethod
		return (1)
	END
/*
** The mapping is stored in sysattributes. The entries for external
** authentication mechanisms are as follows:
**
**	- class:	20
**	- attribute:	0
**	- object:	mapped suid
**			- It may have a real suid or,
**			- INVALID_SUID (-2), to map using the external name.
**			- CRTLOGIN_SUID (-3), to create login if it does not
**			  exist.
**	- object_cinfo:	external name, or '*' for all external names.
**	- object_info1: authentication mechanism. If we map any authentication
**			it will contain LOGIN_ALL, that is an OR of all the
**			existing authentication mechinsms.
**
** If there is already an entry for that external user, we'll update
** it, else we'll insert a new row.
** For each user only one authentication mechanism is allowed. However,
** when setting a generic map (extern user name is null), there can
** be multiple entries for it. We can specify that all the users using
** PAM will be mapped as u1, all users using LDAP will be mapped
** u2, etc.
*/
	select @login_class = 20, @attrib = 0

/*
** Check whether a mapping already exists. If it does, update it
** or delete it, depending on the parameter @delete.
** If the client user name is null, we will look for a mapping for
** all users with the authentication method specified.
** If the client user name is not null, we will look for a mapping
** for this user.
*/
	if ((@externname = '*' and 
		exists(select * from master.dbo.sysattributes where
			class = @login_class and attribute = @attrib and
			object_cinfo = '*' and
			object_info1 = @authid))
	   or (@externname != '*' and
		exists(select * from master.dbo.sysattributes where
			class = @login_class and attribute = @attrib and 
			object_cinfo = @externname)))
	BEGIN	
		if (@del = 0)
			select @action = 2	/* update attribute */
		else
			select @action = 3      /* delete attribute */
	END
	else 
	BEGIN
		if (@del = 0)
			select @action = 1 	/* insert attribute */	
		else
			/* Nothing to delete. */
			return (0)
	END

/*
** First validate the row. 
*/
	if attrib_valid(@login_class, @attrib, "LM", @suid, @authid, NULL, NULL,
		@externname, NULL, NULL, NULL, NULL, NULL, @action) = 0         
	BEGIN
		return(1)
	END


if (@nHARSTClass = 1)
begin

	if @loginame is not NULL
	BEGIN
		/* 
		** Make sure that the @loginame is valid on the companion 
		** server.
		*/
		if not exists (select 1 from master.dbo.rmt_ha_syslogins
			where name = @loginame AND suid = @suid)
		BEGIN
			/*
			** 18773, "HA_LOG: HA consistency check failure 
			** in '%1!' on the companion server '%2!'"
			*/
			exec sp_getmessage 18773, @msg output
			print @msg, "sp_maplogin", @@hacmpservername

			/*
			** 18778, "Unable to find login '%1!' with id '%2!' 
			** in syslogins."
			*/
       		        exec sp_getmessage 18778, @msg output
       		        print @msg, @loginame, @suid

			return (1)
		END
	END

	begin tran ha_dynsyn

	exec @retstat = sp_halockclustertables "sp_maplogin"
	if (@retstat != 0)
		goto clean_all
end


/*
** Now insert/update/delete the row
*/
	if @action = 1
	BEGIN
		insert into master.dbo.sysattributes (class, attribute, 
			object_type, object_info1, object, object_cinfo,
			image_value, object_info2)
		values (@login_class, @attrib, "LM", @authid, @suid, 
			@externname, null, null)

		if (@@error != 0)
			goto clean_all

                /*
                ** 19256 "Client authentication mapping updated."
                */
                exec sp_getmessage 19256, @msg output
                print @msg
	END
	else if @action = 2 
	BEGIN
	        if (@externname = '*') 
                BEGIN
			/* 
			** Select the previous mapping information to be 
			** displayed in the message before updating the row.
			*/
                        select  @auth_mech = isnull(s.name, "ANY"),
                                @client_name =
                                case object_cinfo
                                        when '*' then "ANY"
                                        else object_cinfo
                                end,
                                @login_name =
                                case object
                                        when -2 then "ANY"
                                        when -3 then "CREATE LOGIN"
                                        else isnull(suser_name(object), "NO MAP")
                                end
                        from master.dbo.sysattributes, master.dbo.spt_values s
                        where class = @login_class and attribute = @attrib and
                                (object_info1 = s.low) and
                                (s.name not in ('AUTH_MASK')) and
                                (s.type = 'ua') and
                                object_cinfo = '*' and object_info1 = @authid

			update master.dbo.sysattributes
			set     object = @suid
			where class = @login_class and attribute = @attrib and
                        	object_cinfo = '*' and
                        	object_info1 = @authid
		END
		else
                BEGIN
                        /*
                        ** Select the previous mapping information to be
                        ** displayed in the message before updating the row.
                        */
                        select  @auth_mech = isnull(s.name, "ANY"),
                                @client_name =
                                case object_cinfo
                                        when '*' then "ANY"
                                        else object_cinfo
                                end,
                                @login_name =
                                case object
                                        when -2 then "ANY"
                                        when -3 then "CREATE LOGIN"
                                        else isnull(suser_name(object), "NO MAP")
                                end
                        from master.dbo.sysattributes, master.dbo.spt_values s
                        where class = @login_class and attribute = @attrib and
                                (object_info1 = s.low) and
                                (s.name not in ('AUTH_MASK')) and
                                object_cinfo = @externname
	
			update master.dbo.sysattributes
			set	object = @suid, object_info1 = @authid
			where	class = @login_class and 
				attribute = @attrib and
				object_cinfo = @externname 
		END

		if (@@error != 0)
			goto clean_all

                /*
                ** 19940 "Client authentication mapping overwritten.
                ** Previous values were @authentication_mech='%1!',
                ** @client_name='%2!' and @login_name='%3!'."
                */
                exec sp_getmessage 19940, @msg output
                print @msg, @auth_mech, @client_name, @login_name
	END 
	else if @action = 3
	BEGIN
		delete master.dbo.sysattributes
		where   class = @login_class and 
			attribute = @attrib and
			object_cinfo = @externname and
			object_info1 = @authid
		if (@@error != 0)
			goto clean_all

                /*
                ** 19256 "Client authentication mapping updated."
                */
                exec sp_getmessage 19256, @msg output
                print @msg
	END


	if (@nHARSTClass = 1)
	begin
		if @action = 1
		BEGIN
			insert into master.dbo.rmt_ha_sysattributes 
				(class, attribute, object_type, 
				object_info1, object, object_cinfo,
				image_value, object_info2)
			values (@login_class, @attrib, "LM", @authid, 
				@suid, @externname, null, null)
	
			if (@@error != 0)
				goto clean_all
		END
		else if @action = 2 
		BEGIN
	        	if (@externname = '*') 
				update master.dbo.rmt_ha_sysattributes
				set     object = @suid
				where class = @login_class 
					and attribute = @attrib and
                        		object_cinfo = '*' and
                        		object_info1 = @authid
			else	
				update master.dbo.rmt_ha_sysattributes
				set	object = @suid, 
					object_info1 = @authid
				where	class = @login_class and 
					attribute = @attrib and
					object_cinfo = @externname 
	
			if (@@error != 0)
				goto clean_all
		END 
		else if @action = 3
		BEGIN
			delete master.dbo.rmt_ha_sysattributes
				where   class = @login_class and 
					attribute = @attrib and
					object_cinfo = @externname and
					object_info1 = @authid
			if (@@error != 0)
				goto clean_all
		END


		commit tran ha_dynsyn

		/* Enable cis_rpc_handling to make remote call */
		if (@@cis_rpc_handling = 0)
		begin
			set cis_rpc_handling on
			select @set_cis_rpc_handling = 1
		end

		exec @retstat = SYB_HACMP.sybsystemprocs.dbo.sp_attrib_notify @login_class, @attrib, "LM", @suid, @authid, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @action
		select @error_save = @@error
	
		if (@set_cis_rpc_handling = 1)
			set cis_rpc_handling off
		
		/* 
		** We want to catch error reported by either @retstat or
		** @@error and save the error code in @retstat if any
		*/
		if ((@retstat != 0) or (@error_save != 0))
			select @retstat = 1
		else
			select @retstat = 0
	end



	/*
	** Sync the in-memory RDES with the new values
	** in sysattributes.
	*/
	if attrib_notify(@login_class, @attrib, "LM", @suid, @authid, NULL,
			NULL, NULL, NULL, NULL, NULL, NULL, NULL,
			@action) = 0
		return (1)
	else
		return (@retstat)
END

clean_all:

	if (@nHARSTClass = 1)
		rollback tran ha_dynsyn

	return (1)
go
exec sp_procxmode 'sp_maplogin', 'anymode'
go
grant execute on sp_maplogin to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_update_authmech_value')
begin
	drop procedure sp_update_authmech_value
end
go
print "Installing sp_update_authmech_value"
go


/*
** This stored procedure is used to update the syslogins.status from 224 or 
** 480 to 0 for logins upgraded from pre 12.5.4 to 12.5.4 or 15.0.2.
** Logins created on pre 12.5.4 code had the status equal to 224 which
** indicated 'ANY' authentication. 224 is formed by ASE, LDAP and PAM bits,
** viz. 32, 64, 128 respectively.
** From 12.5.4 onwards, KERBEROS was also included in this status. So,
** effectively, the value that would indicate 'ANY' became 32+64+128+256 = 480
** If now the ASE is upgraded to 12.5.4 or 15.0.2, the new ASE will compare
** it with 480 instead of 224 to check if the authentication is 'ANY'.
** In case of KERBEROS authentication, new ASE server was looking for status
** as 256 for KERBEROS logins, which lead to their failure. In order to avoid
** this, this procedure will update the status bits appropriately.
*/
/*
** Messages for update_authmech_value [Total 3]
** 17260, "Can't run %1! from within a transaction."
** 19882, "sp_update_authmech_value should not be executed on this release of Adaptive Server, no changes made."
** 19883, "Updated authentication mechanism for %1! row(s) on %2! server."
*/

create procedure sp_update_authmech_value
as
declare @ase_version            char(10),/* Indicate current ASE version */
        @HA_CERTIFIED           tinyint, /* Is the SP HA certified ? */
        @retstat                int,
        @auth_mask              int,     /* Authentication Mask */
        @auth_1253_all          int,     /* ASE, LDAP and PAM bit mask */
        @msg                    varchar(1024),
        @prisavedupdatecount    int     /* Number of rows updated on
                                         ** primary server
                                         */

select @HA_CERTIFIED = 0


/* Dynamic synchronization related variables declaration and initialization */
declare @nHARSTClass    int,
        @rtn_code       int,
	@cmpsavedupdatecount    int     /* Number of rows updated on
					** companion server
					*/

select @nHARSTClass = ha_getrestrictionclass("sp_update_authmech_value")
if (@nHARSTClass = -1)
        return (1)
select @HA_CERTIFIED = 1


/* check to see if we are using HA specific SP for a HA enabled server */
exec @retstat = sp_ha_check_certified 'sp_update_authmech_value',
                        @HA_CERTIFIED
if (@retstat != 0)
        return (1)

/*
** Do not allow this system procedure to be run from within a transaction
** to avoid creating a multi-database transaction where the 'master'
** database is not the co-ordinating database.
*/
if @@trancount > 0
begin
        /* 17260, "Can't run %1! from within a transaction." */
        raiserror 17260, "sp_update_authmech_value"
        return (1)
end
else
begin
        set chained off
end

set transaction isolation level 1

/*
** Check for the version of ASE on which this procedure is getting executed.
** Procedure should be executed only on 12.5.4 or 15.0.2 servers where an
** update to status is required.
*/
if (((@@version_as_integer = 12500) AND (@@version_number < 12540)) OR
    ((@@version_as_integer = 15000) AND (@@version_number < 15020)) OR
     (@@version_as_integer < 12500))
begin
        /*
        ** 19882, "sp_update_authmech_value should not be executed on this
        ** release of Adaptive Server, no changes made."
        */
        raiserror 19882
        return (1)
end

/*
** Check if user has sso role, proc_role will also do auditing
** if required. proc_role will also print error message if required.
*/
if (proc_role("sso_role") = 0)
        return (1)


        if (@nHARSTClass = 1)
        begin
                begin tran ha_dynsyn

                exec @rtn_code = sp_halockclustertables "sp_update_authmech_value"
                if (@rtn_code != 0)
                        goto clean_all
        end


/* Obtain the authentication mask value from master.dbo.spt_values */
select @auth_mask = low from master.dbo.spt_values
        where type = 'ua' and name = 'AUTH_MASK'

/* Obtain bitmask for ASE, LDAP, PAM bits */
select @auth_1253_all = (select low from master.dbo.spt_values
                                where name = 'ASE') |
                        (select low from master.dbo.spt_values
                                where name = 'LDAP') |
                        (select low from master.dbo.spt_values
                                where name = 'PAM')

/*
** Update all the master.dbo.syslogins row to unset the authentication
** mechanism bits where the status has value of 224 i.e ASE, LDAP and PAM
** bits set which indicated 'ANY' authentication mechanism in pre 12.5.4
** versions.
*/
update master.dbo.syslogins set status = status & ~@auth_mask
        where ((status & @auth_1253_all) = @auth_1253_all)

select @prisavedupdatecount = @@rowcount


        if (@@error != 0)
                goto clean_all
        if (@nHARSTClass = 1)
        begin
                update master.dbo.rmt_ha_syslogins
                        set status = status & ~@auth_mask
                        where ((status & @auth_1253_all) = @auth_1253_all)

		select @cmpsavedupdatecount = @@rowcount

                /*
                ** Print number of rows updated on both primary and
                ** companion server
                */
		/*
                ** 19883, "Updated authentication mechanism for %1! row(s)
                ** on %2! server."
                */
                exec sp_getmessage 19883, @msg output
                print @msg, @prisavedupdatecount, @@servername
                print @msg, @cmpsavedupdatecount, @@hacmpservername

        if (@@error != 0)
                goto clean_all
        else
                commit tran ha_dynsyn
        end

return (0)

clean_all:

        if (@nHARSTClass = 1)
                rollback tran ha_dynsyn

        return (1)
go
exec sp_procxmode 'sp_update_authmech_value', 'anymode'
go
grant execute on sp_update_authmech_value to public
go
dump tran master with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_attrib_notify')
begin
	drop procedure sp_attrib_notify
end
go
print "Installing sp_attrib_notify"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_rmt_adhoc_update')
begin
	drop procedure sp_rmt_adhoc_update
end
go
print "Installing sp_rmt_adhoc_update"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */

/* This is a wrapper stored procedure for built_in function attrib_notify() */
create procedure sp_attrib_notify
@class_id smallint,
@attrib_id smallint,
@object_type varchar(3),
@object_id int,
@object_info1 int,
@object_info2 int,
@object_info3 int,
@object_cinfo varchar (255),
@int_value int,
@char_value varchar (50),
@text_value varchar (50),
@image_value varbinary(50),
@comments varchar (50),
@action smallint
as
declare @rtn_code smallint
select @rtn_code = 0

select @rtn_code = attrib_notify (@class_id, @attrib_id, @object_type,
				@object_id, @object_info1, @object_info2,
				@object_info3, @object_cinfo, @int_value,
				@char_value, @text_value, @image_value,
				@comments, @action)
if (@rtn_code = 1)
	return (0)
else
	return (1) 
go


/* 
** This procedure allows other HA SPs to perform adhoc updates to system tables
** when the HA server is in SSM. The @token parameter determines what action
** should be taken and future uses of this SP should ensure that this is set
** correctly by the caller.
*/

create procedure sp_rmt_adhoc_update
@param1 smallint,
@param2 varchar(100),
@token  smallint
as

declare @srvclass smallint
declare @srvname varchar(30)

select @srvclass = @param1
select @srvname = convert(varchar(30), @param2)

if @token = 1	/* update srvclass in sysservers */
begin
	update master.dbo.sysservers set srvclass = @srvclass 
		where srvname = @srvname
	if @@error != 0
		return (1)
end

return (0)
go
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpvalidatecfg')
begin
	drop procedure sp_hacmpvalidatecfg
end
go
print "Installing sp_hacmpvalidatecfg"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpcheckcfg')
begin
	drop procedure sp_hacmpcheckcfg
end
go
print "Installing sp_hacmpcheckcfg"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */

/*
** SP_HACMPVALIDATECFG:
**
** Description:
*	This is a common procedure that process the local and remote
** values for an attribute in question. Based on the supplied parameters
** it will generate the advisory and, if instructed it will log an advisory
** record for this attribute. This function should be used primarily for
** processing the values derived from SYSCONFIGURES of the local and remote
** server.
**
** Design:
**	Local server is at a state where flexibility exists. So all checks
** should be to make local as compatible as possible with the remote values.
**
** Parameters:
**		@attrib_name: 		Name of the attribute instance - Input
**		@attrib_id: 		Id of the Base attribute       - Input
**		@val_type: 		Type of the attribute instance - Input
**		@advisory: 		Advisory to be logged          - Input
**		@comparator		Comparison type		       - Input
**		@ref_value		Reference value to compare     - Input
**		@check_only: 		Is it for Check only	       - Input
**		@skip_error: 		Skip validation on error       - Input
**		@comment:		Comment to be logged in Log    - Input
**
**
**	The comparator accepts currently 3 values. ( 0, 1, 2, 3)
**		COMPARATOR = 0
**			In this case, the local value and remote values
**			are compared. If a reference value is passed in
**			the local and remote should match to that value
**			else an advisory record is logged.
**
**		COMPARATOR = 1
**			In this case if the reference values is passed
**			the remote or local should have this value as
**			minimum. The remote should always have equal
**			or lesser than the local node value.
**
**		COMPARATOR = 2
**			Same as above, but the remote should have equal
**			or greater than value  wrt to local
**
**		COMPARATOR = 3
**			In this case the remote value is checked for
**			EQUAL or GREATER than the local value, only if
**			the local value != 0.
**
** Returns:
**		0 on success, else (failure) 1 
** 
**
*/
create procedure sp_hacmpvalidatecfg
@attrib_name varchar(255),
@attrib_id int,
@val_type varchar (20),
@advisory int,
@comparator int,
@ref_value int,
@check_only int,
@skip_error int,
@comment varchar(128) = "null"
as
declare 
	@attrib_type varchar(32),
	@computed_advisory int,
	@lattrintval int,
	@rattrintval int,
	@retstat int,
	@logrecord int,
	@lattrcharval varchar(128),
	@rattrcharval varchar(128)

begin
	/* Initialize the Defaults */
	select 	@lattrintval = 0,  
		@rattrintval = 0, 
		@lattrcharval = NULL, 
		@rattrcharval = NULL,
		@computed_advisory = 0, 
		@retstat = 0, 
		@logrecord = 0

	/* Check if trace 2202 is on; or Check only is on, log the record. */	
	dbcc istraceon(2202)
	if @@error != -1 
	begin
		select @logrecord = 1
	end

	/* Validate Attribute Id */
	if @attrib_id = 0 or @attrib_id < 1000
	begin
		print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
		return (1)
	end

	/* Get the attribute type based on the attribure id */
	select @attrib_type = attrib_type from tempdb.dbo.ha_advisory_attrs 
				 where attrib_id = @attrib_id

	/*
	** All the attribute names must be valid. If some one sends an
	** erroneous msg, just print it.
	*/
	if not exists ( select 1 from master.dbo.sysconfigures where
				name = @attrib_name)
	begin
		print "Int Error: Invalid Attribute name '%1!', ID = '%2!'",
				@attrib_name, @attrib_id
	end

	/* Get the local and remote Values */
	if @val_type = "INT"
	begin
		select @lattrintval = a.value, @rattrintval = b.value from 
				master.dbo.sysconfigures a, 
				master.dbo.rmt_ha_sysconfigures b where
				a.name = @attrib_name and
				b.name = @attrib_name 
		if @@error != 0
			return(1)
	end
	else
	begin
		select @lattrcharval = a.value2, @rattrcharval = b.value2 from 
				master.dbo.sysconfigures a, 
				master.dbo.rmt_ha_sysconfigures b where
				a.name = @attrib_name and
				b.name = @attrib_name 
		if @@error != 0
			return(1)

	end
	/* Determine the Advisory */
	if (@val_type = "INT")
	begin
		/* If same values have to be set in local and remote */
		if (@comparator = 0)	
		begin
			/* Check if the value has to be a preset_value */
			if (@ref_value != -1)
			begin
				if @lattrintval != @ref_value or
					@rattrintval != @ref_value
				begin
					select @computed_advisory = @advisory 
					select @logrecord = 1
				end
			end
			else
			begin
				if @lattrintval != @rattrintval
				begin
					select @computed_advisory = @advisory 
					select @logrecord = 1
				end
			end
		end

		/* If the remote value has to be greater than or equal */
		if (@comparator = 1 or @comparator = 2)
		begin
			/* Check if there is a default minimum value */
			if (@ref_value != -1)
			begin
				if @lattrintval < @ref_value
				begin
					select @computed_advisory = @advisory 
					select @logrecord = 1
				end
			end
			
			if (@comparator = 1 and  @lattrintval < @rattrintval)
			  or (@comparator = 2 and @lattrintval > @rattrintval) 
			begin 
				select @computed_advisory = @advisory 
				select @logrecord = 1
			end
		end

		/* 
		** If the value is set in the remote server (i.e != 0), it 
		** should also be set in the local to exactly the same value.
		** In all other cases, its a no fault
		*/
		if (@comparator = 3)
		begin
			if  @rattrintval != 0 
			begin
				if  @rattrintval !=  @lattrintval
				begin
					select @computed_advisory = @advisory 
					select @logrecord = 1
				end
			end
		end	
				
	end 

	if (@val_type = "CHAR" and @lattrcharval != @rattrcharval)
	begin
		select @computed_advisory = @advisory 
		select @logrecord = 1
	end

	/* Log a record if check only */
	if @logrecord = 1
	begin
		if @val_type = "INT"
		begin
			exec @retstat = sp_ha_logadvisory_rec @attrib_name, 
					@attrib_type, @attrib_id, NULL, NULL,
					@lattrintval, NULL, @rattrintval, 
					@computed_advisory, @comment
			if @retstat != 0
				return (1)
		end

		if @val_type = "CHAR"
		begin
			exec @retstat = sp_ha_logadvisory_rec @attrib_name, 
					@attrib_type, @attrib_id, NULL, 
					@lattrcharval, 0,  @rattrcharval, 0,  
					@computed_advisory, @comment 
			if @retstat != 0
				return (1)
		end
	end
	
	/* Check only or the computed advisory is zero, just return */
	if @check_only = 1 or @computed_advisory = 0
		return (0)

	/* If skip on error, simply return 0 else return 1 */ 
	if @skip_error = 1
		return (0)
	else
		return (1)
end
go

/*
** SP_HACMPCHECKCFG
**
** Description:
** 	This stored procedure verifies that configurations of the
** local server with respects to remote server for compatiblity
** and reports descripencies if any.
**
** Purpose:
**
** 	Here All the server configurations are examined wrt to companion
** server and any descripencies are logged according to the severity
** of the descripency
**
** Parameters:
**		@servername	: Name of the Companion server -- Input
**		@skip_error	: Skip on encountering an error-- Input
**		@check_only	: Check only 		       -- Input
**		@servername	: Attribute ID 		       -- Input
** Design: 
**
** 	All of the configuration values are checked against the
** sysconfigures not syscurconfigures. If a config parameter is dynamic
** and has been changed, its config value would also have changed. So
** it sufficient to make compatibility checks at the sysconfigures level.
** Based on the attribute pre determine what the advisory is going to be
** in case the validation fails. 
** 
** Error Messages:
**
** Returns:
**		0 on success, 1 on failure.
*/

create procedure sp_hacmpcheckcfg
@servername varchar(30)  = null,	/* Name of the primary server */
@skip_error int,			/* Skip the check on error */
@check_only int,			/* Check only */	
@attrib_id  int,			/* attribute Id of interest */
@option	    int 			/* Additional option */
as
declare 
	@retstat   int,			/* return value of executing a SQL */
	@id int,			/* Id */
	@comparator int,		/* Comparison type for INT values */
	@refvalue   int,		/* Reference for INT comparison */
	@cmpstate  int,			/* Companion server state */
	@sybstmdbid int,		/* Database id */
	@advisory int,			/* Advisory for the attribute */
	@attrib_name varchar(255),	/* Attribute name */
	@type varchar(20),		/* Value type for attribute */
	@localservername varchar(32),	/* Local server name */
	@attrib_type varchar(32), 	/* attribute type */
	@devices int,			/* number of rows in local sysdevices */
	@rmt_devices int,		/* number of rows in rmt sysdevices */
	@pci_enabled int		/* PCI enabled on local server */

/* 17260, "Can't run %1! from within a transaction." */
if @@trancount != 0
begin
	raiserror 17260, "sp_hacmpcheckcfg"
	return (1)
end

/* Initialize the defaults */
select @retstat = 0, @localservername = @@servername

dbcc istraceon(2227)
if @@error != -1
begin
	print "Proc name = '%1!'", "sp_hacmpcheckcfg" 
	print "Servername Id = '%1!'", @servername
	print "Attribute Id = '%1!'", @attrib_id
end

/* Check for valid Base attribute Id */
if @attrib_id != 0
begin
	if not exists (select 1 from tempdb.dbo.ha_advisory_attrs where
				attrib_id = @attrib_id and @attrib_id > 999)
	begin
		print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
		return(1)
	end
end

set nocount on

/*
** CIS Configuration. 
*/
if (@attrib_id = 1100)
begin
	/*
	** 'enable cis', This parameter should allways be set
	** in both the primary and in secondary, else it is 
	** a HARD fault. Comparator = 0 and Reference = 1
	*/
	select @advisory = 2,  @id = 1100, @type = "INT" ,
			@attrib_name = "enable cis", @comparator = 0,
			@refvalue = 1
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'cis packet size'. This has to be exactly be same on both
	** the nodes. There is no default for this any way.
	*/
	select @advisory = 2,  @id = 1100, @type = "INT" ,
			@attrib_name = "cis packet size", @comparator = 0,
			@refvalue = -1
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'cis rpc handling. This should be same on both the nodes.
	*/
	select @advisory = 2,  @id = 1100, @type = "INT" ,
			@attrib_name = "cis rpc handling", @comparator = 0,
			@refvalue = -1
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, @check_only, 
			@skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'max cis remote connections'. This value should be atleast
	** be default > 2 and be greater than or equal to remote node
	*/
	select @advisory = 2,  @id = 1100, @type = "INT" ,
			@attrib_name = "max cis remote connections", 
			@comparator = 1, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'enable file access'. This value should be same
	** on remote node
	*/
	select @advisory = 2,  @id = 1100, @type = "INT" ,
			@attrib_name = "enable file access",
			@comparator = 2, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'bulk insert array size'. This value should be same
	** on remote node
	*/
	select @advisory = 2,  @id = 1100, @type = "INT" ,
			@attrib_name = "cis bulk insert array size",
			@comparator = 0, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'enable full text search'. This value should be same
	** on remote node
	*/
	select @advisory = 2,  @id = 1100, @type = "INT" ,
			@attrib_name = "enable full-text search",
			@comparator = 2, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/* END NON QUORAM ATTRIBUTES */
end

/*
** General Configuration
*/
if (@attrib_id = 1110)
begin
		
	/* BEGIN NON QUORAM ATTRIBUTES */ 
	if @option != 1
	begin 
		/*
		** 'lock scheme'. We would ideally  require that this 
		** parameter be same in remote node. 
		*/
		select @advisory = 1,  @id = 1110, @type = "CHAR" ,
			@attrib_name = "lock scheme", 
			@comparator = 0, @refvalue = -1

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** 'number of alarms'
		*/
		select @advisory = 1,  @id = 1110, @type = "INT" ,
			@attrib_name = "number of alarms", 
			@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** 'disable sort merge join'
		*/
		select @advisory = 1,  @id = 1110, @type = "INT" ,
			@attrib_name = "enable sort-merge join and JTC", 
			@comparator = 0, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		/*
		** 'number of locks'. We would ideally  require that this 
		** parameter be same or greater in remote node. 
		*/
		select @advisory = 1,  @id = 1110, @type = "INT" ,
			@attrib_name = "number of locks", 
			@comparator = 1, @refvalue = -1

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** 'lock wait period'. We would ideally  require that this 
		** parameter be same or greater in remote node. 
		*/
		select @advisory = 1,  @id = 1110, @type = "CHAR" ,
			@attrib_name = "lock wait period", 
			@comparator = 1, @refvalue = -1

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** number of open databases.
		*/
		select @advisory = 1,  @id = 1110, @type = "INT" ,
			@attrib_name = "number of open databases", 
			@comparator = 1, @refvalue = 7 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** number of open indexes.
		*/
		select @advisory = 1,  @id = 1110, @type = "INT" ,
			@attrib_name = "number of open indexes", 
			@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** number of open objects.
		*/
		select @advisory = 1,  @id = 1110, @type = "INT" ,
			@attrib_name = "number of open objects", 
			@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** 'number of user connections'
		*/
		select @advisory = 1,  @id = 1110, @type = "INT" ,
			@attrib_name = "number of user connections", 
			@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

	end /* END NON QUORAM ATTRIBUTES */

	/*
	** 'stack guard size'
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "stack guard size", 
			@comparator = 1, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'stack size'
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "stack size", 
			@comparator = 1, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'allow backward scans'
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "allow backward scans", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'allow nested triggers'
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "allow nested triggers", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'allow resource limits'
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "allow resource limits", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'cpu grace time'
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "cpu grace time", 
			@comparator = 1, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	
	/*
	** 'number of aux scan descriptor'
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "number of aux scan descriptors", 
			@comparator = 1, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'partition groups'
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "partition groups", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'size of auto identity columns'
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "size of auto identity column", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	
	/*
	** 'SQL Perfmon Integration'
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "SQL Perfmon Integration", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'cfg read committed with lock'
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "read committed with lock", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'memory alignment boundary'. We would enforce that this parameter 
	** be same on both the servers. For some hardware platforms they are 
	** hard coded so it better be the same.
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "memory alignment boundary", 
			@comparator = 0, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'enable rep agent threads'. We would enforce that this parameter
	** be same on both the servers.
	*/
	select @advisory = 2,  @id = 1110, @type = "INT" ,
			@attrib_name = "enable rep agent threads",
			@comparator = 0, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
end

/*
** DISK Configuration:
*/
if (@attrib_id = 1120)
begin
	/*
	** disable disk mirroring, ideal to have same values.
	*/
	select @advisory = 2,  @id = 1120, @type = "INT" ,
		@attrib_name = "disable disk mirroring",
		@comparator = 0, @refvalue = 1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
		@advisory, @comparator, @refvalue,
		@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/* BEGIN NON QUORAM ATTRIBUTES */
	if @option != 1
	begin
		/*
		** allow sql server async i/o, its a ideal to have same values.
		*/
		select @advisory = 1,  @id = 1120, @type = "INT" ,
			@attrib_name = "allow sql server async i/o",
			@comparator = 0, @refvalue = -1

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)


		/*
		** 'disk i/o structures. This should be ideally equl or greater
		** than the remote node
		*/
		select @advisory = 1,  @id = 1120, @type = "INT" ,
			@attrib_name = "disk i/o structures", 
			@comparator = 1, @refvalue = -1

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		
	end
	/* END NON QUORAM ATTRIBUTES */

	/*
	** 'number of devices. It should be at the minimum sum of the number
	** of physical disks on the local and remote servers.
	*/
	select @devices = count(*) from master.dbo.sysdevices 
		where status & 2 != 0
	select @rmt_devices = count(*) from master.dbo.rmt_ha_sysdevices 
		where status & 2 != 0

	select @advisory = 2,  @id = 1120, @type = "INT" ,
			@attrib_name = "number of devices", 
			@comparator = 1, @refvalue = (@devices + @rmt_devices)	

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
end

/*
** Event Handling.
*/
if (@attrib_id = 1140)
begin
	/* BEGIN NON QUORAM ATTRIBUTE */
	if @option != 1
	begin
		/*
		** Event handling. If enabled in primary, enable in secondary
		*/
		select @advisory = 1,  @id = 1140, @type = "INT" ,
			@attrib_name = "event logging", 
			@comparator = 3, @refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** event log computer name. It should be ideally be same
		*/	
		select @advisory = 1,  @id = 1140, @type = "CHAR" ,
			@attrib_name = "event log computer name", 
			@comparator = 0, @refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** 'log audit logon failure', should be enabled in both
		*/
		select @advisory = 1,  @id = 1140, @type = "INT" ,
			@attrib_name = "log audit logon failure", 
			@comparator = 3, @refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** 'log audit logon success', should be enabled in both
		*/
		select @advisory = 1,  @id = 1140, @type = "INT" ,
			@attrib_name = "log audit logon success", 
			@comparator = 3, @refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

	end
	/* END NON QUORAM ATTRIBUTE */

end

/*
** Extended stored procedures, configuration
*/
if (@attrib_id = 1150)
begin
	/*
	** 'esp execution stack size'. This has to be atleast equal
	** or greater than the remote node.
	*/
	select @advisory = 2,  @id = 1150, @type = "INT" ,
			@attrib_name = "esp execution stacksize", 
			@comparator = 1, @refvalue = -1
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'start mail session'. This has to same in remote node.
	*/
	select @advisory = 2,  @id = 1150, @type = "INT" ,
			@attrib_name = "start mail session", 
			@comparator = 0, @refvalue = -1
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'xp_cmdshell context'. This has to same in remote node.
	*/
	select @advisory = 2,  @id = 1150, @type = "INT" ,
			@attrib_name = "xp_cmdshell context", 
			@comparator = 0, @refvalue = -1
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

end

/*
** Languages, charsets and sortorder configuration
*/
if (@attrib_id = 1130)
begin
	/*
	** default character set id, this should be same.
	*/
	select @advisory = 2,  @id = 1130, @type = "INT" ,
			@attrib_name = "default character set id",
			@comparator = 0, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue, 
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** default language id, this should be same.
	*/
	select @advisory = 2,  @id = 1130, @type = "INT" ,
			@attrib_name = "default language id",
			@comparator = 0, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'default sortorder' id should be same in both the nodes
	*/
	select @advisory = 2,  @id = 1130, @type = "INT" ,
			@attrib_name = "default sortorder id",
			@comparator = 0, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'disable chracter set conversions'. This should be same.
	*/
	select @advisory = 2,  @id = 1130, @type = "INT" ,
			@attrib_name = "disable character set conversions",
			@comparator = 0, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
end

/*
** Handle JAVA related configuration parameters.
*/
if (@attrib_id = 1160)
begin
	/*
	** 'enable java'
	*/
	select @advisory = 2,  @id = 1160, @type = "INT" ,
			@attrib_name = "enable java", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** if PCI is NOT enabled then we need to check the config props
	** associated with Kona
	*/
	select @pci_enabled = value from master.dbo.sysconfigures
			where name = 'enable pci'
	if ( @pci_enabled = 0 )
	begin
		/*
		** 'size of process object heap'
		*/
		select @advisory = 2,  @id = 1160, @type = "INT" ,
				@attrib_name = "size of process object heap", 
				@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
				@advisory, @comparator, @refvalue,
				@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		/*
		** 'size of shared class heap'
		*/
		select @advisory = 2,  @id = 1160, @type = "INT" ,
				@attrib_name = "size of shared class heap", 
				@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
				@advisory, @comparator, @refvalue,
				@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		/*
		** 'size of global fixed heap'
		*/
		select @advisory = 2,  @id = 1160, @type = "INT" ,
				@attrib_name = "size of global fixed heap", 
				@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
				@advisory, @comparator, @refvalue,
				@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** BEGIN NON-QUORAM ATTRIBUTES
		*/
		if @option != 1
		begin

		/*
		** 'number of java sockets'
		*/
		select @advisory = 1,  @id = 1160, @type = "INT" ,
				@attrib_name = "number of java sockets",
				@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
				@advisory, @comparator, @refvalue,
				@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		end
		/*
		** END NON QUORAM ATTRIBUTES
		*/
	end
	/*
	** END KONA ONLY ATTRIBUTES
	*/
end

/*
** Handle DTM related config parameters.
*/
if (@attrib_id = 1170)
begin
	/*
	** 'enable DTM'
	*/
	select @advisory = 2,  @id = 1170, @type = "INT" ,
			@attrib_name = "enable DTM", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'number of dtx participants'
	*/
	select @advisory = 2,  @id = 1170, @type = "INT" ,
			@attrib_name = "number of dtx participants", 
			@comparator = 1, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'strict dtm enforcement'
	*/
	select @advisory = 2,  @id = 1170, @type = "INT" ,
			@attrib_name = "strict dtm enforcement", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** BEGIN NON QUORAM ATTRIBUTES
	*/
	if @option != 1
	begin
		/*
		** 'xact coordination interval'
		*/
		select @advisory = 1,  @id = 1170, @type = "INT" ,
			@attrib_name = "xact coordination interval", 
			@comparator = 2, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** 'dtm lock timeout period'
		*/
		select @advisory = 1,  @id = 1170, @type = "INT" ,
			@attrib_name = "dtm lock timeout period", 
			@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
	end
	/* END NON QUORAM ATTRIBUTES */
end

/*
** Monitoring 
*/
if (@attrib_id = 1180)
begin
	
	/*
	** 'enable monitoring'
	*/
	select @advisory = 2,  @id = 1180, @type = "INT" ,
			@attrib_name = "enable monitoring", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'sql text pipe active should be same'
	*/
	select @advisory = 2,  @id = 1180, @type = "INT" ,
			@attrib_name = "sql text pipe active", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'plan text pipe active should be same'
	*/
	select @advisory = 2,  @id = 1180, @type = "INT" ,
			@attrib_name = "plan text pipe active", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** ' statement pipe active should be same'
	*/
	select @advisory = 2,  @id = 1180, @type = "INT" ,
			@attrib_name = "statement pipe active", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** ' errorlog pipe active be same'
	*/
	select @advisory = 2,  @id = 1180, @type = "INT" ,
			@attrib_name = "errorlog pipe active", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** ' deadlock pipe be same'
	*/
	select @advisory = 2,  @id = 1180, @type = "INT" ,
			@attrib_name = "deadlock pipe active", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** ' wait event timing'
	*/
	select @advisory = 2,  @id = 1180, @type = "INT" ,
			@attrib_name = "wait event timing", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'process waitevents'
	*/
	select @advisory = 2,  @id = 1180, @type = "INT" ,
			@attrib_name = "process wait events", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'object lockwait timing'
	*/
	select @advisory = 2,  @id = 1180, @type = "INT" ,
			@attrib_name = "object lockwait timing", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'SQL batch capture'
	*/
	select @advisory = 2,  @id = 1180, @type = "INT" ,
			@attrib_name = "SQL batch capture", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'statement statistcis active'
	*/
	select @advisory = 2,  @id = 1180, @type = "INT" ,
			@attrib_name = "statement statistics active", 
			@comparator = 3, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
end

/*
** Network Related configuration parameters 
*/
if (@attrib_id = 1190)
begin
	/*
	** 'allow remote access'
	*/
	select @advisory = 2,  @id = 1190, @type = "INT" ,
			@attrib_name = "allow remote access", 
			@comparator = 0, @refvalue = 1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'default network packet size'
	*/
	select @advisory = 2,  @id = 1190, @type = "INT" ,
			@attrib_name = "default network packet size", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'max network packet size'
	*/
	select @advisory = 2,  @id = 1190, @type = "INT" ,
			@attrib_name = "max network packet size", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'number of remote sites'
	*/
	select @advisory = 2,  @id = 1190, @type = "INT" ,
			@attrib_name = "number of remote sites", 
			@comparator = 1, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** BEGIN NON QUORAM ATTRIBUTES
	*/
	if @option != 1
	begin

		/*
		** 'number of remote connections'
		*/
		select @advisory = 1,  @id = 1190, @type = "INT" ,
			@attrib_name = "number of remote connections", 
			@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		/*
		** 'number of remote logins'
		*/
		select @advisory = 1,  @id = 1190, @type = "INT" ,
			@attrib_name = "number of remote logins", 
			@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		
		/*
		** 'max number network listeners'
		*/
		select @advisory = 1,  @id = 1190, @type = "INT" ,
			@attrib_name = "max number network listeners",
			@comparator = 1, @refvalue = -1
		
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		
	end
	/* END NON QUORAM ATTRIBUTES */
end

/*
** Parallel configuration parameters. 
** If the primary is configured, we will evaluate it against
** the secondary. If primary is not configured, but secondary
** is, the we will just ignore the secondary configuration. 
*/
if (@attrib_id = 1200)
begin
	/*
	** 'memory per worker process'. If there has been a specific
	** configuration based in some assumption in primary we do 
	** not want it to break on fail-over.
	*/
	select @advisory = 2,  @id = 1200, @type = "INT" ,
			@attrib_name = "memory per worker process", 
			@comparator = 1, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'max parallel degree'. If primary is configured with
	** a specific value, that means, the application has been
	** coded to do so, hence we do not want it to break.
	*/
	select @advisory = 2,  @id = 1200, @type = "INT" ,
			@attrib_name = "max parallel degree", 
			@comparator = 1, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** BEGIN NON QUORAM ATTRIBUTES 
	*/
	if @option != 1
	begin
	
		/*
		** 'number of worker processes'. If the available number
		** of process is less, it will perform poorly. The validity
		** max-parallel degree and the number of worker process
		** is checked by defalt by server, hence no need. 
		*/
		select @advisory = 1,  @id = 1200, @type = "INT" ,
			@attrib_name = "number of worker processes", 
			@comparator = 3, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		/*
		** 'max scan parallel degree'. If the values are not same, at
		** most it will perform slower, but application will not break
		** 
		*/
		select @advisory = 1,  @id = 1200, @type = "INT" ,
			@attrib_name = "max scan parallel degree", 
			@comparator = 1, @refvalue = -1 

		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
		return(1)
	end
	/* END NON QUORAM ATTRIBUTES */
end

/*
** Security related configuration parameters.
** All of the security related configurations should be matching
** in the cluster domain. 
*/
if (@attrib_id = 1210)
begin
	/*
	** 'auditing', if the auditing is enabled in one, it should be
	** on in the secondary server as well. Remember that users can
	** access the data through the secondary via proxy db.
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "auditing", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'allow procedure grouping'
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "allow procedure grouping", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'secure default login'
	*/
	select @advisory = 2,  @id = 1210, @type = "CHAR" ,
			@attrib_name = "secure default login", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'systemwide password expiration'
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "systemwide password expiration", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'use security services'
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "use security services", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'unified login required'
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "unified login required", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'check password for digit'
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "check password for digit", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'enable row level access'
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "enable row level access",
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'enable ssl'
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "enable ssl",
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'minimum password length'
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "minimum password length", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'maximum failed logins'
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "maximum failed logins", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'msg confidentiality reqd'
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "msg confidentiality reqd",
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'msg integrity reqd'
	*/
	select @advisory = 2,  @id = 1210, @type = "INT" ,
			@attrib_name = "msg integrity reqd",
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	
	/*
	** select on syscomments.text
	*/
	select @advisory = 2, @id = 1210, @type = "INT" ,
		@attrib_name = "select on syscomments.text",
		@comparator = 0, @refvalue = -1
	
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
		@advisory, @comparator, @refvalue,
		@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/* Get the attribute type based on the attribure id */
	select @attrib_type = attrib_type from tempdb.dbo.ha_advisory_attrs
					where attrib_id = @attrib_id
	select @attrib_name = "Missing sybsecurity"


	/* 
	** If the remote server has 'sybsecurity' installed, the local server
	** should be configured for security, else it is a fatal error.
	*/
	if exists (select 1 from master.dbo.rmt_ha_sysdatabases 
			where name = "sybsecurity")
	begin
		if not exists ( select 1 from master.dbo.sysdatabases
			where name = "sybsecurity")
		begin
			exec @retstat = sp_ha_logadvisory_rec 
				@attrib_name, @attrib_type, @attrib_id,
				NULL, "null", 0,  "sybsecurity", 0, 2

			if ((@retstat != 0) or (@@error != 0))
			return(1)
		end
		else
		/* If the debug trace is on, log anyway */
		dbcc istraceon(2202)
		if @@error != -1 
		begin
			exec @retstat = sp_ha_logadvisory_rec 
				@attrib_name, @attrib_type, @attrib_id,
				NULL, "sybsecurity", 0,  "sybsecurity",
				0, 0
		end	
	end
	else
	begin
		/* If the debug trace is on, log anyway */
		dbcc istraceon(2202)
		if @@error != -1 
		begin
			exec @retstat = sp_ha_logadvisory_rec 
				@attrib_name, @attrib_type, @attrib_id,
				NULL, "sybsecurity", 0,  "sybsecurity",
				0, 0
		end	
	end
end
/*
** Handle Unicode related config parameters.
*/
if (@attrib_id = 1220)
begin
	/*
	** 'enable unicode conversions'
	*/
	select @advisory = 2,  @id = 1220, @type = "INT" ,
			@attrib_name = "enable unicode conversions",
			@comparator = 0, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'enable unicode normalization'
	*/
	select @advisory = 2,  @id = 1220, @type = "INT" ,
			@attrib_name = "enable unicode normalization",
			@comparator = 0, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'enable surrogate processing'
	*/
	select @advisory = 2,  @id = 1220, @type = "INT",
			@attrib_name = "enable surrogate processing",
			@comparator = 0, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	
	/* 
	** BEGIN NON-QUORAM ATTRIBUTES 
	*/
	if @option != 1
	begin
	/*
	** 'size of unilib cache'
	*/
	select @advisory = 1,  @id = 1220, @type = "INT",
			@attrib_name = "size of unilib cache",
			@comparator = 1, @refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	end
	/* END NON QUORAM ATTRIBUTES */
end

/*
** Handle physical memory requirements
*/

if (@attrib_id = 1230) 
begin
	/*
	** 'heap memory per user'
	*/
	select @advisory = 2,  @id = 1230, @type = "INT" ,
		@attrib_name = "heap memory per user", @comparator = 2,
		@refvalue = -1
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
		@advisory, @comparator, @refvalue,
		@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
end

/*
** Handle SQL Server Administration
*/
if (@attrib_id = 1250)
begin
	/*
	** 'number of mailboxes'
	*/
	select @advisory = 2,  @id = 1250, @type = "INT" ,
		@attrib_name = "number of mailboxes", @comparator = 1,
		@refvalue = -1

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
		@advisory, @comparator, @refvalue,
		@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'size of auto identity column'
	*/
	select @advisory = 2,  @id = 1250, @type = "INT" ,
		@attrib_name = "size of auto identity column", @comparator = 2,
		@refvalue = -1
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
		@advisory, @comparator, @refvalue,
		@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'allow resource limits'
	*/
	select @advisory = 2,  @id = 1250, @type = "INT" ,
		@attrib_name = "allow resource limits", @comparator = 2,
		@refvalue = -1
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
		@advisory, @comparator, @refvalue,
		@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	/*
	** 'abstract plan load'
	*/
	select @advisory = 2,  @id = 1250, @type = "INT" ,
		@attrib_name = "abstract plan load", @comparator = 2,
		@refvalue = -1
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
		@advisory, @comparator, @refvalue,
		@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'enable pci'
	*/
	select @advisory = 2,  @id = 1250, @type = "INT" ,
			@attrib_name = "enable pci", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'pci memory size'
	*/
	select @advisory = 2,  @id = 1250, @type = "INT" ,
			@attrib_name = "pci memory size", 
			@comparator = 2, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'max pci slots'
	*/
	select @advisory = 2,  @id = 1250, @type = "INT" ,
			@attrib_name = "max pci slots", 
			@comparator = 2, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** 'enable job scheduler'
	*/
	select @advisory = 2,  @id = 1250, @type = "INT" ,
			@attrib_name = "enable job scheduler", 
			@comparator = 0, @refvalue = -1 

	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type, 
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/*
	** BEGIN NON-QUORAM ATTRIBUTES
	*/
	if @option != 1
	begin
		/*
		** 'procedure cache size'
		*/
		select @advisory = 1,  @id = 1250, @type = "INT" ,
			@attrib_name = "procedure cache size", @comparator = 1,
			@refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		
		/*
		** 'default database size'
		*/
		select @advisory = 1,  @id = 1250, @type = "INT" ,
			@attrib_name = "default database size", @comparator = 1,
			@refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)

		/*
		** 'number of messages'
		*/
		select @advisory = 1,  @id = 1250, @type = "INT" ,
			@attrib_name = "number of messages", @comparator = 1,
			@refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		/*
		** 'event buffers per engine'
		*/
		select @advisory = 1,  @id = 1250, @type = "INT" ,
			@attrib_name = "event buffers per engine", @comparator = 1,
			@refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		/*
		** 'time slice'
		*/
		select @advisory = 1,  @id = 1250, @type = "INT" ,
			@attrib_name = "time slice", @comparator = 1,
			@refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		/*
		** 'sort buffers'
		*/
		select @advisory = 1,  @id = 1250, @type = "INT" ,
			@attrib_name = "number of sort buffers", @comparator = 1,
			@refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		/*
		** 'abstract plan dump'
		*/
		select @advisory = 1,  @id = 1250, @type = "INT" ,
			@attrib_name = "abstract plan dump", @comparator = 2,
			@refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		/*
		** 'abstract plan cache'
		*/
		select @advisory = 1,  @id = 1250, @type = "INT" ,
			@attrib_name = "abstract plan cache", @comparator = 0,
			@refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
		/*
		** 'text prefetch size'
		*/
		select @advisory = 1,  @id = 1250, @type = "INT" ,
			@attrib_name = "text prefetch size", @comparator = 1,
			@refvalue = -1
		exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
			@advisory, @comparator, @refvalue,
			@check_only, @skip_error
		if ((@retstat != 0) or (@@error != 0))
			return(1)
	end
	/* END NON QUORAM ATTRIBUTES */
end
/*
** Handle User environment
*/
if (@attrib_id = 1260)
begin

	/*
	** 'permission cache entries'
	*/
	select @advisory = 2,  @id = 1250, @type = "INT" ,
		@attrib_name = "permission cache entries", @comparator = 1,
		@refvalue = -1
	exec @retstat = sp_hacmpvalidatecfg @attrib_name, @id, @type,
		@advisory, @comparator, @refvalue,
		@check_only, @skip_error
	if ((@retstat != 0) or (@@error != 0))
		return(1)
end
set nocount off 
go
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_haproxydbspace')
begin
	drop procedure sp_haproxydbspace
end
go
print "Installing sp_haproxydbspace"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_numrows_usedpgs')
begin
	drop procedure sp_ha_numrows_usedpgs
end
go
print "Installing sp_ha_numrows_usedpgs"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hatabspace')
begin
	drop procedure sp_hatabspace
end
go
print "Installing sp_hatabspace"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hamasterspace')
begin
	drop procedure sp_hamasterspace
end
go
print "Installing sp_hamasterspace"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_haspacereqd')
begin
	drop procedure sp_haspacereqd
end
go
print "Installing sp_haspacereqd"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */

/*
** SP_HAPROXYDBSPACE
** 
** Description:
** 	This stored procedure calculates the space required for creating the
** the proxy of the remote server's databases.
**
** Parameters:
**		@space_reqd: numeric(15,0)	-- Output
**
** Returns:
**	1 if failure
**	0 otherwise
*/
create procedure sp_haproxydbspace
@space_reqd numeric(15,0) output
as
begin
declare	@retstat int,
	@name char(30),
	@num int,
	@sp_reqd int,
	@mb_reqd int,
	@model_size int,
	@pages_per_mb int,
	@tempdb_mask   int

	set nocount on
	select @retstat = 0

	select @tempdb_mask = number
		from master.dbo.spt_values
		where type = "D3" and name = "TEMPDB STATUS MASK"

	/* determine number of pages per Megabyte */
	select @pages_per_mb = (1024 * 1024) / @@maxpagesize

	create table #ha__spacetable(cnt int)

	/* 
	** System databases, user temporary databases and archive databases
	** do not have corresponding HA proxy databases, so do not include 
	** them in space estimation.
	*/
	declare dbname_cursor cursor for
	select name from master.dbo.sysdatabases
	where name not in ('master', 'model', 'tempdb', 'sybsystemdb',
			   'sybsystemprocs', 'dbccdb', 'dbccalt', 'sybsecurity',
			   'sybsyntax', 'sybmgmtdb', 'sybpcidb')
		   and (status3 & (1 | 2 | 4 | 4194304 | @tempdb_mask)) = 0

	declare cnt_cursor cursor for
	select cnt from #ha__spacetable

	open dbname_cursor
	open cnt_cursor

	select @space_reqd = 0
	select @model_size = sum(size)
	from master.dbo.sysusages where dbid = db_id('model')

	fetch dbname_cursor into @name

	/*
	** Walk each user database and estimate the space needed to create proxy
	** for that database.
	*/
	while (@@sqlstatus = 0)
	begin
		exec(	"declare @i int select @i=count(*) from " +
			@name + 
			"..sysobjects where type in ('U', 'V') " +
			"insert into #ha__spacetable values(@i)")

		if (@@error != 0)
		begin
			select @retstat = 1
			goto finish
		end

		fetch cnt_cursor into @num

		/*
		** Calculate 1MB of space per 32 proxy tables, then
		** add the size of model, plus 1MB for good measure.
		*/
		select @mb_reqd = (@num / 32) + (@model_size / @pages_per_mb) + 1

		/*
		** Convert resulting MB into pages and add 512, for 'safety'
		*/
		select @sp_reqd = (@mb_reqd * @pages_per_mb) + 512

		select @space_reqd = @space_reqd + @sp_reqd
		fetch dbname_cursor into @name
	end

finish:
	close dbname_cursor
	close cnt_cursor
	deallocate cursor dbname_cursor
	deallocate cursor cnt_cursor

	drop table #ha__spacetable
	set nocount off
	return (@retstat)
end
go

/*
** SP_HA_NUMROWS_USEDPGS
** 
** Description:
** 	This stored procedure calculates the number of rows in a table given
** the table id and the number of pages occupied by that table.
**
** Parameters:
**		@tabid:		int	-- Input
**		@numrows:	int	-- Output
**		@space_used:	int	-- Output
** Returns:
**	1 if failure
**	0 otherwise
*/
create procedure sp_ha_numrows_usedpgs
@tabid int,
@numrows int output,
@space_used int output
as
begin
declare @name varchar(255),
	@retstat int

	set nocount on
	select @numrows = 0, @space_used = 0, @retstat = 0
	select @name = name from master.dbo.sysobjects where id = @tabid

	if @name != isnull(@name, "")
	begin
		return (@retstat)
	end

	create table #ha__numrows(numrows int)

	exec ("declare @nrows int select @nrows = count(*) from master.dbo."
		+ @name +" insert into #ha__numrows values (@nrows)")

	if (@@error != 0)
	begin
		select @retstat = 1
		goto finish
	end

	select @numrows = numrows from #ha__numrows
	select @space_used = data_pages(1, @tabid)

finish:
	drop table #ha__numrows
	set nocount off
	return (@retstat)
end
go

/*
** SP_HATABSPACE
** 
** Description:
** 	This stored procedure figures out the space required for synchronizing
** a table, given the number of rows on the remote/local server and the space
** used by the remote table.
**
** Parameters:
**		@sp_used:	int	-- Input
**		@lnumrows:	int	-- Input
**		@rnumrows:	int	-- Input
**		@sp_reqd:	int	-- Output
**
** Returns:
**	0 (success)
*/
create procedure sp_hatabspace 
@sp_used int,
@lnumrows int = 0,
@rnumrows int = 0,
@sp_reqd int output
as
begin
declare @numrows int

	set nocount on
	select @sp_reqd = 0

	if (@lnumrows < @rnumrows)
		select @numrows = @rnumrows - @lnumrows
	else
		select @numrows = @lnumrows - @rnumrows

	if ((@lnumrows = 0) and (@rnumrows = 0))
	begin
		return 0
	end

	if (@rnumrows = 0)
		select @rnumrows = 1

	/* This gives the space need for the potential inserts */
	select @sp_reqd = (@sp_used * @numrows)/@rnumrows

	if (@sp_reqd = 0)
		select @sp_reqd = 1

	/* For a average number of potential updates */
	select @sp_reqd = @sp_reqd + (@sp_used * (@lnumrows/4))/@rnumrows

	/* For a rough estimation of log + data space needed */
	select @sp_reqd = @sp_reqd * 2 + @sp_reqd/10

	set nocount off
	return 0
end
go

/*
** SP_HAMASTERSPACE
** 
** Description:
** 	This stored procedure calculates the space required on the master for
** synchronization. It calculates the space required based on the average
** space used by a row for a given table on the remote server and the number
** of rows that need to be synchronized for that table. The number of rows 
** that need to be synchronized is estimated as the difference between the 
** number of rows on the remote and the local table plus 25% of the rows in the
** local table (are assumed to have an update).
**
** Parameters:
**		@space_reqd:	numeric(15,0)	-- Output
**		@space_avail:	numeric(15,0)	-- Output
**
** Returns:
**	1 if failure
**	0 otherwise
*/
create procedure sp_hamasterspace
@space_reqd numeric(15,0) output,
@space_avail numeric(15,0) output
as
begin
declare
	@tabid int,
	@sp_reqd numeric(15,0),
	@numrows int,
	@rnumrows int,
	@lnumrows int,
	@lstart int,
	@size int,
	@sp_used int,
	@unused_pgs int,
	@retstat int
	
	set nocount on
	select @space_reqd = 0, @rnumrows = 0, @lnumrows = 0, @sp_reqd = 0,
	       @retstat = 0
	create table #ha__tables_sync(tabid int, numrows int)

	/* Tables that need to be synchronized */
	select @lnumrows = count(*) from master.dbo.systypes
	insert into #ha__tables_sync
		values(object_id('master.dbo.systypes'), @lnumrows)
	select @lnumrows = count(*) from master.dbo.sysusers
	insert into #ha__tables_sync
		values(object_id('master.dbo.sysusers'), @lnumrows)
	select @lnumrows = count(*) from master.dbo.sysalternates
	insert into #ha__tables_sync
		values(object_id('master.dbo.sysalternates'), @lnumrows)
	select @lnumrows = count(*) from master.dbo.syslogins
	insert into #ha__tables_sync
		values(object_id('master.dbo.syslogins'), @lnumrows)
	select @lnumrows = count(*) from master.dbo.sysservers
	insert into #ha__tables_sync
		values(object_id('master.dbo.sysservers'), @lnumrows)
	select @lnumrows = count(*) from master.dbo.syslanguages
	insert into #ha__tables_sync
		values(object_id('master.dbo.syslanguages'), @lnumrows)
	select @lnumrows = count(*) from master.dbo.syscharsets
	insert into #ha__tables_sync
		values(object_id('master.dbo.syscharsets'), @lnumrows)
	select @lnumrows = count(*) from master.dbo.sysloginroles
	insert into #ha__tables_sync
		values(object_id('master.dbo.sysloginroles'), @lnumrows)
	select @lnumrows = count(*) from master.dbo.systimeranges
	insert into #ha__tables_sync
		values(object_id('master.dbo.systimeranges'), @lnumrows)
	select @lnumrows = count(*) from master.dbo.sysresourcelimits
	insert into #ha__tables_sync
		values(object_id('master.dbo.sysresourcelimits'), @lnumrows)

	declare tabid_cursor cursor for
	select tabid, numrows from #ha__tables_sync

	declare dbusage_cursor cursor for
	select lstart, size from master.dbo.sysusages where dbid = 1

	open dbusage_cursor
	open tabid_cursor
	fetch tabid_cursor into @tabid, @lnumrows

	/*
	** Calculate the total space needed for all the tables involved in 
	** synchronization.
	*/
	while (@@sqlstatus = 0)
	begin
		exec @retstat = SYB_HACMP.sybsystemprocs.dbo.sp_ha_numrows_usedpgs
				  @tabid, @rnumrows output, @sp_used output
		if @retstat != 0
			goto finish

		exec @retstat = sp_hatabspace @sp_used, @lnumrows, @rnumrows,
					@sp_reqd output
		if @retstat != 0
			goto finish

		select @space_reqd = @space_reqd + @sp_reqd

		fetch tabid_cursor into @tabid, @lnumrows
	end

	fetch dbusage_cursor into @lstart, @size
	select @unused_pgs = 0, @space_avail = 0

	/* Calculate the space available on master */
	while (@@sqlstatus = 0)
	begin
		select @unused_pgs = curunreservedpgs(1, @lstart, @size)
		select @space_avail = @space_avail + @unused_pgs
		fetch dbusage_cursor into @lstart, @size
	end

finish:
	close tabid_cursor
	close dbusage_cursor
	deallocate cursor tabid_cursor
	deallocate cursor dbusage_cursor
	drop table #ha__tables_sync

	set nocount off

	return @retstat
end
go

/*
** SP_HASPACEREQD
** 
** Description:
** 	This stored procedure is the entry point for estimating the space
** requirements. Based on the attrib_id, it either calculates the space needed
** for:
**	- creating the proxy databases or
**	- the space needed on the master for synchronizing with the remote 
**	  server.
**
** Parameters:
**	@servername	: Name of the Companion server	-- Input
**	@skip_error	: Skip on encountering an error	-- Input
**	@check_only	: Check only			-- Input
**	@servername	: Attribute ID			-- Input
**	@option		: Additional option		-- Input
**
** Returns:
**	1 if failure
**	0 otherwise
*/
create procedure sp_haspacereqd
@servername varchar(30)  = null,	/* Name of the primary server */
@skip_error int,			/* Skip the check on error */
@check_only int,			/* Check only */	
@attrib_id  int,			/* attribute Id of interest */
@option	    int 			/* Additional option */
as
begin
declare
	@attrib_name varchar(32),
	@attrib_type varchar(32),
	@computed_advisory int,
	@space_reqd numeric(15,0),
	@space_avail numeric(15,0),
	@retstat int,
	@set_cis_rpc_handling int,
	@error int

	select @retstat = 0, @error = 0, @computed_advisory = 0,
	       @set_cis_rpc_handling = 0

	/* Enable cis rpc handling? */
	if (@@cis_rpc_handling = 0)
	begin
		set cis_rpc_handling on
		select @set_cis_rpc_handling = 1
	end

	/* Compute space requirements for proxy db */
	if (@attrib_id = 3100)
	begin
		exec @retstat = SYB_HACMP.sybsystemprocs.dbo.sp_haproxydbspace @space_reqd output

		if @retstat != 0
			goto finish

		/*
		** Compute the total space available on all the default
		** devices.
		*/
		select @space_avail = 
			(isnull((select sum(high + 1 - low) from master..sysdevices
			  where status & 1 = 1), 0)
		       - (isnull((select sum(size) from master..sysusages u, master..sysdevices d
			  where u.vdevno = d.vdevno and status & 1 = 1),0)))
	end
	/* Compute space required on master db */
	else if (@attrib_id = 3200)
	begin
		select @error = 0
		exec @retstat = sp_hamasterspace @space_reqd output, @space_avail output

		if @retstat != 0
			goto finish
	end

	/*
	** If space available is in the range of 80% to 120% of the space
	** space required, treat it as a soft fault. If space available is
	** less than 80% of the space required it is considered a hard fault.
	*/
        if ((@space_avail is NULL  or @space_avail = 0 ) and @space_reqd > 0)
        begin
                select @error = 1
                select @computed_advisory = 2
        end
        else
	if (@space_avail < @space_reqd)
	begin
		if (@space_avail < (@space_reqd-(@space_reqd/5)))
		begin
			select @error = 1
			select @computed_advisory = 1
		end
		
	end
	else
	begin
		if (@space_avail < (@space_reqd+(@space_reqd/5)))
		begin 
			select @error = 1
			select @computed_advisory = 1
		end
	end

	dbcc istraceon(2202)

	if ((@@error != -1) or (@error != 0))
	begin
		select @attrib_type = attrib_type
		from tempdb..ha_advisory where attrib_id = @attrib_id
		
		if @attrib_id = 3100
			select @attrib_name = "Space for user proxydbs"

		if @attrib_id = 3200
			select @attrib_name = "Space for masterdb sync"

		/* This is to bypass the space estimations */
		dbcc istraceon(2228)
		if (@@error != -1)
			select @computed_advisory = 1

		exec @retstat = sp_ha_logadvisory_rec @attrib_name, 
				@attrib_type, @attrib_id, NULL, 
				NULL, @space_avail,  NULL,
				@space_reqd, @computed_advisory, NULL 

		if @retstat != 0
			goto finish
	end

finish:
	if (@set_cis_rpc_handling = 1)
		set cis_rpc_handling off

	if @retstat != 0
		return (1)
end
go
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_havrfyargs')
begin
	drop procedure sp_havrfyargs
end
go
print "Installing sp_havrfyargs"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
** SP_HAVRFYARGS
** This procedure verifies the arguments passed to the main
** sp_companion procedure and makes sure that for the given
** action all the required parameters are correctly set. If
** anything is missing, it will print the usage error. If
** no arguments are passed then it will report the current 
** status of the HA cluster and return.
**
** Error Messages:
**
** 18933 :"Cluster verification failed. See errorlog for details"
** 18707 :"Local server is currently configured with server '%1!'. The command 
**	  '%2!' can only be run on the configured server."
** 18705 :"Single Server"
** 18706 :"Secondary normal"
** 18708 :"Secondary suspended"
** 18709 :"Secondary failedover"
** 18710 :"Secondary failback"
** 18711 :"Primary normal"
** 18712 :"Primary suspended"
** 18713 :"Primary failback"
** 18714 :"Symmetric normal"
** 18715 :"Symmetric suspended"
** 18716 :"Symmetric failback"
** 18717 :"Symmetric failedover"
** 18718 :"Invalid server"
** 18719 :"Server '%1!' is configured for HA services"
** 18720 :"Server '%1!' is currently in '%2!' mode"
** 18721 :"Server is already in normal companion mode"
** 18722 :"Server is currently configured, drop and retry"
** 18789 :"Usage: sp_companion [[srvname {,cmd}] [,option | NULL ][,srvlogin]
**         [,srvpassword] [,cluslogin] [,cluspassword]]; 
**	   cmd is [configure | drop | suspend | resume | prepare_failback | 
**	   do_advisory | show_cluster | set_cluster]; 
**         option is [with_proxydb] if cmd not [show_cluster | set_cluster]
** 18736 :"Server '%1!' is alive and cluster configured" 
** 18737 :"Server '%1!' is not cluster configured" 
** 18750 :"The command '%1!' can not be run in this server. The server is 
**	  currently configured with mode '%2!'" 
** 
** 18835 :"Option 'with_proxydb' is valid only during Assymmetric ASE HA 
**  	   Configuration, not for Symmetric ASE HA Configuration"
*/
create procedure sp_havrfyargs
@remoteserver varchar(30),	/* Name of the primary server */
@cmd	      varchar(20),	/* desired companion cmd */
@option       varchar(20),	/* option to start watch thread */
@srvlogin     varchar(30),	/* server login for HA monitors */
@srvpwd       varchar(31),	/* server login password */
@cluslogin    varchar(30),	/* clus login for OS/HA */
@cluspwd      varchar(31)	/* clus login password */
as
declare @status	smallint		/* original status */
declare @retstat int			/* return value of executing a SQL */
declare @clusterstatus int		/* status of underlying cluster */
declare @cmpstate int			/* Current companion server status */
declare @dbstatus3 int			/* Status 3 bit of sysdatabases */
declare @sortorder_id int		/* current sortorder id */
declare @charset_id int			/* current charset id */
declare @sortorder_desc varchar(255)	/* description of default sort order */
declare @msg varchar(1024)		/* temp buffer for messages */
declare @servermode varchar(30)		/* current run mode of the server */
declare @hacmpservername varchar(30)	/* name of the associated companion */
declare @localservername varchar(30)	/* name of the local server name */
declare @attrib_grpname varchar(32)	/* name of the advisory attribute */
declare @advoption varchar(30)		/* "display" or "compute" option */

/* Initialize the defaults */
select @retstat = 0
select @cmpstate = @@cmpstate
select @advoption = @srvlogin

/* First process the param list */
if @cmd not in ("configure", "drop", "suspend", "resume", 
				"prepare_failback", "do_advisory",
				"set_cluster", "show_cluster", NULL) 
begin
	raiserror 18789
	return(1)
end

if (@cmd IS NOT NULL and @remoteserver IS NULL)
begin
	raiserror 18789
	return(1)
end

select @cmpstate = @@cmpstate
select @hacmpservername = @@hacmpservername
select @localservername = @@servername

if (@cmpstate = 0)
	exec sp_getmessage 18705, @servermode output
else if (@cmpstate = 2)
	exec sp_getmessage 18706, @servermode output
else if (@cmpstate = 3)
	exec sp_getmessage 18708, @servermode output
else if (@cmpstate = 4)
	exec sp_getmessage 18709, @servermode output
else if (@cmpstate = 5)
	exec sp_getmessage 18710, @servermode output
else if (@cmpstate = 7)
	exec sp_getmessage 18711, @servermode output
else if (@cmpstate = 8)
	exec sp_getmessage 18712, @servermode output
else if (@cmpstate = 9)
	exec sp_getmessage 18713, @servermode output
else if (@cmpstate = 11)
	exec sp_getmessage 18714, @servermode output
else if (@cmpstate = 12)
	exec sp_getmessage 18717, @servermode output
else if (@cmpstate = 13)
	exec sp_getmessage 18715, @servermode output
else if (@cmpstate = 14)
	exec sp_getmessage 18716, @servermode output
else
	exec sp_getmessage 18718, @servermode output

/* Process the parameters */
if (@cmd IS NULL)
begin
	/* 
	** If procedure is invoked without any cmd, 
	** just return the status 
	*/
	if (@remoteserver IS NOT NULL or @option IS NOT NULL)
	begin
		raiserror 18789
		return(1)
	end

	/* 
	** If the Server is alive get the state and display 
	** SHESH_RESOLVE: When HA_CHECKALIVE returns meaningful
	** status, decipher and return the status
	*/
	select @retstat = ha_checkalive(@localservername)
	if (@retstat != 0)
	begin
		exec sp_getmessage 18737, @msg output
		print @msg, @localservername
	end
	else
	begin
		/* Display Success msg for non 2201 invocation only */
		dbcc istraceon(2201)
		if @@error = -1	
		begin
			exec sp_getmessage 18736, @msg output
			print @msg, @localservername

			exec sp_getmessage 18719, @msg output
			print @msg, @localservername
		end
	end

	/* Display server state */
	exec sp_getmessage 18720, @msg output
	print @msg, @localservername, @servermode
	return(0)
end

/* 
** Only Advisory command has the valid values for '@option.' All other commands
** excluding 'show_cluster' and 'set_cluster', only accept option 'override' or
** 'with_proxydb'. 
** If command is 'show_cluster', option is [OS_name | any | ANY];
** If command is 'set_cluster', option is [cluster_name | default | DEFAULT]. 
*/
if @cmd != "do_advisory" and @cmd != "show_cluster" and @cmd != "set_cluster"
begin
	if @option IS NOT NULL 
		if @option not in ("override", "with_proxydb")
		begin
			raiserror 18789
			return(1)
		end
end
	
/* "with_proxydb" option is valid only with the command "configure" */
if (@cmd != "configure" and @option = "with_proxydb")
begin
	raiserror 18789
	return(1)
end

if (@cmd = "configure")
begin
	/* Server is currently running in normal companion mode */
	if (@cmpstate = 2 or @cmpstate = 11)
	begin
		raiserror 18721
		return(1)
	end

	/* You can only do symmetric companion with your companion */
	if (@cmpstate = 7)
	begin
		if (@remoteserver != @hacmpservername)
		begin
			raiserror 18707, @hacmpservername, @cmd
			return(1)
		end

		/*
		** If 'with_proxydb' option is passed, it is an error
		*/
		if @option = "with_proxydb"
		begin
			raiserror 18835
			return(1)
		end
	end

	/* If you are already in some server state, drop and retry */
	if (@cmpstate != 0 and @cmpstate != 7)
	begin
		raiserror 18722
		return(1)
	end

	return(0)
end
else
if (@cmd = "do_advisory")
begin

	/* 
	** Do advisory is generally run when server is in one
	** of the stable modes where the companion server may
	** be gauranteed to be running.
	*/
	if @cmpstate in (9, 10, 12, 13, 14, 15, 3, 4, 5, 6, 8 )
	begin
		raiserror 18750, @cmd, @servermode
		return(1)
	end

	/*
	** If you are re-running the advisory on the currently
	** configured server; better it be on the server it is
	** currently configured with. We have already switch the
	** remote tables pointers so, we will not be able to
	** run advisory on non configured servers
	*/
	if @cmpstate in (2, 7, 11, 13)
	begin
		if (@remoteserver != @hacmpservername)
		begin
			raiserror 18707, @hacmpservername, @cmd
			return(1)
		end
	end

	/* 
	** Do advisory supports advisoy information on all Base
	** attrinutes and group attribute. Just make sure that the
	** option passed in has group name associated with it.
	*/
	if @option = "help" or @option IS NULL
	begin
		exec sp_ha_displayadvisory_help 
		return(0)
	end
	
	if (@option != "all") 
	begin
		/*
		** make sure that option passed in is one of the
		** group or types.. else display help message
		*/
		if not exists (select 1 from tempdb.dbo.ha_advisory_attrs
					where attrib_type = @option)
		begin
			exec sp_ha_displayadvisory_help 
			return(1)
		end

		return(@retstat)
	end
	/* valid advisory actions are 'display' or 'compute' only */
	if (@advoption not in ("display", "compute"))
	begin
		exec sp_ha_displayadvisory_help 
		return(1)
	end
	return(0)	
end
else
/*
** Validate each of the command to the extent possible by looking
** at the server state. 
*/
if (@cmd != "configure" and @cmd != "do_advisory")
begin
	/*
	** There is no specific requirements for 'set_cluster' and
	** 'show_cluster' commands.
	*/
	if @cmd = "set_cluster" or @cmd = "show_cluster"
	begin
		return (0)
	end
 
	/*
	** Suspend command is not applicable in failed-over state
	** and failback state of the server as it is currently
	** running in a transient mode.
	*/
	if @cmd = "suspend" 
	begin
		/* server should not be in one of these state to do suspend */
		if @cmpstate in (0, 4, 5, 8, 9, 10, 12, 14)
		begin
			raiserror 18750, @cmd, @servermode
			return(1)
		end

		/* 
		** If server is in primary normal mode you can not suspend
		** from this server. Inform the user and exit. 
		*/ 
		if @cmpstate = 7
		begin
			raiserror 18764
			return(1)
		end
			
		/* if the server is already in suspended mode no need */
		if @cmpstate in (3, 13) and @option != "override"
		begin
			raiserror 18762
			return(1)
		end

		/* Server should be the configured server */
		if (@remoteserver != @hacmpservername)
		begin
			raiserror 18707, @hacmpservername, @cmd
			return(1)
		end
		
		return(0)
	end

	/*
	** Resume is not applicable in several other states 
	*/
	if @cmd = "resume" 
	begin
		/* server should not be in one of these state to do resume */
		if  @cmpstate in (0, 2, 4, 5, 7, 10, 11, 12)
		begin
			raiserror 18750, @cmd, @servermode
			return(1)
		end
	
		if @cmpstate = 8
		begin
			raiserror 18764
			return(1)
		end

		/* if the server is already in suspended mode no need */
		if @cmpstate in (2, 11) and @option != "override"
		begin
			raiserror 18721
			return(1)
		end

		/* Server should be the configured server */
		if (@remoteserver != @hacmpservername)
		begin
			raiserror 18707, @hacmpservername, @cmd
			return(1)
		end
			return(0)
	end
		
	/*
	** Do prepare failback only from failed-over state or restart
	** of the prepare_failback
	*/
	if @cmd = "prepare_failback" 
	begin
		/* 
		** Check the health of the underlying cluster system
		** Only if this is OK can we proceed.  
		*/ 
		select @clusterstatus = ha_cluster_verify() 
		if (@clusterstatus != 0 and @option != "override") 
		begin 
			raiserror 18933 
			return(1) 
		end
 
		if @cmpstate not in (12, 14, 5, 4)
		begin
			raiserror 18750, @cmd, @servermode
			return(1)
		end	

		if (@cmpstate in (14, 5) and @option != "override")
		begin
			raiserror 18750, @cmd, @servermode
			return(1)
		end
	
		/* Server should be the configured server */
		if (@remoteserver != @hacmpservername)
		begin
			raiserror 18707, @hacmpservername, @cmd
			return(1)
		end
		
		return(0)
	end	

	if @cmd = "drop"
	begin
		if (@cmpstate in (2, 11))
			return(0)

		if (@cmpstate = 7)
		begin
			raiserror 18750, @cmd, @servermode
			return(1)
		end

		if (@cmpstate = 0 and @option != "override")
		begin
			raiserror 18750, @cmd, @servermode
			return(1)
		end

		if (@cmpstate in (12, 13, 14, 5, 4, 3, 8, 9, 10) and 
					@option != "override")
		begin
			raiserror 18750, @cmd, @servermode
			return(1)
		end	
		return(0)
	end

	/*
	** Drop is a special command where we will drop the  configuration
	** its behaviour will be drastically changed by the override option
	** and hence we will let it go through here and catch them at the
	** sp_havrfymodule level where we have more information on the
	** companion server.
	*/

	return(0)
end
else
begin
	raiserror 18789
	return(1)
end
go
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_havrfy')
begin
	drop procedure sp_havrfy
end
go
print "Installing sp_havrfy"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
** SP_HAVRFY
**
**
** Error Messages:
**
** 18756, "Unable to setup omni-connection. Possible causes maybe, server is 
**	  down, sa passwords are different or improper interface definitions"
**
** 18757, "Remote server '%1!' is not added as a local entry.
**	  Use sp_addserver to add it as local enttry and try again"
** 
** 18758, "Remote server '%1!' dosen't have server '%2!' as a remote server.
** 	  Use Sp_addserver at server '%3!' to add server '%4!'"
**
** 18759, "Unable to drop the '%1!' server to fix srvid"
**
** 18760, "Unable to add the '%1!' server to fix srvid"
**
** 18761, "Unable to Update the srvid with fixed srvid"
**
** 18762, "Server is already in suspended state"
**
** 18763, "Suspend operation is not allowed in current server state"
**
** 18764, "Please issue the command from your companion secondary"
**
** 18765, "Server is not in suspended/failingback state you can not resume"
**
** 18766, "Database '%1!' is still being shutdown. Please wait till all
**	 the databases are shutdown before issuing this command"
** 18874, "Server '%1!' could not be added to '%2!'."
** 18875, "Server ID for '%1!' is missing in server '%2!'."
** 18876, "Step: Checking to See if the remote server is up."
*/
create procedure sp_havrfy
@servername varchar(30)  = null,	/* Name of the primary server */
@operation  varchar(20) 
as
declare @sortorder_id int               /* current sortorder id */
declare @charset_id int                 /* current charset id */
declare @sortorder_desc varchar(255)    /* description of the 
					** default sort order */
declare @srvnetname	varchar(32)	/* server net name */
declare @msg		varchar(1024)	/* Buffer for error messages */
declare @alivestatus	int		/* Cluster alive status */
declare @local_haversion varchar(100)	/* ha version of local server */
declare @localservername varchar(30) 	/* Local server name */
declare @xpservername varchar(30) 	/* Server name */
declare @local_xpservername varchar(30) /* Server name */
declare @remote_xpservername varchar(30)/* Server name */
declare @name	varchar(30)		/* Generic name */
declare @check_for_logins int		/* if we need to validate logins */
declare @cfgrunvalue int		/* original status */
declare @cmpstate int			/* Current companion server status */
declare @retstatus int			/* sproc ret status */
declare @dbname varchar(32)		/* database name */
declare @dbstatus3 int			/* database's status 3 */
declare @retstat   int			/* return status */
declare @maxsrvid smallint		/* current max of server id */
declare @srvid_in_remote smallint	/* srvid of local server in remote
					** servers's sysservers entry */
declare @srvid_in_local  smallint	/* srvid of remote server in local
					** servers's sysservers entry */
declare @srvclass smallint		/* srvclass as a number */
declare @srvclass_name varchar(30)	/* srvclass as a name */

/* can not run with in a transaction */
if @@trancount > 0
begin
       	/*
       	** 17260, "Can't run %1! from within a transaction."
       	*/
       	raiserror 17260, "sp_havrfy"
	return (1)
end
else
begin
       	set chained off
end

/* Initialization */
select @localservername = @@servername, @srvclass = 0, @srvclass_name = null

/* Get the current sort order */
select @sortorder_id =
        value from master.dbo.syscurconfigs where config = 123
select @charset_id =
        value from master.dbo.syscurconfigs where config = 131
select @sortorder_desc =
        description from master.dbo.syscharsets
        where id = @sortorder_id and csid = @charset_id

if (@operation = "configure" or @operation = "do_advisory") 	/* Access */
begin
	if (@@cmpstate > 0)
	begin
		return (0)
	end

	/*
	** 300119: We need to allow the XP server entry and 'local'
	** server entry that are automatically instantiated by srvbuild
	**
	** XP servers will be in the form of <srvname_XP> and the local
	** server will have the name 'local'. For now we will allow to
	** waste 2 server ids, one for XP server entry for its companion
	** and other for 'local' server. 
	**
	** If the proposed secondary does not have any of these entries
	** there is no issue. If the secondary has the entries and 
	** primary may or may not have, then we need to manipulate it
	**
	** Phase I will add to remote server any missing entries from
	** secondary server for default server entries like SYB_BACKUP, 'local'
	** The PHASE II adjusts the IDs so as to match. 
	*/

	/*
	** PHASE 1: FIX ENTRIES FOR BACKUP SERVER
	*/
	select @srvid_in_remote = 0, @srvid_in_local  = 0
	select @srvid_in_remote = srvid from master.dbo.rmt_ha_sysservers
				where srvname = "SYB_BACKUP"
	if @@error !=0
		return(1)
	select @srvid_in_local = srvid from master.dbo.sysservers 
				where srvname = "SYB_BACKUP"
	/*
	** If any one of the servers has the entry, we need to adjust
	*/
	if @srvid_in_remote != 0 or @srvid_in_local != 0
	begin
		if (@srvid_in_remote = 0)
		begin
			exec @retstat = sp_remotesql "SYB_HACMP", 
						"sp_addserver 'SYB_BACKUP'"
			if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
			begin
				/*
				** 18874, "Server '%1!' could not be added 
				** to '%2!'."
				*/
				raiserror 18874, "SYB_BACKUP", @servername
				return(1)
			end
		end
	
		if (@srvid_in_local = 0)
		begin
			exec @retstat = sp_addserver 'SYB_BACKUP'
			if ((@retstat != 0) or (@@error != 0))
			begin
				/*
				** 18874, "Server '%1!' could not be added 
				** to '%2!'."
				*/
				raiserror 18874, "SYB_BACKUP", @localservername
				return(1)
			end
		end
	end

	/*
	** PHASE 1: FIX ENTRIES FOR SERVER 'LOCAL'
	*/
	select @srvid_in_remote = 0, @srvid_in_local  = 0
	select @srvid_in_remote = srvid from master.dbo.rmt_ha_sysservers
				where srvname = "local"
	if @@error !=0
		return(1)
	select @srvid_in_local = srvid from master.dbo.sysservers 
				where srvname = "local"
	/*
	** If any one of the servers has the entry, we need to adjust
	*/
	if @srvid_in_remote != 0 or @srvid_in_local != 0
	begin
		if (@srvid_in_remote = 0)
		begin
			/*
			** Get the net name from the local servers, netname
			*/
			select @srvnetname = srvnetname, @srvclass = srvclass 
					from 
					master.dbo.rmt_ha_sysservers where
					srvid = 0
			if @@error != 0
				return(1)

			select @msg = "sp_addserver 'local', null, " + 
						@srvnetname

			exec @retstat = sp_remotesql "SYB_HACMP", @msg
			if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
			begin
				/*
				** 18874, "Server '%1!' could not be added 
				** to '%2!'",
				*/
				raiserror 18874, "local", @servername
				return(1)
			end
		end
	
		if (@srvid_in_local = 0)
		begin
			select @srvnetname = srvnetname , @srvclass = srvclass
				from master.dbo.sysservers where srvid = 0

			exec @retstat = sp_addserver 'local', null, 
					@srvnetname

			if ((@retstat != 0) or (@@error != 0))
			begin
				/*
				** 18874, "Server '%1!' could not be added 
				** to '%2!'."
				*/
				raiserror 18874, "local", @localservername
				return(1)
			end
		end
	end
 
	/*
	** PHASE 1: FIX ENTRIES FOR SERVER '<localserver_XP>'
	*/
	select @xpservername = upper(@localservername) + "_XP"	
	select @srvid_in_remote = 0, @srvid_in_local  = 0
	select @srvid_in_remote = srvid from master.dbo.rmt_ha_sysservers
				where srvname = @xpservername 
	if @@error !=0
		return(1)
	select @srvid_in_local = srvid from master.dbo.sysservers 
				where srvname = @xpservername
	/*
	** If the entry does not exist in local server, nothing to do
	*/
	if @srvid_in_local != 0
	begin
		if (@srvid_in_remote = 0)
		begin
			/*
			** Get the net name from the local servers, netname
			*/
			select @srvnetname = srvnetname, @srvclass = srvclass 
						from 
						master.dbo.sysservers where
						srvid = @srvid_in_local 
			/* Get the class name from the server class number */
			select @srvclass_name = name from master.dbo.spt_values
				where type = 'X' and number = @srvclass

			if (@srvclass_name is null)
			begin
				select @msg = "sp_addserver " + @xpservername + 
					", " + "null" + ", " + @srvnetname
			end
			else
			begin
				select @msg = "sp_addserver " + @xpservername + 
					", " + @srvclass_name + ", " + 
					@srvnetname
			end
			exec @retstat = sp_remotesql "SYB_HACMP", @msg
			if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
			begin
				/*
				** 18874, "Server '%1!' could not be added 
				** to '%2!'."
				*/
				raiserror 18874, @xpservername, @servername
				return(1)
			end
			/*
			** Even though we added the server entry on the remote,
			** for NT, if the srvclass_name is null, it will be 
			** added with a class value of 7 which is not desired.
			** so we update the sysservers row with the actual 
			** class value in the local.  This update will be a
			** redundant operation for other platforms but is o.k
			*/
			if (@srvclass is null)
			begin
				select @msg = "sp_rmt_adhoc_update " + 
				"null" + "," + @xpservername + "," + "1"
			end
			else
			begin
				select @msg = "sp_rmt_adhoc_update " + 
					convert(varchar(10), @srvclass) + "," +
				@xpservername + "," + "1"
			end
			exec @retstat = sp_remotesql "SYB_HACMP", @msg
			if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
			begin
				raiserror 18874, @xpservername, @servername
				return(1)
			end
		end
	end

	/*
	** PHASE 1: FIX ENTRIES FOR SERVER '<remoteserver_XP>'
	*/
	select @xpservername = upper(@servername) + "_XP"	
	select @srvid_in_remote = 0, @srvid_in_local  = 0
	select @srvid_in_remote = srvid from master.dbo.rmt_ha_sysservers
				where srvname = @xpservername 
	if @@error !=0
		return(1)
	select @srvid_in_local = srvid from master.dbo.sysservers 
				where srvname = @xpservername
	/*
	** If the entry does not exist in local server, nothing to do
	*/
	if @srvid_in_local != 0
	begin
		if (@srvid_in_remote = 0)
		begin
			/*
			** Get the net name from the local servers, netname
			*/
			select @srvnetname = srvnetname , @srvclass = srvclass
						from 
						master.dbo.sysservers where
						srvid = @srvid_in_local 

			/* Get the class name from the server class number */
			select @srvclass_name = name from master.dbo.spt_values
				where type = 'X' and number = @srvclass

			if (@srvclass_name is null)
			begin
				select @msg = "sp_addserver " + @xpservername + 
					", " + "null" + ", " + @srvnetname
			end
			else
			begin
				select @msg = "sp_addserver " + @xpservername + 
					", " + @srvclass_name + ", " + 
					@srvnetname
			end
			exec @retstat = sp_remotesql "SYB_HACMP", @msg
			if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
			begin
				/*
				** 18874, "Server '%1!' could not be added 
				** to '%2!'."
				*/
				raiserror 18874, @xpservername, @servername
				return(1)
			end
			if (@srvclass is null)
			begin
				select @msg = "sp_rmt_adhoc_update " + 
				"null" + "," + @xpservername + "," + "1"
			end
			else
			begin
				select @msg = "sp_rmt_adhoc_update " + 
					convert(varchar(10), @srvclass) + "," +
				@xpservername + "," + "1"
			end
			exec @retstat = sp_remotesql "SYB_HACMP", @msg
			if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
			begin
				raiserror 18874, @xpservername, @servername
				return(1)
			end
		end
	end

	/*
	** PHASE 1: FIX ENTRIES FOR THE EJB SERVER
	*/
	select @srvid_in_remote = 0, @srvid_in_local  = 0
	select @srvid_in_remote = srvid from master.dbo.rmt_ha_sysservers
				where srvclass = 10
	if (@@error !=0)
		return(1)
	select @srvid_in_local = srvid from master.dbo.sysservers 
				where srvclass = 10
	/*
	** If and Only if there are entries in both the primary and secondary
	** for the ejb servers will we go ahead with manipulating server id's
	** else the verification will fail with the error message indicating
	** that the user needs to configure EJB Servers before attempting
	** to perform the verification.
	*/
	if (@srvid_in_local = 0 AND @srvid_in_remote != 0)
	begin

		print "Unable to find an EJB Server entry in the local server"
		return(1)
	end
	if (@srvid_in_remote = 0 AND @srvid_in_local != 0)
	begin
		print "Unable to find an EJB Server entry in the remote server"
		return(1)
	end
	/*
	** PHASE II : 
	**
	**	Fixing the entries for server would require pretty much
	** the same requirement as that of the drop server. 
	**
	** 1.  The server whose entries we are fixing should not be involved
	**     in any distributed transactions ( where this is a participant)
	**
	** 2. Obtain the shared table lock on the syscoordinations table
	**
	** 3. When we fix the server id with a new id, this should percolate
	**    to sysremotelogins and sysattributes where remote and
	**    external logins are defined for this server. Instead of this
	**    we will enforce that there should be no such logins defined 
	**    for the remote server. Since these server entries we are fixing
	**    are only for the default servers, it is not a hughe restriction. 
	*/
	begin transaction fixsrvids
	lock table sybsystemdb.dbo.syscoordinations in share mode	
	select 	@local_xpservername = upper(@localservername) + "_XP", 
		@remote_xpservername = upper(@servername) + "_XP"

	declare sysservers_curs cursor for select srvname, srvid from
        				master.dbo.sysservers 
	open sysservers_curs
	fetch sysservers_curs into @name, @srvid_in_local 
	while (@@sqlstatus = 0)
	begin
		select @check_for_logins = 0

		/* Syscoordinations check  is done for all server entries */
		if exists (select 1 from sybsystemdb.dbo.syscoordinations c,
           		master.dbo.sysservers s
           		where 	s.srvname = @name and
                		s.srvid = c.participant and c.owner = 1)
		begin
        		rollback transaction fixsrvids
 
        		/*
        		** 17537, "Unable to drop server '%1!' because it is
        		**         referenced by transaction coordinator."
        		*/
        		raiserror 17537, @name
			close sysservers_curs
			deallocate cursor sysservers_curs
        		return (1)
		end

		/* 
		** The default server should not have any remote logins
		** and extern logins. Other servers having this would be
		** checked at the advisory level.
		*/
		if @name in ("SYB_BACKUP", "local", @servername,
				@remote_xpservername, @local_xpservername)
		begin
			/* 
			** if the remote server id is same as in local server
			** nothing to worry, just go ahed. Remeber that in
			** in phase 1, for every entry in local a corresponding
			** entry is made to exists.
			*/
			if not exists (select 1 from 
					master.dbo.rmt_ha_sysservers where 
						srvname = @name and 
						srvid = @srvid_in_local)
			begin 		
				select @check_for_logins = 1
			end

			/* 
			** The companion servers will share the same server 
			** id for remote server entry of each other, if so 
			** check, if this has happend already, in that case no 
			** need to check for logins.
			*/
			if  @name = @servername
			begin
				if exists (select 1 from
						master.dbo.rmt_ha_sysservers
						where srvname = @@servername
						and srvid = @srvid_in_local)
				begin
					select @check_for_logins = 0
				end		
			end

			/* Check if remote and external logins are compatible */
			if @check_for_logins = 1
			begin
				/* Check for remote logins */
				if exists (select 1 from 
						master.dbo.sysremotelogins l,
                        			master.dbo.sysservers s
                				where s.srvid = l.remoteserverid
                        			and s.srvname = @name)
        			begin
                			rollback transaction fixsrvids
                			/*
                			** 17530, "There are still remotelogins
					** for the server '%1!'."
					*/
                			raiserror 17530, @name
					close sysservers_curs
					deallocate cursor sysservers_curs
                			return (1)  
        			end

				/* Check for extern logins */
				if exists (select 1 from 
					master.dbo.sysattributes a,
                        		master.dbo.sysservers s
                        		where s.srvid = a.object_info1 and
                        		s.srvname = @name and
                        		a.class = 9 and a.attribute = 0)
        			begin
                			rollback transaction fixsrvids
                			/*
                			** 17534, "There are still external 
					** logins for the server '%1!'."
                			*/
                			raiserror 17534, @name
					close sysservers_curs
					deallocate cursor sysservers_curs
                			return (1)
        			end
			end
		end

		fetch sysservers_curs into @name, @srvid_in_local 
	end

	/*
	** fetch would return 1, if any error  occured. 0 for success
	** and 2 for issuing fetch again on the last row
	*/
	if (@@sqlstatus = 1)
	begin
		rollback transaction fixsrvids
		close sysservers_curs
		deallocate cursor sysservers_curs
		return(1)
	end

	close sysservers_curs
	deallocate cursor sysservers_curs

	/*
	** Here we  will fix the entries to see that all the existing default 
	** servers will have a matching server IDs
	**
	** PHASE II : Fix the BACKUP server entries 
	*/
	select @srvid_in_remote = 0, @srvid_in_local  = 0
	select @srvid_in_remote = srvid from master.dbo.rmt_ha_sysservers 
					where srvname = "SYB_BACKUP"
	select @srvid_in_local = srvid from master.dbo.sysservers where 
					srvname = "SYB_BACKUP"
	if (@srvid_in_local != @srvid_in_remote)
	begin
		/*
		** The remote server id for SYB_BACKUP should not be 0
		*/
		if @srvid_in_remote = 0
		begin
			rollback transaction fixsrvids
			/*
			** 18875, "Server ID for '%1!' is missing in 
			** server '%2!'."
			*/
			raiserror 18875, "SYB_BACKUP", @servername
			return(1)
		end
 
		/*
		** Ok First, see if the remote server id for SYB_BACKUP
		** in local is free, if it is, just patch the server id.
		** 
		** If it is not free, since it is a fresh server, we have
		** the liberty of updating the server id to next max, move it
		** and install SYB_BACKUP.
		*/
		if exists ( select 1 from master.dbo.sysservers
				where srvid = @srvid_in_remote 
				and srvname != 'SYB_BACKUP' )
		begin
			select @maxsrvid  = max(srvid) from 
						master.dbo.sysservers
			select @name = srvname from master.dbo.sysservers
                                                where srvid = @srvid_in_remote
			update master.dbo.sysservers
			set srvid = @maxsrvid +1 where srvid = @srvid_in_remote
		end
		update master.dbo.sysservers
		set srvid = @srvid_in_remote where srvname = "SYB_BACKUP"
		dbcc cis ("srvdes",  @srvid_in_remote)
		if (@@error !=0)
		begin
			rollback transaction fixsrvids
			raiserror 18761
			return(1)
		end	
		dbcc connection_hangup(@name)
		dbcc connection_hangup("SYB_BACKUP")		
	end
		
	/*
	** Here we  will fix the entries to see that all the existing default 
	** servers will have a matching server IDs
	**
	** PHASE II : Fix the EJB server entries 
	*/
	select @srvid_in_remote = 0, @srvid_in_local  = 0
	select @srvid_in_remote = srvid from master.dbo.rmt_ha_sysservers 
					where srvclass = 10
	select @srvid_in_local = srvid from master.dbo.sysservers where 
					srvclass = 10
	if (@srvid_in_local != @srvid_in_remote)
	begin
		/*
		** The remote server id for EJB Server should not be 0
		** and this has been verified in phase I.
		**
		** First, see if the remote server id for the EJB Server
		** in local is free, if it is, just patch the server id.
		** 
		** If it is not free, since it is a fresh server, we have
		** the liberty of updating the server id to next max, move it
		** and install the EJB Server.
		*/
		if exists (select 1 from master.dbo.sysservers
				where srvid = @srvid_in_remote 
				and srvclass != 10)
		begin
			select @maxsrvid  = isnull(max(srvid), 0) + 1 from 
						master.dbo.sysservers
			update master.dbo.sysservers
			set srvid = @maxsrvid +1 where srvid = @srvid_in_remote
		end
		update master.dbo.sysservers
			set srvid = @srvid_in_remote where srvclass = 10

		dbcc cis ("srvdes",  @srvid_in_remote)
		if (@@error !=0)
		begin
			rollback transaction fixsrvids
			raiserror 18761
			return(1)
		end	

		dbcc cis ("srvdes",  @srvid_in_local)
		if (@@error !=0)
		begin
			rollback transaction fixsrvids
			raiserror 18761
			return(1)
		end	
	end
	/* 
	** OK at this stage we have reached the state where it is ok to
	** fix the server ids.
	** 
	** Fix the local server ids.
	*/	
	select @srvid_in_remote = 0, @srvid_in_local  = 0
	select @srvid_in_remote = srvid from master.dbo.rmt_ha_sysservers 
					where srvname = "local"
	select @srvid_in_local = srvid from master.dbo.sysservers where 
					srvname = "local"
	if (@srvid_in_local != @srvid_in_remote)
	begin
		/*
		** The remote server id for 'local' should not be 0
		*/
		if @srvid_in_remote = 0
		begin
			rollback transaction fixsrvids
			/*
			** 18875, "Server ID for '%1!' is missing in 
			** server '%2!'."
			*/
			raiserror 18875, "local", @servername
			return(1)
		end
 
		/*
		** Ok First, see if the remote server id for local
		** in local is free, if it is, just patch the server id.
		** 
		** If it is not free, since it is a fresh server, we have
		** the liberty of updating the server id to next max, move it
		** and install local.
		*/
		if exists ( select 1 from master.dbo.sysservers
				where srvid = @srvid_in_remote 
				and srvname != "local" )
		begin
			select @maxsrvid  = max(srvid) from 
						master.dbo.sysservers
			select @name = srvname from master.dbo.sysservers
                                                where srvid = @srvid_in_remote
			update master.dbo.sysservers
			set srvid = @maxsrvid +1 where srvid = @srvid_in_remote
		end
		update master.dbo.sysservers
		set srvid = @srvid_in_remote where srvname = "local"
		dbcc cis ("srvdes",  @srvid_in_remote)
		if (@@error !=0)
		begin
			rollback transaction fixsrvids
			raiserror 18761
			return(1)
		end	
		dbcc connection_hangup(@name)
		dbcc connection_hangup("local")		
	end

	/*
	** PHASE II : Fix the <localserver_XP> server entries 
	*/
	select @srvid_in_remote = 0, @srvid_in_local  = 0
	select @xpservername = upper(@localservername) + "_XP"
	select @srvid_in_remote = srvid from master.dbo.rmt_ha_sysservers 
					where srvname = @xpservername 
	select @srvid_in_local = srvid from master.dbo.sysservers where 
					srvname = @xpservername
	if (@srvid_in_local != @srvid_in_remote and @srvid_in_local != 0)
	begin
		/*
		** The remote server id for <localservername_XP> should not be 0
		*/
		if @srvid_in_remote = 0
		begin
			rollback transaction fixsrvids
			/*
			** 18875, "Server ID for '%1!' is missing in 
			** server '%2!'."
			*/
			raiserror 18875, @xpservername, @servername
			return(1)
		end
 
		/*
		** Ok First, see if the remote server id for local XP server
		** in local is free, if it is, just patch the server id.
		** 
		** If it is not free, since it is a fresh server, we have
		** the liberty of updating the server id to next max, move it
		** and install local XP server.
		*/
		if exists ( select 1 from master.dbo.sysservers
				where srvid = @srvid_in_remote 
				and srvname != @xpservername )
		begin
			select @maxsrvid  = max(srvid) from 
						master.dbo.sysservers
			select @name = srvname from master.dbo.sysservers
						where srvid = @srvid_in_remote
			update master.dbo.sysservers
			set srvid = @maxsrvid +1 where srvid = @srvid_in_remote
		end
		update master.dbo.sysservers
		set srvid = @srvid_in_remote where srvname = @xpservername
		dbcc cis ("srvdes",  @srvid_in_remote)
		if (@@error !=0)
		begin
			rollback transaction fixsrvids
			raiserror 18761
			return(1)
		end	
		dbcc connection_hangup(@name)		
		dbcc connection_hangup(@xpservername)		
	end

	/*
	** PHASE II : Fix the <remoteserver_XP> server entries 
	*/
	select @srvid_in_remote = 0, @srvid_in_local  = 0
	select @xpservername = upper(@servername) + "_XP"
	select @srvid_in_remote = srvid from master.dbo.rmt_ha_sysservers 
					where srvname = @xpservername 
	select @srvid_in_local = srvid from master.dbo.sysservers where 
					srvname = @xpservername
	if (@srvid_in_local != @srvid_in_remote and @srvid_in_local != 0)
	begin
		/*
		** The remote server id for <localservername_XP> should not be 0
		*/
		if @srvid_in_remote = 0
		begin
			rollback transaction fixsrvids
			/*
			** 18875, "Server ID for '%1!' is missing in 
			** server '%2!'."
			*/
			raiserror 18875, @xpservername, @servername
			return(1)
		end
 
		/*
		** Ok First, see if the remote server id for local XP server
		** in local is free, if it is, just patch the server id.
		** 
		** If it is not free, since it is a fresh server, we have
		** the liberty of updating the server id to next max, move it
		** and install local XP server.
		*/
		if exists ( select 1 from master.dbo.sysservers
				where srvid = @srvid_in_remote 
				and srvname != @xpservername )
		begin
			select @maxsrvid  = max(srvid) from 
						master.dbo.sysservers
			select @name = srvname from master.dbo.sysservers
                                                where srvid = @srvid_in_remote
			update master.dbo.sysservers
			set srvid = @maxsrvid +1 where srvid = @srvid_in_remote
		end
		update master.dbo.sysservers
		set srvid = @srvid_in_remote where srvname = @xpservername
		dbcc cis ("srvdes",  @srvid_in_remote)
		if (@@error !=0)
		begin
			rollback transaction fixsrvids
			raiserror 18761
			return(1)
		end	
                dbcc connection_hangup(@name)
		dbcc connection_hangup(@xpservername)
	end

	/*
	** PAHSE II : Fix the local and remote server entries.
	*/
	select @srvid_in_remote = 0, @srvid_in_local  = 0
	select @srvid_in_remote =  srvid from master.dbo.rmt_ha_sysservers
                where srvname = @@servername
	select @srvid_in_local = srvid, @srvnetname = srvnetname from 
		master.dbo.sysservers where srvname = @servername
	/*
	** If the remoteserver's id (srvid) in local sysservers
	** and local servers's id (@srvid_in_remote) are the same
	** no messing around needed.
	*/
	if (@srvid_in_remote != @srvid_in_local)
	begin
		/* At this stage there will be no new connections
		** using this server id, we can go safely and update
		** with the new number we want
		** 
		** If the new slot is already accupied with something, 
		** move it over and then update.
		*/
		if exists ( select 1 from master.dbo.sysservers
				where srvid = @srvid_in_remote 
				and srvname != @servername )
		begin
			select @maxsrvid  = max(srvid) from 
						master.dbo.sysservers
			select @name = srvname from master.dbo.sysservers
                                                where srvid = @srvid_in_remote
			update master.dbo.sysservers
			set srvid = @maxsrvid +1 where srvid = @srvid_in_remote
		end
		
		update master.dbo.sysservers 
			set srvid = @srvid_in_remote where 
			srvname = @servername 

		dbcc cis ("srvdes",  @srvid_in_remote)
		if (@@error !=0)
		begin
			rollback transaction fixsrvids
			raiserror 18761
			return(1)
		end	
		dbcc connection_hangup(@servername)
                dbcc connection_hangup(@name)
	end

	commit transaction fixsrvids

	return(0)
end
else if (@operation = "suspend")
begin
	/*
	** OK finally make sure that that the remote server is
	** up and alive and the passwords are correct
	*/
	dbcc ha_admin("SYB_HACMP", handshake)
	if (@@error !=0)
	begin
		raiserror 18756
		return(1)
	end

	/*
	** Do this to clear any dead connections; if any
	*/
	dbcc ha_admin(@servername, handshake)
	if (@@error !=0)
	begin
		raiserror 18756
		set nocount off
		return(1)
	end

	/*
	** OK make sure that the master device has different
	** pathnames abd are accessible
	*/
	dbcc ha_admin(@servername, pathname, master)
	if (@@error != 0)
	begin
		exec sp_getmessage 18724, @msg output
		print @msg	
		return(1)
	end
	return(0)
end
else if (@operation = "resume")
begin
	/*
	** OK finally make sure that that the remote server is
	** up and alive and the passwords are correct
	*/
	/*
	** 18876,  "Step: Checking to See if the remote server is up." */
	exec sp_getmessage 18876, @msg output
	print @msg

	/* Check the loop back through the 'SYB_HACMP' */
	if (@cmpstate != 9)
	begin
		dbcc ha_admin("SYB_HACMP", handshake)
		if (@@error !=0)
		begin
			raiserror 18756
			set nocount off
			return(1)
		end
	end

	/*
	** Clear any dead connections; if any
	*/
	dbcc ha_admin(@servername, handshake)
	if (@@error !=0)
	begin
		raiserror 18756
		set nocount off
		return(1)
	end

	/*
	** OK make sure that the master device has different
	** pathnames and are accessible.
	** USE servername instead of "SYB_HACMP" because in
	** assymmetric mode SYB_HACMP will not be set for
	** the remote server
	*/
	dbcc ha_admin(@servername, pathname, master)
	if (@@error != 0)
	begin
		exec sp_getmessage 18724, @msg output
		print @msg	
		return(1)
	end
	return(0)
end
else if (@operation = "prepare_failback")
begin
	select @retstatus = 0

	/*
	** If any of mounted databases are still being shutdown, it
	** is pre-mature to issue this command. Wait until all the
	** user databases have been completely shutdown and terminated
	** the connections.
	*/
	declare sysdatabases_curs cursor  for select name, status3
		from master.dbo.sysdatabases 
	open sysdatabases_curs
	fetch sysdatabases_curs into @dbname, @dbstatus3
	while (@@sqlstatus = 0)
	begin
		/*
		** Make sure that the DBSHUTDOWN (of failover) is not 
		** in progress. The way to determine this is to check
		** that DBT3_DBSHUTDOWN_COMPLETED status is set for
		** all the local (not the failedover/mounted) proxy databases.
		*/
		if (((@dbstatus3 & 0x00000002) > 0) and 
		    ((@dbstatus3 & 0x00000010) = 0) and  
		    ((@dbstatus3 & 0x00001000) = 0))
		begin	
			raiserror 18766, @dbname
			select @retstatus = 1	
		end
		fetch sysdatabases_curs into @dbname, @dbstatus3
	end

	/*
	** fetch would return 1, if any error  occured. 0 for success
	** and 2 for issuing fetch again on the last row
	*/
	if (@@sqlstatus = 1)
       		select @retstatus = 1

	close sysdatabases_curs
	deallocate cursor sysdatabases_curs
	return(@retstatus)
end
else if (@operation = "drop")
begin
	select @cmpstate = @@cmpstate
	if (@cmpstate in (6, 7, 8, 9, 10))
	begin
		exec sp_getmessage 18764, @msg output
                print @msg
                return(1)
	end
	return(0)
end
else
	print "Invalid operation for havrfy"
	return(1)
go
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_gensguid')
begin
	drop procedure sp_ha_gensguid
end
go
print "Installing sp_ha_gensguid"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_haupdcatalogs')
begin
	drop procedure sp_haupdcatalogs
end
go
print "Installing sp_haupdcatalogs"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_haupdsuid')
begin
	drop procedure sp_haupdsuid
end
go
print "Installing sp_haupdsuid"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hasyncsysattrs')
begin
	drop procedure sp_hasyncsysattrs
end
go
print "Installing sp_hasyncsysattrs"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hasynclogins')
begin
	drop procedure sp_hasynclogins
end
go
print "Installing sp_hasynclogins"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hasyncgrouproles')
begin
	drop procedure sp_hasyncgrouproles
end
go
print "Installing sp_hasyncgrouproles"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
** Error Messages:
**
**
*/
/* SP_HA_GENSGUID
** This proc generates a new suid/gid/uid suid which is either the max or 
** the min depending upon the available ids for the respective 
** logins/groups/users. If no ids are available, it will return a status of 1.
**
** Parameters :	@type specifies group/user/login -- INPUT
** 		@id is the generated id -- OUTPUT
*/
create procedure sp_ha_gensguid 
@type varchar(30),
@id int output
as

declare @maxid int
declare @minid int

if (@type = 'login')
begin
	select @maxid = max(suid) from master.dbo.syslogins
	if (@maxid = @@maxsuid)
	begin
		select @minid = min(suid) from master.dbo.syslogins
		if (@minid = @@minsuid)
		begin
			print "HA_LOG: Login synchronization error"
			print "All login ids have been used up"
			return (1)
		end
		else if (@minid is NULL)
			select @id = -3 /* suid -2 is an invalid login id */
		else
			select @id = @minid - 1
	end
	else if (@maxid is NULL) /* suid 1 for sa and 2 for probe is reserved */
			select @id = @@probesuid + 1
	     else
			select @id = @maxid + 1
end
else if (@type = 'group')
begin
	/* group/roles have ids in the range @@mingroupid to @@maxgroupid */
	select @maxid = max(uid) from master.dbo.sysusers
	  where uid = gid
	if (@maxid = @@maxgroupid)
	begin
		print "HA_LOG: Group/Role synchronization error"
		print "All group ids have been used up"
		return (1)
	end
	else if (@maxid is NULL or @maxid < @@mingroupid)
		select @id = @@mingroupid
	     else
		select @id = @maxid + 1		
end
else if (@type = 'user')
begin
	/* user ids use the number space between  MINUSERID to MINGROUPID and
	** between (MAXGROUPID + 1) to MAXUSERID. 
	*/
	select @maxid = max(uid) from master.dbo.sysusers 
		where (uid > @@guestuserid and uid < @@mingroupid) 
		or (uid > @@maxgroupid and uid <= @@maxuserid)
	if (@maxid is NULL)
		select @id = @@guestuserid + 1
	else if (@maxid = @@maxuserid)
	begin
		/* checking -ve space since +ve space has been used up */
		select @minid = min(uid) from master.dbo.sysusers
			where uid < @@invaliduserid AND uid >= @@minuserid
		if (@minid = @@minuserid)
		begin
			print "HA_LOG: User synchronization error"
			print "All user ids have been used up"
			return (1)
		end
		else if (@minid is NULL)
			select @id = @@invaliduserid - 1
		     else
			select @id = @minid - 1
	end
	else 
		select @id = @maxid + 1
end
else if (@type = 'usertype')
begin
	/* user defined types are smallint > 100 */
	select @maxid = max(usertype) from master.dbo.systypes 
		where usertype > 100
	if (@maxid is NULL)
		select @id = 101
	else if (@maxid = 32767)
	begin
		print "HA_LOG: Usertype synchronization error"
		print "All usertype ids have been used up"
		return (1)
	end
	else 
		select @id = @maxid + 1
end
else if (@type = 'timerange')
begin
	/* user defined types are smallint > 100 */
	select @maxid = max(id) from master.dbo.systimeranges 
		where id > 1
	if (@maxid is NULL)
		select @id = 2
	else if (@maxid = 32767)
	begin
		print "HA_LOG: Timerange synchronization error"
		print "All timerange ids have been used up"
		return (1)
	end
	else 
		select @id = @maxid + 1
end

return (0)

go
	
/* SP_HAUPDCATALOGS
** This proc makes necessary updates to suid field in various system catalogs 
** like sysalternates, sysusers, sysloginroles, sysremotelogins, systhresholds,
** sysusermessages and sysattributes arising due to fixing up of an suid 
** in sp_haupdsuid resulting due to login synchronization.
**
** Returns 0 on success, 1 on failure
*/

create procedure sp_haupdcatalogs
@oldsuid int,		/* old suid to be replaced */
@rmtsuid int		/* new value to be updated to */

as

declare @srvid smallint		/* server id */

update master.dbo.sysusers set suid = @rmtsuid where suid = @oldsuid
if (@@error != 0)
	return (1)

update master.dbo.sysalternates set suid = @rmtsuid where suid = @oldsuid
if (@@error != 0)
	return (1)

update master.dbo.sysloginroles set suid = @rmtsuid where suid = @oldsuid
if (@@error != 0)
	return (1)

update master.dbo.sysremotelogins set suid = @rmtsuid where suid = @oldsuid
if (@@error != 0)
	return (1)

update master.dbo.systhresholds set suid = @rmtsuid where suid = @oldsuid
if (@@error != 0)
	return (1)

update master.dbo.sysusermessages set uid = @rmtsuid where uid = @oldsuid
if (@@error != 0)
	return (1)

/* Update 'PS' in sysattributes if needed */
update master.dbo.sysattributes set object = @rmtsuid where
	class = 14 and attribute < 3 and object_type = 'PS'
	and object_cinfo = 'login' and object = @oldsuid
if (@@error != 0)
	return (1)

/* Update 'EL' in sysattributes if needed */
select @srvid = srvid from master.dbo.sysservers 
	where srvname = @@servername
update master.dbo.sysattributes set object = @rmtsuid where
	class = 9 and attribute = 0 and object_type = 'EL'
	and object_info1 != @srvid and object = @oldsuid
if (@@error != 0)
	return (1)

return(0)

go


/* SP_HAUPDSUID
** This proc makes necessary updates to suid field in various system catalogs 
** like syslogins, sysalternates, sysusers etc in the local server to ensure 
** that the suid entries across the local and remote servers are in sync.  
** This update may involve changing the suid on the local side or inserting 
** all together a new entry if one does not exist.  
**
** Returns 0 on success, 1 on failure
*/

create procedure sp_haupdsuid
@rmtsuid int,
@defdb	varchar(30),
@status smallint,
@rmtloginame varchar(30),
@password varbinary(129),
@deflanguage varchar(30),
@audflags int,
@fullname varchar(30),
@srvname varchar(30),
@crdate datetime,
@locksuid int,
@lockreason int,
@lockdate datetime

as

declare @tempsuid int		/* temp. suid to do the synchronization */
declare @default_login tinyint
declare @login_exists tinyint
declare @suid_exists tinyint
declare @suid_copied tinyint	/* suid was blindly copied to local server */
declare @suid_inserted tinyint	/* new suid was inserted on the local server */
declare @oldsuid int		/* old suid being updated */
declare @uid int		
declare @gid int		
declare @environ varchar(255)
declare @dbname varchar(30)		
declare @gname varchar(30)		
declare @uname varchar(30)		
declare @uname_to_update varchar(30)		
declare @srvid smallint		/* server id */
declare @retstat int		
declare @sql varchar(255)		

select @suid_copied = 0
select @suid_inserted = 0
select @retstat = 0
select @oldsuid = NULL


set nocount on
if (@rmtloginame in ('sa','probe','qcollector','qrepository','mon_user'))
	select @default_login = 1
else
	select @default_login = 0

/*
** The suid from the remote server should not own any user databases in
** the local server.  This check has been enforced by assuming that the local
** server will not have any user databases, but it is more of a sanity check.
** This check will be done only in single server mode.
*/
if (@rmtloginame != 'sa' and @@cmpstate = 0)
begin
select @dbname = name from master.dbo.sysdatabases where
		suid = @rmtsuid and name not in ('master', 'tempdb', 
			'sybsystemprocs', 'sybsystemdb', 'model')
end

if (@dbname is not NULL)
begin
	print "HA_LOG:Login synchronization error"
	print "suid %1! owns database %2! on the local server", @rmtsuid,
		@dbname
	return(1)
end
/* 
** If the (suid, name) pair does not exist in the local server,
** just insert the row from remote syslogins into the local syslogins 
*/
if (not exists (select 1 from master.dbo.syslogins where 
			suid = @rmtsuid or name = @rmtloginame))
begin			
	insert into master.dbo.syslogins (suid, status, accdate, totcpu, 
		totio, spacelimit, timelimit, resultlimit, dbname, name, 
		password, language, pwdate, audflags, fullname, srvname,
		crdate, locksuid, lockreason, lockdate)
		values(@rmtsuid, @status, getdate(), 0, 0, 0, 0, 0, @defdb, 
		@rmtloginame, @password, @deflanguage, getdate(), @audflags, 
		@fullname, @srvname, @crdate, @locksuid, @lockreason, 
		@lockdate)
		if (@@error != 0)
			return (1)

	select @suid_inserted = 1
end
else	/* Name,suid or both exists */
begin
	/* 
	** If Non default logins have mismatch in terms of suid, we
	** will not synchronize, but raise an error.
	** However, for default logins, we will always synchronize.
	*/
	if not exists(select 1 from  master.dbo.syslogins where
			name = @rmtloginame and suid = @rmtsuid)
	begin
		if (@default_login = 0) /* Non default login */
		begin
			print "HA_LOG:Login synchronization error"
			print "	      Login name '%1!' or suid '%2!' exists", 
				@rmtloginame, @rmtsuid
			return (1)
		end
		else /* Need to sync. up default logins */
		begin	
			if (exists (select 1 from master.dbo.syslogins 
					where name = @rmtloginame)) 
				select @login_exists = 1
			else
				select @login_exists = 0
			if (exists (select 1 from 
					master.dbo.syslogins where 
					suid = @rmtsuid))
				select @suid_exists = 1
			else
				select @suid_exists = 0
			
			/* 
			** Remember the user name corresponding to the changing
			** suid that must be updated in the local sysusers 
			*/
			select @oldsuid = suid from master.dbo.syslogins where
				name = @rmtloginame
			/* 
			** The same default login exists but the suid 
			** is not occupied by any other login, so 
			** simply update the local syslogins entry.
			*/
			if (@login_exists = 1 and @suid_exists = 0)
			begin
				update master.dbo.syslogins set
				suid = @rmtsuid, status = @status,
				dbname = @defdb, password = @password,
				language = @deflanguage, srvname = @srvname, 
				fullname = @fullname, crdate = @crdate,
				locksuid = @locksuid, lockreason = @lockreason,
				lockdate = @lockdate
				where name = @rmtloginame
				if (@@error != 0)
					return (1)

				exec @retstat = sp_haupdcatalogs @oldsuid, 
							@rmtsuid
				if (@retstat = 1)
					return (1)
			end
			/*
			** If the login does not exist in the local 
			** server, first update the suid which is
			** occupying the slot for @rmtsuid to @tempsuid
			** then insert the row from remote server into
			** local server.  The row on the local server
			** whose suid was updated to @tempsuid will get
			** sync'd up subsequently.
			** 
			*/
			if (@login_exists = 0)
			begin
				exec @retstat = 
					sp_ha_gensguid 'login', @tempsuid output
				if (@retstat = 1)
					return (1)

				update master.dbo.syslogins set
				suid = @tempsuid where suid = @rmtsuid
				if (@@error != 0)
					return (1)

				exec @retstat = sp_haupdcatalogs @rmtsuid, 
							@tempsuid
				if (@retstat = 1)
					return (1)

				insert into master.dbo.syslogins 
					(suid, status, accdate, totcpu,
					 totio, spacelimit, timelimit, 
					resultlimit, dbname, name, password, 
					language, pwdate, audflags, fullname, 
					srvname, crdate, locksuid, lockreason,
					lockdate)
					values(@rmtsuid, @status, getdate(), 0,
					0, 0, 0, 0, @defdb, @rmtloginame, 
					@password, @deflanguage, getdate(), 
					@audflags, @fullname, @srvname,
					@crdate, @locksuid, @lockreason, 
					@lockdate)
				if (@@error != 0)
					return (1)

				select @suid_inserted = 1
			end
			/*
			** If the login and suid exist in the local server but 
			** do not match, first update the suid occupying 
			** @rmtsuid to @tempsuid in the local server, then 
			** update the row with login @rmtlogin in the local 
			** from values in remote.  The row that was updated to 
			** @tempsuid will result in an update of the suid field
			** for that user in sysusers.
			*/
			if (@login_exists = 1 and @suid_exists = 1)
			begin
				exec @retstat = 
					sp_ha_gensguid 'login', @tempsuid output
				if (@retstat = 1)
					return (1)

				update master.dbo.syslogins set
				suid = @tempsuid where suid = @rmtsuid
				if (@@error != 0)
					return (1)
				exec @retstat = sp_haupdcatalogs @rmtsuid, 
							@tempsuid
				if (@retstat = 1)
					return (1)

				update master.dbo.syslogins set
				suid = @rmtsuid, status = @status,
				dbname = @defdb, password = @password,
				language = @deflanguage, srvname = @srvname, 
				fullname = @fullname, crdate = @crdate,
				locksuid = @locksuid, lockreason = @lockreason,
				lockdate = @lockdate
				where name = @rmtloginame
				if (@@error != 0)
					return (1)

				exec @retstat = sp_haupdcatalogs @oldsuid, 
							@rmtsuid
				if (@retstat = 1)
					return (1)

			end
		end /* sync'ng upd default logins */
	end
	else	/* logins match exactly, just copy blindly */
	begin
		if (not exists (select 1 from master.dbo.syslogins where
			suid = @rmtsuid and name = @rmtloginame and 
			status = @status and dbname = @defdb and 
			password = @password and language = @deflanguage and 
			audflags = @audflags and srvname = @srvname and 
			fullname = @fullname ))
		begin
			update master.dbo.syslogins set
			suid = @rmtsuid, status = @status, dbname = @defdb, 
			password = @password, language = @deflanguage, 
			srvname = @srvname, fullname = @fullname,
			crdate = @crdate, locksuid = @locksuid,
			lockreason = @lockreason, lockdate = @lockdate
			where name = @rmtloginame

			if (@@error != 0)
				return (1)

			/* syslogins row was copied */
			select @suid_copied = 1
		end
	end
end 

/* 
** If a suid was inserted or copied into the local syslogins, ensure that any 
** alternate login associated with this suid in the remote server is also 
** sync'd up into the local server.
*/
if (@suid_inserted = 1 or @suid_copied = 1)
begin
	if (exists (select 1 from master.dbo.rmt_ha_sysalternates where
			suid = @rmtsuid))
	begin
		/* Add sysalternates entry only if that suid does not exist */
		if (not exists (select 1 from master.dbo.sysalternates where
			suid = @rmtsuid))
		begin
			insert into master.dbo.sysalternates select * from 
				master.dbo.rmt_ha_sysalternates where 
				suid = @rmtsuid
			if (@@error != 0)
				return (1)
		end
	end
end
/*
** If a suid entry was created in the local syslogins, ensure that any user
** associated with this suid is added with the appropriate group in the local
** server.  This is done because users never got synchronized.
*/
if (@suid_copied = 1 or @suid_inserted = 1)
begin
	select @uname = NULL
	select @gid = NULL
	
	/* get the user name and group id associated with this @rmtsuid */
	select @uname = name, @gid = gid, @environ  = environ from 
		master.dbo.rmt_ha_sysusers where 
		suid = @rmtsuid and uid != gid
	if (@uname is not NULL)
	begin
		/* insert this user only if it doesn't exist on the local */
		if (not exists (select 1 from master.dbo.sysusers 
				where name = @uname))
		begin
			/* get the group name for this user */
			select @gname = name from master.dbo.rmt_ha_sysusers 
				where gid = @gid and uid = @gid

			/* generate a uid to insert this user in the local */
			exec @retstat = sp_ha_gensguid 'user', @uid output
			if (@retstat = 1)
				return (1)
			insert master.dbo.sysusers values (@rmtsuid, @uid, 
				@gid, @uname, @environ)
			if (@@error != 0)
				return (1)
		end
		else
		begin
			if (@suid_inserted = 1)
			begin
				print "HA_LOG:Sysusers synchronization error"
				print "suid %1! exists in sysusers while the suid was just added in the local syslogins catalog", @rmtsuid
				return (1)
			end
			else
			begin
				if (not exists (select 1 from 
					master.dbo.rmt_ha_sysusers rmtsysus,
					master.dbo.sysusers sysus where 
					rmtsysus.suid = @rmtsuid
					and rmtsysus.suid = sysus.suid and 
					rmtsysus.name = sysus.name))
				begin
					print "HA_LOG:Error synchronizing users" 
					print "suid %1! has a mismatch in sysusers on server %2!",
							@rmtsuid, @@servername
					return (1)
				end
			end
		end
	end
end

set nocount off
return (0)

go

/* SP_HASYNCSYSATTRS
** This proc makes necessary updates to sysattributes catalog in the local 
** server to ensure that the attributes info. pertaining to password and 
** external logins across the local and remote servers are in sync.  If any
** suid has been updated in syslogins, that change will be reflected at that
** time in sysattributes catalog.
**
** Returns 0 on success, 1 on failure
*/

create procedure sp_hasyncsysattrs

as

declare @passeclass int			/* attribute class */
declare @attribute int			/* attribute id */
declare @suid int
declare @int_value int
declare @srvid int			/* server id */
declare @object_cinfo varchar(255)	/* object info */
declare @class int
declare @object_type char(2)
declare @object_info1 int
declare @image_value varbinary(16)
declare @retstat int
declare @udrclass int
declare @object int

select @retstat = 0
select @passeclass = NULL

select @passeclass = class from master.dbo.sysattributes
	where object_type = "PS"

declare rmtsysattr_curs cursor for
	select attribute, object_cinfo, object, int_value from 
	master.dbo.rmt_ha_sysattributes 
	where class = @passeclass and 
	object_type = "PS" and 
	object_cinfo = "login" and
	attribute < 3 
open rmtsysattr_curs
fetch rmtsysattr_curs into @attribute, @object_cinfo, @suid, @int_value

/* Insert into local sysattributes table */
while (@@sqlstatus = 0)
begin
	if not exists(select 1 from master.dbo.sysattributes where 
			class = @passeclass and
			attribute = @attribute and
			object_type = "PS" and
			object = @suid and
			object_cinfo = @object_cinfo )
	begin			
		insert into master.dbo.sysattributes (class, attribute,
			object_type, object_cinfo, object, int_value)
			values (@passeclass, @attribute, "PS", @object_cinfo,
			@suid, @int_value)

	end
	else	/* There is a matching entry, just copy from remote to local */
	begin
		update master.dbo.sysattributes set int_value = @int_value 
			where class = @passeclass and
			attribute = @attribute and object_type = "PS" and
			object = @suid and object_cinfo = @object_cinfo
	end
	fetch rmtsysattr_curs into @attribute, @object_cinfo, @suid, @int_value
end

if (@@sqlstatus = 1)
	select @retstat = 1

close rmtsysattr_curs
deallocate cursor rmtsysattr_curs

/* return if we encountered any error */
if (@retstat = 1)
	return (@retstat)

/*
** Set the extern login specific attributes. 
** object_info1: server id
** object: @suid
** object_cinfo: externname
** image_value: externpassword 	The length of the encrypted password won't 
** 	exceed 16, which is defined by the schema of sysattributes.
*/

select @srvid = srvid from master.dbo.sysservers where srvname = @@servername
declare rmtsysattr_curs cursor for
	select class, attribute, object_type, object_info1, object,
		object_cinfo, convert(varbinary(16), image_value) 
	  from master.dbo.rmt_ha_sysattributes 
	  where class = 9 and attribute = 0 and object_type = "EL" and
		object_info1 != @srvid 

open rmtsysattr_curs
fetch rmtsysattr_curs into @class, @attribute, @object_type, @object_info1,
	@suid, @object_cinfo, @image_value

/* Insert into local sysattributes table */
while (@@sqlstatus = 0)
begin
	if not exists(select 1 from master.dbo.sysattributes
			where class = @class and
			  attribute = @attribute and
			  object_info1 = @object_info1 and
			  object_type = "EL" and
			  object = @suid)
	begin			
		insert into master.dbo.sysattributes (class, attribute,
			object_type, object_info1, object, 
			object_cinfo, image_value)
		  	values (@class, 0, "EL", @object_info1, @suid, 
			@object_cinfo, @image_value)
	end
	else	
	begin
		update master.dbo.sysattributes 
			set class = @class, attribute = @attribute,
			object_type = "EL", object_info1 = @object_info1, 
			object = @suid, object_cinfo = @object_cinfo, 
			image_value = @image_value where
		  	class = @class and attribute = @attribute and
		  	object_info1 = @object_info1 and
		  	object_type = "EL" and object = @suid
	end

	fetch rmtsysattr_curs into @class, @attribute, @object_type, 
		@object_info1, @suid, @object_cinfo, @image_value
end

if (@@sqlstatus = 1)
	select @retstat = 1

close rmtsysattr_curs
deallocate cursor rmtsysattr_curs

/* return if we encountered any error */
if (@retstat = 1)
	return (@retstat)

/*
** Set the password specific attributes for the role. If an attribute exists, 
** just update it, else insert it as a new attribute.
*/
select @passeclass = NULL
select @passeclass = class from master.dbo.sysattributes
where object_type = "PS"

declare sysattr_pwdcurs cursor for
	select attribute, object_cinfo, object, int_value from 
	master.dbo.rmt_ha_sysattributes 
	where class = @passeclass and 
	object_type = "PS" and 
	object_cinfo = "role" and
	attribute < 3 
open sysattr_pwdcurs
fetch sysattr_pwdcurs into @attribute, @object_cinfo, @object, @int_value

/* Insert into local sysattributes table */
while (@@sqlstatus = 0)
begin
	if not exists(select 1 from master.dbo.sysattributes where 
			class = @passeclass and
			attribute = @attribute and
			object_type = "PS" and
			object = @object and
			object_cinfo = @object_cinfo )
	begin			
		insert into master.dbo.sysattributes (class, attribute,
			object_type, object_cinfo, object, int_value)
			values (@passeclass, @attribute, "PS", @object_cinfo,
			@object, @int_value)

	end
	else	
	begin
		/* Update the values if the value has changed  */
		if not exists (select 1 from master.dbo.sysattributes where
                        	class = @passeclass and
                        	attribute = @attribute and
                        	object_type = "PS" and
                        	object = @object and
                        	object_cinfo = @object_cinfo and
				int_value != @int_value)
		begin
			update master.dbo.sysattributes
			set int_value = @int_value where 
				class = @passeclass and
                        	attribute = @attribute and
                        	object_type = "PS" and
                        	object = @object and
                        	object_cinfo = @object_cinfo
		end
	end

	/* Get the next remotesyslogins row */
	fetch sysattr_pwdcurs into @attribute, @object_cinfo, 
			@object, @int_value
end

if (@@sqlstatus = 1)
	select @retstat = 1

close sysattr_pwdcurs
deallocate cursor sysattr_pwdcurs

/* return if we encountered any error */
if (@retstat = 1)
	return (@retstat)


/*
** Set the role specific attributes. If an attribute exists, just
** update it, else insert it as a new attribute.
*/
select @udrclass = 8
declare sysattr_roleudr_curs cursor for
	select attribute, object_info1, object from 
	master.dbo.rmt_ha_sysattributes 
	where class = @udrclass and 
	object_type = "UR" and 
	attribute < 3 
open sysattr_roleudr_curs
fetch sysattr_roleudr_curs into @attribute, @object_info1, @object

/* Insert into local sysattributes table */
while (@@sqlstatus = 0)
begin
	/*
	** If the entry for a server already exists, skip it.
	*/
	if not exists(select 1 from master.dbo.sysattributes where 
			class = @udrclass and
			attribute = @attribute and
			object_type = "UR" and
			object = @object and
			object_info1 = @object_info1 )
	begin			
		insert into master.dbo.sysattributes (class, attribute,
			object_type, object_info1, object)
			values (@udrclass, @attribute, "UR", @object_info1,
			@object)
	end /* There is no else as the row already exists */

	/* Get the next sysattributes row */
	fetch sysattr_roleudr_curs into @attribute, @object_info1, @object
end

if (@@sqlstatus = 1)
	select @retstat = 1

close sysattr_roleudr_curs
deallocate cursor sysattr_roleudr_curs

return (@retstat)

go


/* SP_HASYNCLOGINS
** This procedure synchronizes the login related system catalogs from the
** remote server to the local server. 
**
** BASICS:
**
** The server logins are spread in basically three catalogs and all are
** connected by the suid in 'syslogins' table. For every login there is
** in the server an entry exists in 'syslogins' with an unique name and
** an unique suid. Remote server logins can be mapped to local server on
** a server wide ( one-to-one), or  all remote logins to a perticular login
** (in local server ) or a perticular remote login to a perticular local
** login. This info. os stored in sysremote logins. Also locally logins can
** have an alternate logins in perticular databases. This mapping is stored
** in 'sysalternate'.
**
** DESIGN:
**
** This opens a cursor on the appropriate catalog in the remote server
** ( by using the proxy tables ) and scans one row at a time. If the 
** entry exists, it is assured to be unique and correct. If the entry
** ( in its entirity) does not exists it is added. If for any failures
** 
** RETURNS:
** 0 if successful;
** 1 if failure;
**
** TBD(s):
**
** May be we can implment the circular dependency check across the catalogs
** This may be very expensieve; but not required for now.
**
*/
create procedure sp_hasynclogins
as

declare @suid int			/* suid in the local server */
declare @loginame varchar(30)           /* login name in the local server */
declare @rmtsuid int			/* suid in the remote server */
declare @rmtloginame varchar(30)        /* login name in the remote server */
declare @password varbinary(129) 	/* password of the new user */
declare @defdb varchar(30) 		/* default db for the new user */
declare @deflanguage varchar(30)        /* default language for the new user */
declare @fullname varchar(30) 		/* account owner's full name */
declare @srvname varchar(30) 		/* account owner's full name */
declare @status	smallint		/* original status */
declare @audflags int			/* original audit flags */
declare @crdate datetime		/* remote login creation date */
declare @locksuid int			/* remote login locked by suid */
declare @lockreason int			/* remote login lock reason */
declare @lockdate datetime		/* remote login lock date */
declare @remoteserverid smallint	/* remote server id */
declare @remoteusername varchar(30)	/* remote username */
declare @altsuid int			/* alternate suid */
declare @retstat int			/* return value of executing a SQL */

select @retstat = 0
/*
** Synchronize the server wide logins. This requires the synchronization
** of both the syslogins and sysattributes where password protection
** related inoformation is kept
*/
declare rmtsyslogins_curs cursor for
	select suid,  dbname, status, name, password, 
	language, audflags, fullname, srvname, crdate, locksuid,
	lockreason, lockdate from 
	master.dbo.rmt_ha_syslogins order by suid
open rmtsyslogins_curs
fetch rmtsyslogins_curs into @rmtsuid, @defdb, @status, @rmtloginame, @password,
	@deflanguage, @audflags, @fullname, @srvname, @crdate, @locksuid,
	@lockreason, @lockdate

/* Insert into local tables */
while (@@sqlstatus = 0)
begin
	/* Synchronize all logins in the syslogins & sysalternates catalog */
	exec @retstat = sp_haupdsuid @rmtsuid, @defdb, @status, 
			@rmtloginame, @password, @deflanguage, @audflags, 
			@fullname, @srvname, @crdate, @locksuid,
			@lockreason, @lockdate
	if (@retstat = 1)
		break

	/* Get the next syslogins row */
	fetch rmtsyslogins_curs into @rmtsuid, @defdb, @status, @rmtloginame, 
			@password, @deflanguage, @audflags, @fullname, @srvname,
			@crdate, @locksuid, @lockreason, @lockdate
end /* while */
	
/*
** fetch would return 1, if any error  occured. 0 for success
** and 2 for issuing fetch again on the last row
*/
if (@@sqlstatus = 1)
	select @retstat = 1

close rmtsyslogins_curs
deallocate cursor rmtsyslogins_curs
return (@retstat)

go


/* SP_HASYNCGROUPROLES
** This procedure synchronizes the groups and roles by replicating the rows
** in sysusers catalog from the remote to the local server.  Since this step
** is independant of the suid, this will be done even before the logins are
** synchronized.
**
** RETURNS: 0 on success and 1 on failure
**
*/
create procedure sp_hasyncgrouproles
as

declare @rmtname varchar(30)		/* name in the local server */
declare @name varchar(30)		/* name in the local server */
declare @retstat int
declare @rmtgid int
declare @gid int

select @retstat = 0

/* select only groups and roles */
declare rmtsysusers_curs cursor for select name, gid 
	from master.dbo.rmt_ha_sysusers where uid = gid order by uid
open rmtsysusers_curs
fetch rmtsysusers_curs into @rmtname, @rmtgid 

while (@@sqlstatus = 0)
begin
	select @name = NULL
	select @gid = NULL

	select @name = name from master.dbo.sysusers 
		where name = @rmtname 
	if (@name is NULL)	/* name not found */
	begin
		/* gid not used up, copy the group/role as is */
		if (not exists (select 1 from master.dbo.sysusers 
				where gid = @rmtgid))
		begin
			insert master.dbo.sysusers select * from 
				master.dbo.rmt_ha_sysusers where name = @rmtname
			if (@@error != 0)
			begin
				select @retstat = 1
				break
			end
		end	
		else /* need to generate a new gid in the local server */
		begin
			/* default groups/roles should have fixed ids */
			if (@rmtname in ("public", "ha_role", 
				"replication_role", "navigator_role", 
				"sybase_ts_role", "oper_role", "sso_role", 
				"sa_role", "dtm_tm_role"))
			begin
				print "HA_LOG: Groups/Roles synchronization error"
				print "Default Group/Role %1! does not exist but its id %2! is used up", @rmtname
				select @retstat = 1
				break
			end
			else
			begin
				exec @retstat = sp_ha_gensguid 'group', 
						@gid output
				if (@retstat = 1)
					return (1)
				insert master.dbo.sysusers select suid, @gid, 
					@gid, name, environ from 
					master.dbo.rmt_ha_sysusers 
					where name = @rmtname
				if (@@error != 0)
				begin
					select @retstat = 1
					break
				end
			end
		end
	end
	fetch rmtsysusers_curs into @rmtname, @rmtgid 
end
		
if (@@sqlstatus = 1)
	select @retstat = 1

close rmtsysusers_curs
deallocate cursor rmtsysusers_curs
return (@retstat)

go

go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hasyncssn')
begin
	drop procedure sp_hasyncssn
end
go
print "Installing sp_hasyncssn"
go


/*
** SP_HASYNCSSN
**
** This procedure syncs up the failed over login sessions from the
** companion server. It does three things:
**
**	o If any session that failed-over from primary to
**	  secondary and subsequently exited from secondary, such 
**	  sessions are removed from primary's syssessions.
**
**	o If any new connections that failed-over to secondary
**	  and they did not exist in primary, such sessions are
**	  copied to primary's syssessions.
**
**	o Since the above two steps brings primary up-to-date
**	  clean-up primary's sessions related data from secondary.
**
** Please see strategy section in demo/ha_sessions.c for details.
*/
create procedure sp_hasyncssn
@servername varchar(30),
@check_only int
as

declare @retstat	int		/* return value of executing a SQL */
declare @sysid		int		/* syssessions column sys_id	   */
declare @sesid		int		/* syssessions column ses_id	   */
declare @state		int		/* syssessions column state	   */	
declare @status		int		/* syssessions column ses_status   */
declare @dbid		int		/* syssessions column dbid	   */
declare @name		varchar(30)	/* syssessions column name	   */
declare @neg_l_nodeid	int		/* negitive of local ha node id    */
declare	@sqlbuf		varchar(255)	/* for sp_remotesql */
declare @diag		int

select @diag = 0
dbcc istraceon(2213)
if (@@error = 0)
begin
	select @diag = 1
end

/* Get the sysid that would be used in secondary for failed-over sessions */
select @neg_l_nodeid = @@ha_local_nodeid * -1

/* Show what we plan to do */

/*
** Step 1: Delete rows in master.dbo.syssessions if the client
** exited from secondary after a failover.
*/
if (@diag = 1)
begin
	select	r.sys_id, r.ses_id, r.state, r.status, r.name 
	AS	"Purging from Primary"
	from 	master.dbo.rmt_ha_syssessions r
	where	r.sys_id = @neg_l_nodeid and r.state = 2
end

/*
** Step 2: If any new sessions were created in secondary after failover
** i.e, they did not exist in primary before failover, such rows must
** be moved to primary.
*/
if (@diag = 1)
begin
	select	r.sys_id, r.ses_id, r.state, r.status, r.name 
	AS	"Moving from Secondary"
	from	master.dbo.rmt_ha_syssessions r
	where	r.sys_id = @neg_l_nodeid and
		r.state = 1 and not exists 
			( select * from master.dbo.syssessions l
			  where l.sys_id = abs(r.sys_id) and
			  l.ses_id = r.ses_id )
end

/*
** Step 3: Now that primary has the correct information. Clean-up
** all the rows pertaining to primary from secondary.
*/
if (@diag = 1)
begin
	select	r.sys_id, r.ses_id, r.state, r.status, r.name 
	AS	"Purging from Secondary"
	from	master.dbo.rmt_ha_syssessions r
	where	r.sys_id = @neg_l_nodeid
end

/* Now do the actual work */

/*
** Step 1: Purge all sessions that that existed in primary and then
** failed over to secondary and subsequently exited from secondary.
** Note that the key phrase here is "existed in primary".
*/
declare ssn_curs cursor for
	select	sys_id, ses_id
	from	master.dbo.rmt_ha_syssessions
	where	sys_id = @neg_l_nodeid and state = 2
open ssn_curs
fetch ssn_curs into @sysid, @sesid
while (@@sqlstatus = 0)
begin
	/*
	** Use @@ha_local_nodeid instead of @neg_l_nodeid as
	** sys_id stored in master will be positive.
	*/
	dbcc ha_admin("", "del_sessions", @@ha_local_nodeid, @sesid)
	fetch ssn_curs into @sysid, @sesid
end
if (@@sqlstatus = 1)
begin
        goto error
end

close ssn_curs
deallocate cursor ssn_curs


/*
** Step 2: Move rows from secondary to primary for those sessions
** that did not exist in primary, but logged into secondary due to
** failover and are still active.
*/
declare ssn_curs cursor for
	select	r.sys_id, r.ses_id, r.state, r.status, r.dbid, r.name
	from	master.dbo.rmt_ha_syssessions r
	where	r.sys_id = @neg_l_nodeid and r.state = 1 and 
		not exists ( select * from master.dbo.syssessions l
		    	  	where l.sys_id = abs(r.sys_id) and
		    	  	      l.ses_id = r.ses_id )
open  ssn_curs
fetch ssn_curs into @sysid, @sesid, @state, @status, @dbid, @name

while (@@sqlstatus = 0)
begin
	insert into master.dbo.syssessions 
		(sys_id, ses_id, state, status, dbid, name, spare)
	values (abs(@sysid), @sesid, @state, @status, @dbid, @name, 0)

	fetch ssn_curs into @sysid, @sesid, @state, @status, @dbid, @name
end

close ssn_curs
deallocate cursor ssn_curs

if (@@sqlstatus = 1)
begin
	goto error
end

/*
** Step 3: Now that primary has the correct information, remove all data
** in secondary pertaining to primary's sessions.
*/
select @sqlbuf = "dbcc ha_admin(' ','del_sessions', " + 
			convert(varchar(12), @neg_l_nodeid) + ", 0)"

exec sp_remotesql "SYB_HACMP", @sqlbuf

return (0)

error:
	close ssn_curs
	deallocate cursor ssn_curs
	return (1)
go
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hasyncsrvroles')
begin
	drop procedure sp_hasyncsrvroles
end
go
print "Installing sp_hasyncsrvroles"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hasyncloginroles')
begin
	drop procedure sp_hasyncloginroles
end
go
print "Installing sp_hasyncloginroles"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hasyncrmtlogins')
begin
	drop procedure sp_hasyncrmtlogins
end
go
print "Installing sp_hasyncrmtlogins"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */

/* SP_HASYNCSRVROLES
** This procedure synchronizes the user defined roles from syssrvroles between
** the local and the remote server. Since system roles are fixed for a given
** version of the server, they need not be synchronized.  Since this step is
** independant of the suid, this will be done even before the logins are
** synchronized.
**
** RETURNS: 0 on success and 1 on failure
**
*/
create procedure sp_hasyncsrvroles
as

declare @rmtsrid int			/* remote server role id */
declare @srid int			/* server role id */
declare @rmtname varchar(30)		/* role name in remote server */
declare @name varchar(30)		/* role name in local server */
declare @retstat int

select @retstat = 0

/* select only user defined roles (they start at 32) */
declare rmtsyssrvroles_curs cursor for select srid, name from
	master.dbo.rmt_ha_syssrvroles where srid  > 31 order by srid
open rmtsyssrvroles_curs
fetch rmtsyssrvroles_curs into @rmtsrid, @rmtname

while (@@sqlstatus = 0)
begin
	select @srid = NULL
	select @name = NULL

	select @srid = srid, @name = name from master.dbo.syssrvroles where
		srid = @rmtsrid or name = @rmtname
	if (@srid is NULL and @name is NULL)
	begin
		/* both srid and name does not exist, insert a row */
		insert into master.dbo.syssrvroles select * from 
			master.dbo.rmt_ha_syssrvroles where 
			srid = @rmtsrid and name = @rmtname
		if (@@error != 0)
		begin
			select @retstat = 1
			break
		end
	end
	else	/* Either Name or srid or both already exists */
	begin
		if (@name = @rmtname) /* name exists */
		begin
			if (@srid != @rmtsrid) /* srids don't match */
			begin
				/*
				** can not synchronize b'cos the srid
				** has been used up.
				*/
				print "HA_LOG:Syssrvroles synchronization error"
				print "Role name '%1!' can not be synchronized", @rmtname
				select @retstat = 1
				break
			end
		end
		else	/* name does not exist */
		begin
			/* srid used for a different role name */
			if (@srid = @rmtsrid) 
			begin
				print "HA_LOG:Syssrvroles synchronization error"
				print "Role name '%1!' can not be synchronized",				@rmtname
				select @retstat = 1
				break
			end
		end
	end

	/* Get the next syssrvroles row */
	fetch rmtsyssrvroles_curs into @rmtsrid, @rmtname
end
	
if (@@sqlstatus = 1)
	select @retstat = 1

close rmtsyssrvroles_curs
deallocate cursor rmtsyssrvroles_curs
return (@retstat)

go

/* SP_HASYNCLOGINROLES
** This procedure synchronizes the entries from sysloginroles between
** the local and the remote server.  This will be done even before syslogins
** is synchronized.  Any change to suid as a result of syslogins 
** synchronization will update sysloginroles at that time.
**
** RETURNS: 0 on success and 1 on failure
**
*/
create procedure sp_hasyncloginroles
as

declare @rmtsrid int
declare @rmtsuid int
declare @rmtstatus smallint
declare @status smallint
declare @retstat int

select @retstat = 0

/*
** Synchronize the roles that are granted to logins
*/
declare rmtsysloginroles_curs cursor for select suid, srid, status from 
	master.dbo.rmt_ha_sysloginroles order by srid
open rmtsysloginroles_curs
fetch rmtsysloginroles_curs into @rmtsuid, @rmtsrid, @rmtstatus

while (@@sqlstatus = 0)
begin
	/* Insert a row if an exact (srid, suid) combo. is not found */
	if not exists(select 1 from master.dbo.sysloginroles 
		where srid = @rmtsrid and suid = @rmtsuid)
	begin			
		insert into master.dbo.sysloginroles (suid, srid, 
				status) values (@rmtsuid, @rmtsrid, @rmtstatus)
		if (@@error != 0)
		begin
			select @retstat = 1
			break
		end
	end
	else /* exact match for (srid, suid) combo exists */
	begin
		select @status = NULL
		select @status = status from master.dbo.sysloginroles
			where srid = @rmtsrid and suid = @rmtsuid
		if (@status is not NULL)
		begin
			/* update if status field has changed */
			if (@status != @rmtstatus)
			begin
				update  master.dbo.sysloginroles
					set status = @status 
					where srid = @rmtsrid and 
					suid = @rmtsuid
				if (@@error != 0)
				begin
					select @retstat = 1
					break
				end
			end
		end
	end	
	fetch rmtsysloginroles_curs into @rmtsuid, @rmtsrid, @rmtstatus
end
	
if (@@sqlstatus = 1)
	select @retstat = 1

close rmtsysloginroles_curs
deallocate cursor rmtsysloginroles_curs
return (@retstat)

go

/* SP_HASYNCRMTLOGINS
** This procedure synchronizes the entries from sysremotelogins between
** the local and the remote server.  This will be done even before syslogins
** is synchronized.  This is because, any logins that exist only in the remote 
** server and has an entry in sysremotelogins may not get copied if we update
** sysremotelogins based on suid changes only.  Any updates to suid as a result 
** of syslogins synchronization will update sysremotelogins at that time.
**
** RETURNS: 0 on success and 1 on failure
**
*/
create procedure sp_hasyncrmtlogins
as

declare @remoteusername varchar(30)
declare @remoteserverid smallint
declare @srvid smallint
declare @rmtsuid int
declare @rmtstatus smallint
declare @status smallint
declare @retstat int

select @retstat = 0

/*
** Synchronize the roles that are granted to logins
*/
/*
** Now synchronize the remote logins
*/
/* exclude the local server in sysremotelogins from being copied over */
select @srvid = srvid from master.dbo.rmt_ha_sysservers 
	where srvname = @@servername

declare rmtsysremotelogins_curs cursor for
	select remoteserverid,  remoteusername, suid, status from 
	master.dbo.rmt_ha_sysremotelogins 
	where remoteserverid  > 1 and remoteserverid != @srvid 
	order by remoteserverid

open rmtsysremotelogins_curs
fetch rmtsysremotelogins_curs into @remoteserverid, @remoteusername, 
		@rmtsuid, @rmtstatus

while (@@sqlstatus = 0)
begin
	if (not exists(select 1 from master.dbo.sysremotelogins where 
			remoteserverid = @remoteserverid and
			remoteusername = @remoteusername))
	begin			
		/* (srvid, username) combo. does not exist, insert a row */
		insert into master.dbo.sysremotelogins 
			(remoteserverid, remoteusername, suid, status)
			values (@remoteserverid, @remoteusername, 
			@rmtsuid, @rmtstatus)
		if (@@error != 0)
		begin
			select @retstat = 1
			break
		end
	end
	else	/* exact match in (srvid, username) combo.*/	
	begin
		select @status = NULL
		select @status = status from master.dbo.sysremotelogins
			where remoteserverid = @remoteserverid and
			remoteusername = @remoteusername and
			suid = @rmtsuid
		if (@status is NULL)
		begin
			/* suid does not match for (srid, username) combo. */
			print "HA_LOG:Remote Login synchronization error"
			print "Suid mismatch for remoteserverid %1!,remoteusername %2!", 
				@remoteserverid, @remoteusername
			select @retstat = 1
			break
		end
		else if (@status != @rmtstatus)
		begin
			/* update if status has changed */
			update master.dbo.sysremotelogins 
				set status = @rmtstatus where 
				remoteserverid = @remoteserverid and
				remoteusername = @remoteusername 
			if (@@error != 0)
			begin
				select @retstat = 1
				break
			end
		end
	end

	/* Get the next remotesyslogins row */
	fetch rmtsysremotelogins_curs into @remoteserverid, @remoteusername, 
		@rmtsuid, @rmtstatus 
end

if (@@sqlstatus = 1)
	select @retstat = 1

close rmtsysremotelogins_curs
deallocate cursor rmtsysremotelogins_curs
return (@retstat)

go

go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hasyncpermissions')
begin
	drop procedure sp_hasyncpermissions
end
go
print "Installing sp_hasyncpermissions"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
** SP_HASYNCPERMISSIONS
**
** This stored procedure synchronizes the permission related information
** from the companion server
**
** BASICS: 
**
** Permissions are granted on a an object or on a 'set of commands'
** to execute. Generally the permissions are stored on per database
** sysprotects catalog. The command 'grant' and 'revoke' are the two
** user interfaces to grant the permissions. However, we are interested
** only in the permissions granted on a database wide set only. Meaning
** permissions granted on an user database are never synchronized, however
** if permissions are granted on an  server wide basis, ex. 'create database'
** command permission for a login or a role, this results in the catalog
** update of the master database. We will synchronize only these.
**
*/
create procedure sp_hasyncpermissions
@servername varchar(30),		/* Remote servername */
@skip_error int,			/* skip the operatio, if found error */
@check_only int, 			/* check_only*/
@attrib_id int
as
declare @status	int			/* original status */
declare @objid	int			/* Object id in sysprotects */
declare @suid 	int           		/* login id */
declare @uid 	int           		/* database user id */
declare @gid 	int           		/* database group id */
declare @id     int           		/* server role id */
declare @lrid   int			/* user role id   */
declare @newuid int	           	/* database user id */
declare @type   smallint                /* type of role   */
declare @grantor int			/* Grantor uid */ 
declare @action smallint		/* operation type */ 
declare @protecttype smallint		/* Protection type, GRANT; REVOKE */
declare @uname 	varchar(30)     	/* user name */
declare @columns varbinary(133)		/* Columns mask */
declare @environ varchar(255)		/* environment of database user */

declare @retstat int			/* return value of executing a SQL */
declare @result  int			/* return value of executing a SQL */

/* Initialize the defaults */
select @retstat = 0
select @result  = 0

/*
** will synchronize on the permission. We will only get the permission related 
** to CREATE DATABASE, CREATE DEFAULT, CREATE PROCEDURE, CREATE RULE, 
** CREATE TABLE, CREATE VIEW, SET SSA and CONNECT commands as these are the only
** things that are stored allways in the master database, else find their way 
** in respective user databases
*/
declare sysprots_curs cursor for
	select id, uid, action, protecttype, columns, grantor from 
	master.dbo.rmt_ha_sysprotects where action in 
	(203, 253, 167, 233, 222, 236, 198, 207)

open sysprots_curs
fetch sysprots_curs into @objid, @uid, @action, @protecttype, @columns, @grantor

/*
** Insert into sysprotects of the local server
*/
while (@@sqlstatus = 0)
begin
	/*
	** The uid on the local server might not be the same as @uid b'cos
	** uids are never synchronized.  So, get the correct uid on the local
	** server for this user and then do the appropriate insert.
	*/
	select @uname = name from master.dbo.rmt_ha_sysusers where
		uid = @uid
	if (@uname is NULL)
	begin
		print "HA_LOG: Sysprotects synchronization error"
		print "userid %1! in sysprotects does not have a username in sysusers for remote server", @uid
		select @retstat = 1
		break
	end

	/*
	** By now any user not present in the local server must have got 
	** created b'cos logins have already been synchronized at this point.
	** Get the uid of this user for the local server.
	*/
	select @uid = uid from master.dbo.sysusers where name = @uname
	if (@uid is NULL)
	begin
		print "HA_LOG: Sysprotects synchronization error"
		print "usename %1! does not exist in the local server", @uname
		select @retstat = 1
		break
	end

	
	/*
	** Here we are synchronizing only the permission granted to
	** commands set DBCREATE, CONNECT, SETSSA as these are done
	** from the master database.
	**
	*/
	if not exists(select 1 from master.dbo.sysprotects where 
			id = @objid and uid = @uid and action = @action)
	begin			
		/* Insert only if desired */
                if (@check_only = 0)
		begin
			insert into master.dbo.sysprotects(id, uid, action, 
				protecttype, columns, grantor )
    	     	        	values(@objid, @uid, @action, @protecttype, 
					@columns, @grantor)
			if (@@error != 0)
			begin
				select @retstat = 1
				break
			end
		end
	end
	else
	begin   /* When they do to same entry, the protecttype, or grantor 
		** might have changed. So, if that the case then update.
		*/
		if exists ( select 1 from master.dbo.sysprotects where 
				id = @objid and
				uid = @uid and
				action = @action and
				protecttype != @protecttype or
				grantor != @grantor)
		begin
			update master.dbo.sysprotects
			set protecttype = @protecttype, grantor = @grantor where
					id = @objid and
					action = @action and
					uid = @uid	
		end
	end 

	fetch sysprots_curs into @objid, @uid, @action, 
			@protecttype, @columns, @grantor
end

/*
** fetch would return 1, if any error occured. 0 for success
** and 2 for issuing fetch again on the last row.
*/
if (@@sqlstatus = 1)
	select @retstat = 1

close sysprots_curs
deallocate cursor sysprots_curs

/*
** If protection info. for the following commands exists in the local but does 
** not exist in the remote server, it means that the permissions were revoked
** on the remote server and hence the corresponding rows have to be deleted 
** from the local sysprotects catalog.
*/
declare sysprots_curs cursor for
	select id, uid, action, protecttype, columns, grantor from 
	master.dbo.sysprotects where action in 
	(203, 253, 167, 233, 222, 236, 198, 207)

open sysprots_curs
fetch sysprots_curs into @objid, @uid, @action, @protecttype, @columns, @grantor

/*
** Delete from sysprotects of the local server
*/
while (@@sqlstatus = 0)
begin
	/*
	** The uid on the remote server might not be the same as @uid b'cos
	** uids are never synchronized.  So, get the correct uid on the remote
	** server for this user and then do the appropriate delete.
	*/
	select @uname = name from master.dbo.sysusers where
		uid = @uid
	if (@uname is NULL)
	begin
		print "HA_LOG: Sysprotects synchronization error"
		print "userid %1! in sysprotects does not have a username in sysusers for local server", @uid
		select @retstat = 1
		break
	end

	/*
	** This user must exist on the remote server.
	** Get the uid of this user for the remote server.
	*/
	select @newuid = uid from master.dbo.rmt_ha_sysusers where name = @uname
	if (@uid is NULL)
	begin
		print "HA_LOG: Sysprotects synchronization error"
		print "usename %1! does not exist in the remote server", @uname
		select @retstat = 1
		break
	end

	if not exists(select 1 from master.dbo.rmt_ha_sysprotects where 
			id = @objid and uid = @newuid and action = @action)
	begin			
		/* Delete only if desired */
                if (@check_only = 0)
		begin
			delete master.dbo.sysprotects where
				id = @objid and uid = @uid and action = @action
			if (@@error != 0)
			begin
				select @retstat = 1
				break
			end
		end
	end
	else
	begin   /* When they do to same entry, the protecttype, or grantor 
		** might have changed. So, if that the case then update.
		*/
		if exists ( select 1 from master.dbo.rmt_ha_sysprotects where 
				id = @objid and
				uid = @newuid and
				action = @action and
				protecttype != @protecttype or
				grantor != @grantor)
		begin
			update master.dbo.sysprotects
			set protecttype = @protecttype, grantor = @grantor where
					id = @objid and
					action = @action and
					uid = @uid	
		end
	end 

	fetch sysprots_curs into @objid, @uid, @action, 
			@protecttype, @columns, @grantor
end

/*
** fetch would return 1, if any error occured. 0 for success
** and 2 for issuing fetch again on the last row.
*/
if (@@sqlstatus = 1)
	select @retstat = 1

close sysprots_curs
deallocate cursor sysprots_curs

return(@retstat)
go
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hasyncapps')
begin
	drop procedure sp_hasyncapps
end
go
print "Installing sp_hasyncapps"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
** Error Messages:
**
**
** SP_HASYNCAPPS
** This procedure synchronizes the remote servers definition in the
** the companion server with the local server for HA. The remote servers
** are located in master database's sysservers catalog.
**
** BASICS:
** The synchronization will be attempted during the configuration and
** resume of companion server relationship. Since when we start the
** configuration, we have the secondat server start from scratch, ideally
** there should be no entries other than the defaults. So synchronization
** should be successful. 
**
** DESIGN:
**
** The sysservers entries have a clusterd index on server id and an non-
** clustered index on server name. Both the server id and names are unique
** So, if any attempts to  duplicate will result in failure. During the
** companion configuration we would have fixed the server installed definition
** like SYB_HACMP, SYB_BACKUP, XP_SERVER etc.. So ideally the synchronization
** should be straight forward.
**
** Additionally, this procedure synchronizes the application specific details 
** like timeranges and user defined types between the companion servers at 
** configuration time.  resourcelimits and jar files are never synchronized.
**
*/
create procedure sp_hasyncapps
@servername varchar(30), 		/* Remote servername */
@skip_error int,			/* skip the operatio, if found error */
@check_only int, 			/* check_only*/
@attrib_id  int				/* attribute Id for advisory */
as

declare @localservername varchar(30), 
	@srvid	smallint,		
	@srvstatus smallint,		
	@srvname varchar(30),		
	@srvnetname varchar(32),	
	@srvclass smallint, 		
	@retstat int,			
	@result int,			
	@clean_cursor int		

declare @langid smallint, 	
	@dateformat char(3), 		
	@datefirst tinyint, 	
	@upgrade int,			
	@alias varchar(30), 
	@months varchar(251), 
	@shortmonths varchar(119), 
	@name varchar(30),		
	@days varchar(216)


declare @rmt_usertype smallint,
	@usertype smallint,
	@rmt_var bit,
	@rmt_null bit, 
	@rmt_type tinyint,
	@rmt_len int, 
	@rmt_name varchar(30),
	@rmt_prec tinyint,
	@rmt_scale tinyint,
	@rmt_ident tinyint,
	@rmt_hierarchy tinyint

declare @rmt_appname varchar(30), 
	@rmt_rangeid smallint, 
	@rmt_limitid smallint, 
	@rmt_limitvalue int,
	@rmt_enforced tinyint, 
	@rmt_action tinyint, 
	@rmt_scope tinyint

declare @rmt_id smallint, 
	@id smallint,
	@rmt_startday tinyint, 
	@rmt_endday tinyint, 
	@rmt_starttime varchar(10), 
	@rmt_endtime varchar(10)


/* Initialize the defaults */
select @retstat = 0
select @result = 0
select @clean_cursor = 0
select @localservername = @@servername

/*
** We need to scan all entries except the local server entry in the
** remote server. The remote servers, will share the server id in its
** local domain. This relationship will be established as part of the 
** configuration setup.
**
** If during the failed-over mode or suspended mode, user was able to
** delete the server entries ( say using sp_dropserver ), the local server
** might still have the same orphan entries. We will not clean it up here.
** users are advised to run advisory to figure-out the orphan entries and
** clean it up. If these entries start confilicting with new entries that
** user might add in the companion, this will be reported automatically
** ( say during the addserver, dropserver etc. )
** 
*/
declare sysservers_curs cursor for
	select srvid,  srvstatus, srvname, srvnetname, srvclass 
	from 
	master.dbo.rmt_ha_sysservers where srvid > 0 and 
	srvname not in (@localservername, 'SYB_HACMP', 
			'SYB_BACKUP', 'local') order by srvid
open sysservers_curs
select @clean_cursor = 1
fetch sysservers_curs into @srvid, @srvstatus, @srvname, @srvnetname, @srvclass

/* Insert/update the local Sysservers table */
while (@@sqlstatus = 0)
begin
	/*
	** Sysservers has an unique index on the srvid and srvname. In order
	** to insert the entry should not exist. This insert would mean that
	** it is a new entry added to this server as part of synchronization
	*/
	if not exists(select 1 from master.dbo.sysservers 
		where srvname = @srvname or srvid = @srvid)
	begin			
		insert into master.dbo.sysservers (srvid, srvstatus, 
			srvname, srvnetname, srvclass )
			values (@srvid, @srvstatus, @srvname, 
				@srvnetname, @srvclass )
	end
	else	/* Name or suid already exists */
	begin
		/* Make sure they do refer to same server entry */
		if not exists(select 1 from  master.dbo.sysservers where
				srvname = @srvname and srvid = @srvid)
		begin
			/* There is a consistency check failure, flag it */
			print "HA_LOG: Remote server synchronization error"
			print "       Conflicting server ids for server '%1!'",
					@srvname
			select @retstat = 1
			goto clean_all
		end
		else
		begin
			/* 
			** if any of the class, server status netname has
			** changed, we will update it
			*/
			if exists (select 1 from master.dbo.sysservers where
					srvnetname != @srvnetname or
					srvclass != @srvclass     or
					srvstatus != @srvstatus and
					srvid = @srvid and 
					srvname = @srvname)
			begin
				update master.dbo.sysservers
				set srvnetname = @srvnetname,
				    srvclass = @srvclass,
				    srvstatus = @srvstatus where
				    srvname = @srvname and 
				    srvid = @srvid
					
				dbcc cis("srvdes", @srvid)
			end
		end
	end

	/* Get the next sysservers row */
	fetch sysservers_curs into @srvid, @srvstatus, @srvname, 
					@srvnetname, @srvclass
end
	
/*
** fetch would return 1, if any error  occured. 0 for success
** and 2 for issuing fetch again on the last row
*/
if (@@sqlstatus = 1)
begin
	select @retstat = 1
	goto clean_all
end

close sysservers_curs
deallocate cursor sysservers_curs
select @clean_cursor = 0

/* syslanguages */
declare sysservers_curs cursor for
	select langid, dateformat, datefirst, upgrade, name, alias, 
		months, shortmonths, days
	from 
	master.dbo.rmt_ha_syslanguages
open sysservers_curs
select @clean_cursor = 1
fetch sysservers_curs into @langid, @dateformat, @datefirst, @upgrade, 
		@name, @alias, @months, @shortmonths, @days

/* Insert into local tables */
while (@@sqlstatus = 0)
begin
	if exists (select 1 from master.dbo.syslanguages
				where name = @name)
	begin
		/* Make sure that langid is same */
		if exists ( select 1 from master.dbo.syslanguages
				where langid = @langid and
					name = @name)
		begin
			/* update the row only, if alias has changed */
			if not exists (select 1 from master.dbo.syslanguages
				where langid = @langid and
					name = @name and
					alias = @alias)
			begin
				update master.dbo.syslanguages
				set 	alias = @alias where
					langid = @langid and
					name = @name
			end
		end
		else
		begin
			/* There is a mismatch in the langid/langname */	
			print "HA_LOG: Language synchronization error"
			print "Language '%1!', Lang id '%2!' conflict",
					@name, @langid
			select @retstat = 1
			goto clean_all
		end
	end
	else
	begin
		/* Make sure that langid and aliase are not used up */
		if exists (select 1 from master.dbo.syslanguages where 
					langid = @langid or
					alias  = @alias)
		begin
			/* There is a mismatch in the langid/langname */	
			print "HA_LOG: Language synchronization error"
			print "Language '%1!' conflicts with Lang id or Alias",
					@name
			select @retstat = 1
			goto clean_all
		end
		else
		begin
			insert into master.dbo.syslanguages (langid, 
				dateformat, datefirst, upgrade, name, alias, 
				months, shortmonths, days)
		  	values (@langid, @dateformat, @datefirst, @upgrade,
				@name, @alias, @months, @shortmonths, @days)
		end
	end		

	/* Get the next syslanguages row */
	fetch sysservers_curs into @langid, @dateformat, @datefirst, @upgrade, 
		@name, @alias, @months, @shortmonths, @days
end

/*
** fetch would return 1, if any error  occured. 0 for success
** and 2 for issuing fetch again on the last row
*/
if (@@sqlstatus = 1)
begin
        select @retstat = 1
        goto clean_all
end
	
close sysservers_curs
deallocate cursor sysservers_curs
select @clean_cursor = 0


/* Close and de allocate the cursor */
clean_all:
if (@clean_cursor = 1)
begin
	close sysservers_curs
	deallocate cursor sysservers_curs
end

if (@retstat = 1)
	return(@retstat)

/*
** Synchronize Systypes
** All User defined data types have usertype > 100
*/
declare rmtsystypes_curs cursor for
	select usertype, name, variable, allownulls, type, length, prec, scale,
	ident, hierarchy from master.dbo.rmt_ha_systypes where 
	usertype > 100 order by usertype

open rmtsystypes_curs
fetch rmtsystypes_curs into @rmt_usertype, @rmt_name, @rmt_var, @rmt_null, 
	@rmt_type, @rmt_len, @rmt_prec, @rmt_scale, @rmt_ident, @rmt_hierarchy

/*
** If this user type exists in the local server it better have the same 
** characteristics except possibly for usertype (id).  If the user tyep does
** not exists, insert a row either with a new id or with the same id if that
** id is not used up.
*/
while (@@sqlstatus = 0)
begin
		
	if (exists (select 1 from master.dbo.systypes where name = @rmt_name))
	begin
		if (not exists (select 1 from master.dbo.systypes 
			where name = @rmt_name and variable = @rmt_var and 
			allownulls = @rmt_null and type = @rmt_type and 
			length = @rmt_len and prec = @rmt_prec and 
			scale = @rmt_scale and ident = @rmt_ident and
			hierarchy = @rmt_hierarchy))
		begin			
			print "HA_LOG:Systypes Synchronization error"
			print "Mismatch for user type %1!", @rmt_name
			select @retstat = 1
			break
		end
	end
	else
	begin	/* user type does not exist on the local server */
		if (not exists (select 1 from master.dbo.systypes where
			usertype = @rmt_usertype))
		begin
			/* copy the row if the id is not used up in local */
			insert into master.dbo.systypes select * from 
				master.dbo.rmt_ha_systypes where
				name = @rmt_name
			if (@@error != 0)
			begin
				select @retstat = 1
				break
			end
		end
		else
		begin
			/* generate a new id */
			exec @retstat = sp_ha_gensguid 'usertype', 
						@usertype output
			if (@retstat != 0)
				break

			/* insert the row with the newly generated id */
			insert into master.dbo.systypes 
				select uid, @usertype, variable, allownulls,
				type, length, tdefault, domain, name, printfmt,
				prec, scale, ident, hierarchy, xtypeid, xdbid,
				accessrule from master.dbo.rmt_ha_systypes where
				name = @rmt_name
			if (@@error != 0)
			begin
				select @retstat = 1
				break
			end
		end
	end
	fetch rmtsystypes_curs into @rmt_usertype, @rmt_name, @rmt_var, 
		@rmt_null, @rmt_type, @rmt_len, @rmt_prec, @rmt_scale, 
		@rmt_ident, @rmt_hierarchy
end
	
if (@@sqlstatus = 1)
	select @retstat = 1

close rmtsystypes_curs
deallocate cursor rmtsystypes_curs
if (@retstat = 1)
	return (1)

/*
** Synchronize Systimeranges
** This catalog always has an id = 1 for the name 'at all time' which need 
** not be synchronized.  If in the future we decide to synchronize 
** sysresourcelimits, we have to do that before doing this.  In such a case, 
** we may have to update the rangeid field in sysresourcelimit if a new id was 
** generated for the corresponding timerange.
*/
declare rmtsystime_curs cursor for
	select name, id, startday, endday, starttime, endtime
	from master.dbo.rmt_ha_systimeranges where id > 1 order by id

open rmtsystime_curs
fetch rmtsystime_curs into @rmt_name, @rmt_id, @rmt_startday, 
	@rmt_endday, @rmt_starttime, @rmt_endtime

/*
** For every time range defined in the remote server, if it also exists in
** the local server, if they don't match exactly except possibly for the id, we
** will update that row in the local server.  If time range not present in the 
** local, we will insert a row for it.
*/
while (@@sqlstatus = 0)
begin
		
	if (exists (select 1 from master.dbo.systimeranges where
			name = @rmt_name)) 
	begin
		if (not exists (select 1 from master.dbo.systimeranges where
			name = @rmt_name and startday = @rmt_startday and 
			endday = @rmt_endday and starttime = @rmt_starttime 
			and endtime = @rmt_endtime))

		begin
			update master.dbo.systimeranges set
				startday = @rmt_startday,
				endday = @rmt_endday,
				starttime = @rmt_starttime,
				endtime = @rmt_endtime
		end
	end
	else
	begin
		if (not exists (select 1 from master.dbo.systimeranges where
			id = @rmt_id))
		begin
			/* copy the row if the id is not used up in local */
			insert into master.dbo.systimeranges select * from 
				master.dbo.rmt_ha_systimeranges where
				name = @rmt_name
			if (@@error != 0)
			begin
				select @retstat = 1
				break
			end
		end
		else
		begin
			/* generate a new id */
			exec @retstat = sp_ha_gensguid 'timerange', 
						@id output
			if (@retstat != 0)
				break

			/* insert the row with the newly generated id */
			insert into master.dbo.systimeranges 
				select name, @id, startday, endday,
				starttime, endtime from
				master.dbo.rmt_ha_systimeranges where
				name = @rmt_name
			if (@@error != 0)
			begin
				select @retstat = 1
				break
			end
		end
	end
	fetch rmtsystime_curs into @rmt_name, @rmt_id, @rmt_startday, 
		@rmt_endday, @rmt_starttime, @rmt_endtime
end
	
if (@@sqlstatus = 1)
	select @retstat = 1

close rmtsystime_curs
deallocate cursor rmtsystime_curs

if (@retstat = 1)
	return (1)

return (@retstat)
go
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_haupdproxydbstate')
begin
	drop procedure sp_haupdproxydbstate
end
go
print "Installing sp_haupdproxydbstate"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
create procedure sp_haupdproxydbstate
@action	    varchar (20) 		/* desired companion action */
as
declare @status	smallint		/* original status */
declare @cfgrunvalue int		/* original status */
declare @retstat int			/* return value of executing a SQL */
declare @clean_table int		/* Clean up all the tables */
declare @clean_cursor int		/* Clean up all the cursors */
declare @name varchar(30)		/* name of the database */
declare @dbstatus3 int			/* database status */
declare @tempdb_mask   int	/* All database status bit for a tempdb */
declare @newstatus int			/* new database status3 */
declare @isproxy   int			/* is database a proxy */
declare @hasproxy  int			/* does database has proxy */

/* Initialize the defaults */
select @retstat = 0
select @clean_table = 0
select @clean_cursor = 0

/* can not run with in a transaction */
if @@trancount > 0
begin
       	/*
       	** 17260, "Can't run %1! from within a transaction."
       	*/
       	raiserror 17260, "sp_updproxydbstate"
	return (1)
end
else
begin
       	set chained off
end

select @tempdb_mask = number
	from master.dbo.spt_values
	where type = "D3" and name = "TEMPDB STATUS MASK"

if (@action = "setdb3state" or @action = "cleardb3state")
begin
	select @newstatus = 4 

	/*
	** We need to create the proxy databases for every
	** primary databases in the the local server.
	** sp_havrfy would have populated the rmt_ha_sysdatabases
	** so use the name and create the proxy database.
	*/
	declare sysdatabases_curs cursor  for select name, status3
		from master.dbo.sysdatabases for update
	open sysdatabases_curs
	select @clean_cursor = 1
	fetch sysdatabases_curs into @name, @dbstatus3
	while (@@sqlstatus = 0)
	begin
		/*
		** Exclude the system databases, user temporary databases 
		** and archive databases.
		*/ 
		if (@name NOT IN ("master","model","tempdb","sybsystemdb",
				  "sybsystemprocs","dbccdb","sybsecurity",
				  "dbccalt","sybsyntax","sybmgmtdb","sybpcidb" )
			and 
			(@dbstatus3 & @tempdb_mask = 0 and
			 @dbstatus3 & 4194304 != 4194304))
		begin
			select @isproxy = @dbstatus3 & 2
			select @hasproxy = @dbstatus3 & 4

			if (@action = "setdb3state")
			begin
				/*
				** We should ONLY update those databases
				** which are not proxies, else we are
				** overwriting !!
				*/
				if (@isproxy = 0 )
				begin
					/*
					** third param should be 1 to set the status bit
					*/
					dbcc cis ("haproxystat", @name, 1)
				end
			end
			else
			begin	
					/*
					** third param should be 2 to reset status bit
					*/
					dbcc cis ("haproxystat", @name, 2)
			end
		end
		fetch sysdatabases_curs into @name, @dbstatus3
	end
	
	/*
	** fetch would return 1, if any error  occured. 0 for success
	** and 2 for issuing fetch again on the last row
	*/
	if (@@sqlstatus = 1)
	begin
        	select @retstat = 1
        	goto clean_all
	end
	/* Close and de allocate the cursor */
	clean_all:
	if (@clean_cursor = 1)
	begin
        	close sysdatabases_curs
        	deallocate cursor sysdatabases_curs
	end
	return(@retstat)
end
else
	return(1)
go

go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_haproxydb')
begin
	drop procedure sp_haproxydb
end
go
print "Installing sp_haproxydb"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
create procedure sp_haproxydb
@servername varchar(30)  = null,	/* Name of the primary server */
@action	    varchar (20) 		/* desired companion action */
as
declare @status	smallint		/* original status */
declare @cfgrunvalue int		/* original status */
declare @retstat int			/* return value of executing a SQL */
declare @clean_table int		/* Clean up all the tables */
declare @clean_cursor int		/* Clean up all the cursors */
declare @name varchar(30)		/* name of the database */
declare @dbstatus3 int			/* database status */
declare @tempdb_mask   int	 /* All database status bit for a tempdb */
declare @msg varchar(1024)		/* message buffer */
declare @isproxy int			/* is database a proxy */
declare @hasproxy int			/* does database has a proxy */

/* Initialize the defaults */
select @retstat = 0
select @clean_table = 0
select @clean_cursor = 0

/* can not run with in a transaction */
if @@trancount > 0
begin
       	/*
       	** 17260, "Can't run %1! from within a transaction."
       	*/
       	raiserror 17260, "sp_haproxydb"
	return (1)
end
else
begin
       	set chained off
end

select @tempdb_mask = number
	from master.dbo.spt_values
	where type = "D3" and name = "TEMPDB STATUS MASK"

if (@action = "create")
begin
	/*
	** We need to create the proxy databases for every
	** primary databases in the the local server.
	** sp_havrfy would have populated the rmt_ha_sysdatabases
	** so use the name and create the proxy database.
	*/
	declare sysdatabases_curs cursor  for select name, status3
		from master.dbo.rmt_ha_sysdatabases
	open sysdatabases_curs
	select @clean_cursor = 1
	fetch sysdatabases_curs into @name, @dbstatus3
	while (@@sqlstatus = 0)
	begin
		/*
		** CR 192638-1: Create proxies for only
		** those databases that are not proxies
		** already. Skip those that have proxies
		** already, check if the database exists
		** locally, if so then skip it.
		*/
		select @isproxy = @dbstatus3 & 2
		select @hasproxy = @dbstatus3 & 4

		if (@isproxy = 0)
		begin
			/*
			** Make sure that we do not already
			** have a proxy database in the local
			** server. 
			*/
			if exists ( select 1 from master.dbo.sysdatabases where	name like @name and 
					 @name NOT IN  ("master","model","tempdb", "sybsystemdb",
							"sybsystemprocs", "dbccdb","sybsecurity",
							"dbccalt","sybsyntax","sybmgmtdb","sybpcidb" ))
			begin
				print "Database '%1!' already exists", @name
			end
			else
			begin
				/* 
				** The user database can be neither a user temp 
				** database nor an archive database.
				*/
				if (((@dbstatus3 & @tempdb_mask) = 0)
				and (@dbstatus3 & 4194304 != 4194304))
				begin
					dbcc create_haproxydb(@name)
				end

				if (@@error !=0 )
				begin
		   			exec sp_getmessage 18770, @msg output
		   			print @msg, @name 
		   			select @retstat = 1
					goto clean_all
				end	
			end
		end

		fetch sysdatabases_curs into @name, @dbstatus3
	end

	/*
	** fetch would return 1, if any error  occured. 0 for success
	** and 2 for issuing fetch again on the last row
	*/
	if (@@sqlstatus = 1)
	begin
        	select @retstat = 1
        	goto clean_all
	end

	if (@retstat != 0)
	begin
		goto clean_all
	   	select @retstat = 1
	end	

	/* Close and de allocate the cursor */
	clean_all:
	if (@clean_cursor = 1)
	begin
        	close sysdatabases_curs
        	deallocate cursor sysdatabases_curs
	end

	/* Ok now set the proxy database state in the remote server */
	if (@retstat = 0)
	begin
		exec @retstat = sp_remotesql "SYB_HACMP",
       				"sp_haupdproxydbstate 'setdb3state'"
		if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
			select @retstat = 1
	end
	return(@retstat)
end
else if (@action = "drop")
begin
	/* Drop the proxy databases in the local server */
	dbcc drop_haproxydbs
	if (@@error != 0)
	begin
		Print "Proxy databases could not be dropped"
		return(1)
	end

	/* Ok now clear the proxy database state in the remote server */
	exec @retstat = sp_haupdproxydbstate 'cleardb3state'
	if ((@retstat != 0) or (@@error != 0))
		return(1)
		
	/* Drop the proxy databases in the remote server */
	if (@servername is not null)
	begin
	     /* Failure to drop remote proxies will print error */
		exec @retstat = sp_remotesql @servername, 
					"dbcc drop_haproxydbs"	
		if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
			return(1)
		exec @retstat = sp_remotesql @servername, 	
					"sp_haupdproxydbstate 'cleardb3state'"
		if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
			return(1)
	end

	return(@retstat)
end
else
	print "Invalid 'action' specification for procedure 'sp_haproxydb'"
	return(1)
go
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_ha_admin')
begin
	drop procedure sp_ha_admin
end
go
print "Installing sp_ha_admin"
go


/*
** Messages for "sp_ha_admin"
**
** 17260, "Can't run %1! from within a transaction."
** 
*/
create procedure sp_ha_admin 
	@cmd 	varchar(30) = null,
	@opt1	varchar(30) = null,
	@opt2	varchar(30) = null
as

declare @sessionrowcount int

/*
**  If we're in a transaction, disallow this since it might make recovery
**  impossible.
*/
if @@trancount > 0
begin
        /*
        ** 17260, "Can't run %1! from within a transaction."
        */
        raiserror 17260, "sp_ha_admin"
        return (1)
end
else
begin
        set chained off
end
set transaction isolation level 1

/* 
**  Check if user has ha role.  proc_role() will do auditing
**  if required and will also print error message if required.
*/
if (proc_role("ha_role") = 0)
        return (1)


/*
**  Begin command processing.
*/

/* Help! */
if (@cmd = "help") or (@cmd is NULL)
begin
	print "sp_ha_admin Usage: sp_ha_admin command [, option1 [, option2]]"
	print "sp_ha_admin commands:"
	print "sp_ha_admin 'cleansessions'"
	print "sp_ha_admin 'help'"
end
else begin 
/* Clean syssessions */
if (@cmd = "cleansessions")
begin
	select @sessionrowcount = count(ses_id)
		from master..syssessions

	if (@sessionrowcount = 0)
		return (0)

	dbcc  ha_admin ("SYB_HACMP", "delstalerows")
	if (@@error != 0)
	begin
        	return(1)
	end

end
else
begin
	/* Invalid command parameter */
	print "sp_ha_admin Usage: sp_ha_admin command [, option1 [, option2]]"
	print "sp_ha_admin commands:"
	print "sp_ha_admin 'cleansessions'"
	print "sp_ha_admin 'help'"
        return(1)
end
end

return (0)
go
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hasyncuserinfo')
begin
	drop procedure sp_hasyncuserinfo
end
go
print "Installing sp_hasyncuserinfo"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */

create procedure sp_hasyncuserinfo
@servername varchar(255),
@skip_error int,
@check_only int,
@attrib_id int
as
declare @retstat int			/* return value of executing a SQL */

	/*
	** IMPORTANT:  DO NOT modify the order in which these synchronizations
	** happen.  This sequence of operations is very important for the
	** catalogs to get sync'd up correctly during configuration time.
	*/

	print "Step: Synchronizing Application Specific information from companion server"
	exec @retstat = sp_hasyncapps @servername, 
					@skip_error, @check_only, @attrib_id
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	print "Step: Synchronizing Roles from companion server"
	exec @retstat = sp_hasyncsrvroles
	if ((@retstat != 0) or (@@error != 0))
		return(1)
	
	print "Step: Synchronizing Login Roles from companion server"
	exec @retstat = sp_hasyncloginroles
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	print "Step: Synchronizing Remote Logins from companion server"
	exec @retstat = sp_hasyncrmtlogins
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	print "Step: Synchronizing Groups in sysusers from companion server"
	exec @retstat = sp_hasyncgrouproles
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	print "Step: Synchronizing Sysattributes from companion server"
	exec @retstat = sp_hasyncsysattrs
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	/* 
	** Up until this point, we replicated some of the catalogs on the
	** local server.  Now we will begin to sync. up the logins and
	** make appropriate updates to related system catalogs
	*/

	print "Step: Synchronizing server logins from companion server"
	exec @retstat = sp_hasynclogins 
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	print "Step: Synchronizing server-wide privs from companion server"
	exec @retstat = sp_hasyncpermissions @servername, 
					@skip_error, @check_only, @attrib_id
	if ((@retstat != 0) or (@@error != 0))
		return(1)

	return(0)
go
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_loglocalstate')
begin
	drop procedure sp_loglocalstate
end
go
print "Installing sp_loglocalstate"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/* Stored procedure for binding entites to named caches.  Entity must
** be the name of a database, table or index.
**
** Databases can only be bound when using Master.
** The Master database cannot be bound to a named cache, but individual
** tables in Master can.
*/

/*
** Messages for "sp_logstate"	18086
**
*/
create procedure sp_loglocalstate
@servername	varchar(30),
@operation	varchar(30),
@new_state	int,	
@loginname	varchar(30),
@option		int = 0
as
declare @srvid	int
declare @status	int
declare @action int
declare @aiobject int
declare @sysattrtype char(2)
declare @statename char(10)
declare @nextstate int
declare @currstate int
declare @maxdbid   int
declare @msg varchar(255)	
declare @cfgstatus int

/* Initialize the status */
select @status = 0, @currstate = @@cmpstate

begin
	set transaction isolation level 1
end

/*
** action can be just to start the configuration
*/

/*
** Map entity type to attribute type.  Note that the attribute manager
** needs a two-byte string...
*/
select @sysattrtype = 'S' + " "
	
select @aiobject  = 1275

/* first cleanup any leftover state if int_value = 0 */
delete from master..sysattributes where
	class = 10 AND
	attribute = 7 AND
	object_type = @sysattrtype AND
	object = 1275 AND
	int_value = 0

/* Figure out if we need to insert, update or delete from sysattributes. */
begin tran logstate
if (@servername is not NULL)
BEGIN
	select @statename = "newstate"
	
	if exists(select * from master..sysattributes where
		class = 10 AND
		attribute = 7 AND
		object_type = @sysattrtype AND
		object = 1275) 
	BEGIN
		select @action = 2 /* ATTR_CHANGE */
	END
	ELSE
	BEGIN
		select @action = 1 /* ATTR_ADD */
	END
END
ELSE
BEGIN
	select @action = 3 /* ATTR_DROP */
END

if @action = 1
BEGIN
	/* remove the following after a permanent fix is invented */
	select @srvid = 2
	if (@new_state = 7)
		select @srvid = 1
	/*
	** dbids from 31512 to 31767 (0x7b18 - 0x7c17 ) are reserved
	** for system databases (MINSYSDBID)
	*/
	select @maxdbid = max(dbid) from master..sysdatabases
			where dbid < 31512
	select @cfgstatus = 0
	if @new_state = 2
       		select @cfgstatus = 1

	/*
	** If the option passed in indicates that we need to
	** set the perticular cfgstatus, do so.
	*/
	if @option & 1 in (1)
	begin
		/* enable HA proxydb requested, HACFG_HAPROXYDB_ENABLED */
		select @cfgstatus = @cfgstatus | 4
	end
	
	if @option & 2 in (2)
		/* disable HA proxydb requested,  HACFG_HAPROXYDB_ENABLEDi */
		select @cfgstatus = @cfgstatus & ~4

	insert into sysattributes 
		(class, attribute, object_type, object, 
		 object_info1, object_info2, object_info3, 
			char_value, int_value, comments)
		VALUES
		(10,	/* HA INFO */
		 7,	/* State information */
		 @sysattrtype,
		 @aiobject,
		 @srvid,
		 @cfgstatus, @maxdbid, 
		 @statename,
		 @new_state,
		 @loginname
		)
	/* Initialize the nextstate for logging to error log */
	select @nextstate = @new_state
END

if @action = 2
BEGIN
	/*
	** Get the current value of cfgstatus and update, if we have to
	*/
	select @cfgstatus = object_info2 from master.dbo.sysattributes
			where   class = 10 AND
				attribute = 7 AND
				object_type = @sysattrtype AND
				object = @aiobject 

	/* disable HA proxydb requested,  HACFG_HAPROXYDB_ENABLED */
	if @option & 2 in (2)
		select @cfgstatus = @cfgstatus & ~4

	/* Mark node for suspend/prepare_failback executed in this node */ 
	if @option & 4 in (4)
		select @cfgstatus = @cfgstatus  | 8

	/* Unmark node for resume execution */ 
	if @option & 8 in (8)
		select @cfgstatus = @cfgstatus  & ~8

	update master.dbo.sysattributes
		set 	int_value = @new_state, object_info2 = @cfgstatus
		where	class = 10 AND
			attribute = 7 AND
			object_type = @sysattrtype AND
			object = @aiobject 

	/* Initialize the nextstate for logging to error log */
	select @nextstate = @new_state
END

if @action = 3
BEGIN
	delete from sysattributes
			where	class = 10 AND
				attribute = 7 AND
				object_type = @sysattrtype AND
				object = @aiobject

	/* Initialize the nextstate for logging to error log */
	select @nextstate = 0 
END

commit tran logstate	

select @msg = "HA_LOG:State Change:Server changing state from  " + 
		convert(char(2), @currstate) + " to " + 
		convert(char(2), @nextstate) 

/* Resets the state info in the memory */
dbcc ha_admin(" ", "reset_validstate")

dbcc printolog(@msg)
return @status
go
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_logremotestate')
begin
	drop procedure sp_logremotestate
end
go
print "Installing sp_logremotestate"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
**
** Error Messages:
**
** 18771:"Could not convert the state into varchar"
*/

create procedure sp_logremotestate 
	@servername varchar(255),
	@operation  varchar(20),
	@newstate   int,
	@loginname  varchar(20),
	@option     int = 0
as
declare @status int
declare @newVstate varchar(10)
declare @newoption varchar(10)

	select @newVstate = convert(varchar(10), @newstate)
	select @newoption = convert(varchar(10), @option)
	if (@@error != 0)
	begin
		raiserror 18771
		return(1)
	end
	select @operation = ", " + @operation + ", "
	select @loginname = ", " + @loginname + ", "

	exec @status = sp_remotesql @servername,  "sp_loglocalstate ", @servername, @operation, @newVstate, @loginname, @newoption
	if ((@status != 0) or (@@error != 0) or (@@transtate = 3))
		return (1)
go
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpcfgvrfy')
begin
	drop procedure sp_hacmpcfgvrfy
end
go
print "Installing sp_hacmpcfgvrfy"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpcheckdevices')
begin
	drop procedure sp_hacmpcheckdevices
end
go
print "Installing sp_hacmpcheckdevices"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpcheckdatabase')
begin
	drop procedure sp_hacmpcheckdatabase
end
go
print "Installing sp_hacmpcheckdatabase"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_havalidatelogin')
begin
	drop procedure sp_havalidatelogin
end
go
print "Installing sp_havalidatelogin"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_havalidatealias')
begin
	drop procedure sp_havalidatealias
end
go
print "Installing sp_havalidatealias"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_havalidatermtlogins')
begin
	drop procedure sp_havalidatermtlogins
end
go
print "Installing sp_havalidatermtlogins"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpchecklogins')
begin
	drop procedure sp_hacmpchecklogins
end
go
print "Installing sp_hacmpchecklogins"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpcheckroles')
begin
	drop procedure sp_hacmpcheckroles
end
go
print "Installing sp_hacmpcheckroles"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpcheckappres')
begin
	drop procedure sp_hacmpcheckappres
end
go
print "Installing sp_hacmpcheckappres"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpcheckapps')
begin
	drop procedure sp_hacmpcheckapps
end
go
print "Installing sp_hacmpcheckapps"
go

if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpchecksysattribs')
begin
	drop procedure sp_hacmpchecksysattribs
end
go
print "Installing sp_hacmpchecksysattribs"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
** SP_HACMPCFGVRFY
** This stored procedure verifies that configurations of the
** local server with respects to remote server are compatible
** and reports discripencies if any.
**
** Error Messages:
**
** Error 18738:Database '%1!': a 'proxy' database or database having 'proxy' 
** 		exists. Drop this database and retry the configuration again. 
** Error 18739:Database '%1!': a user database exists. Drop this database and 
** 		retry the configuration again. 
** Error 18740:Server '%1!' has remote server definitions other than defaults.
**		Drop the non-default servers and retry the configuration again.
** Error 18741:Server '%1!' has remote logins defined. Please drop all remote
**		logins and retry the configuration again.
** Error 18742:Server '%1!' has logins defined other than defaults. Please drop
**		all other logins and retry the configuration again. 
** Error 18743:Server '%1!' has login roles defined other than defaults. Please
**		drop all other login roles and retry the configuration again.
** Error 18744:Server '%1!' has roles defined other than defaults. Please
**              drop all other roles and retry the configuration again. 
** Error 18745:Server '%1!' has alternate logins defined. Please drop all 
**		alternate logins and retry the configuration again. 
** Error 18746:Server '%1!' has users in masterdb defined other than defaults. 
**		Please drop all other users and retry the configuration again.
** Error 18747:Server '%1!' has roles in masterdb defined other than defaults. 
**		Please drop all other roles and retry the configuration again.
*/
create procedure sp_hacmpcfgvrfy
@servername varchar(30)  = null,	/* Name of the primary server */
@action	    varchar (20)		/* desired companion action */
as
declare @suid      int,            	/* suid to be inserted */
	@status	   smallint, 		/* original status */
	@retstat   int,			/* return value of executing a SQL */
	@isproxy   int,			/* Database is a proxy database */
	@hasproxy  int,			/* Database has a proxy database */
	@cmpstate  int,			/* Companion server state */
	@xpsrvr_local varchar(30),	/* name of the local_XP server */
	@xpsrvr_remote varchar(30),	/* name of the remote XP server */
	@dbstatus3 int,			/* Databases status ( proxy related )*/
	@tempdb_mask   int,   	/* All database status bit for a tempdb */
	@dbid	   int,			/* Database id */
	@name	   varchar(30),		/* Generic Name */
	@sybstmdbid int,		/* Database id */
	@hasuserdb int,			/* User databases exists */
	@clean_dbname_cursor int,	/* Clean up all the cursors */
	@localservername varchar(30)	/* name of the local server */

/* Initialize the defaults */
select @retstat = 0, @clean_dbname_cursor = 0, @hasuserdb = 0, 
       @localservername = @@servername

select @tempdb_mask = number
	from master.dbo.spt_values
	where type = "D3" and name = "TEMPDB STATUS MASK"

/*
** Get the Current Server State. At this stage we have already established
** the server-server compatibility for cluster configuration. Only based
** on the server state we need to run through different types of verification
*/
select @cmpstate = @@cmpstate

/*
** Verification of companions are done for different purposes
** In the case where we are configuring the server for the 
** first time, there are certain things that absolutely must
** not exists. These are hard requirements. 
*/
if (@cmpstate = 0 )
begin
	/* 
	** Verify that there are no user databases in the server other than
	** the system databases and user temp databases.
	*/
	select @isproxy  = 2 
	select @hasproxy = 4
 
	declare sysdatabases_curs cursor  for select name, status3
		from master.dbo.sysdatabases 
		where (status3 & @tempdb_mask) = 0 
	open sysdatabases_curs
	select @clean_dbname_cursor = 1
	fetch sysdatabases_curs into @name, @dbstatus3
	while (@@sqlstatus = 0)
	begin
		if (@name NOT IN ("master", "model","tempdb","sybsystemdb",
				  "sybsystemprocs","dbccdb","sybsecurity",
				  "dbccalt","sybsyntax","sybmgmtdb","sybpcidb"))
		begin
			/*
			** User Database exists; This might even be a
			** left-over proxy database or database having
			** the proxy bit set; Identify that and infor
			** user appropriately.
			*/
			select @isproxy = (@dbstatus3 & 2), 
				@hasproxy = (@dbstatus3 & 4)
			if (@isproxy !=0 or @hasproxy !=0)
				raiserror 18738, @name
			else
				raiserror 18739, @name
			
			/* 
			** If the trace is on, then do not  set
			** variables to report error, skip it.
			*/
			dbcc istraceon(2209)
			if @@error != 0
			begin
				select @retstat = 1	
				select @hasuserdb = 1	
			end
		end
		fetch sysdatabases_curs into @name, @dbstatus3
	end

	/*
	** fetch would return 1, if any error  occured. 0 for success
	** and 2 for issuing fetch again on the last row
	*/
	if (@@sqlstatus = 1)
	begin
       		select @retstat = 1
       		goto clean_all
	end

	close sysdatabases_curs
	deallocate cursor sysdatabases_curs
	select @clean_dbname_cursor = 0
end

clean_all:
	/* Close and de allocate the cursor */
if (@clean_dbname_cursor = 1)
begin
	close sysdatabases_curs
	deallocate cursor sysdatabases_curs
end

/*
** If we have requested to ignore the warning
** and there are no fatal error like having the
** user databases; return true
*/
if (@action = "override")
begin
	/*
	** The following indicates the list of hard errors where
	** it is catastrophic to continue;
	*/
	if (@hasuserdb = 1)
	begin
		return(1)
	end
	else
	begin
		return(0)
	end
end
return(@retstat)
go


/*
** SP_HACMPCHECKDEVICES
**
** Description:
**	This stored procedure's function is to do compatibility checks related
** to devices across the companions. The following attributes related to devices
** are checked.
**
**
** Parameters:
**		@servername	: Name of the Companion server -- Input
**		@skip_error	: Skip on encountering an error-- Input
**		@check_only	: Check only 		       -- Input
**		@attrib_id	: Attribute ID 		       -- Input
**		@option		: to indicate some context     -- Input 
** Design: 
**
** 	Attribute ID 1400: This attributes basically verifies that the
** logical devices names across the nions be unique. 
** 
** Error Messages:
**
** Returns:
**		0 on success, 1 on failure.
*/
create procedure sp_hacmpcheckdevices
@servername varchar(30)  = null,	/* Name of the primary server */
@skip_error int,			/* Skip the check on error */
@check_only int,			/* Check only */	
@attrib_id  int,			/* attribute Id of interest */
@option	    int 			/* Additional option */
as
declare 
	@retstat   int,			/* return value of executing a SQL */
	@computed_advisory int,		/* Advisory for the attribute */
	@attrib_name varchar(80),	/* Attribute name */
	@comment varchar(255),		/* Comments */
	@low	   int,			/* low of vstart of a device */
	@high	   int,			/* high of vstart of a device */
	@name	   varchar(30),		/* name of the database */
	@logrecord int,			/* to log or not */
	@attrib_type varchar(32)	/* Base type of the attribute */

/* 17260, "Can't run %1! from within a transaction." */
if @@trancount != 0
begin
	raiserror 17260, "sp_hacmpcheckdevices"
	return (1)
end

dbcc istraceon(2227)
if @@error != -1
begin
	print "Proc name = '%1!'", "sp_hacmpcheckdevices" 
	print "Servername Id = '%1!'", @@servername
	print "Attribute Id = '%1!'", @attrib_id
end

/* Check for valid Base attribute Id */
if @attrib_id != 0
begin
	if not exists (select 1 from tempdb.dbo.ha_advisory_attrs where
				attrib_id = @attrib_id and @attrib_id > 999)
	begin
		print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
		return(1)
	end
end

/* Initialize the variables */
select 	@comment = "Compatible unique device names", 
	@retstat = 0,
	@logrecord = 0

/* Check if trace 2202 is on; or Check only is on, log the record. */	
dbcc istraceon(2202)
if @@error != -1 
begin
	select @logrecord = 1
end

/* Validate Attribute Id */
if @attrib_id = 0 or @attrib_id < 1000
begin
	print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
	return (1)
end

/* Get the attribute type based on the attribure id */
select @attrib_type = attrib_type from tempdb.dbo.ha_advisory_attrs 
			 where attrib_id = @attrib_id
set nocount on

/*
** (unique) Devices names
*/
if (@attrib_id = 1400)
begin
	select @attrib_name = "Unique Devnames"
	declare sysdevices_curs cursor for select name, low, high
		from master.dbo.sysdevices where 
		name not in ("master", "tapedump", "tapedump2", "tapedump1",
				"systemdbdev", "sysprocsdev", "d_master")
	open sysdevices_curs
	fetch sysdevices_curs into @name, @low, @high
	while (@@sqlstatus = 0)
	begin
		/* Check if trace 2202 is on; log the record. */	
		dbcc istraceon(2202)
		if @@error != -1 
		begin
			select @logrecord = 1
		end
		else
		begin
			select @logrecord = 0
		end
		/* initialize @computed_advisory */
		select 	@computed_advisory = 0 

		if exists (select 1 from master.dbo.rmt_ha_sysdevices 
						where name = @name)
		begin
			/* If there is failure in accessing the remote table */
			if @@error != 0 or @@transtate = 3
			begin
				select @retstat = 1
				goto clean_devcurs
			end

			select @logrecord = 1, 
				@comment = "Non unique logical names",
			       	@computed_advisory = 2
		end

		if @logrecord = 1
		begin
			exec @retstat = sp_ha_logadvisory_rec @attrib_name, 
				@attrib_type, @attrib_id, NULL, 
				@name, 0,  @name, 0,  
				@computed_advisory, @comment 

			if @retstat != 0
				goto clean_devcurs	
		end

		fetch sysdevices_curs into @name, @low, @high
	end

	/*
	** fetch would return 1, if any error  occured. 0 for success
	** and 2 for issuing fetch again on the last row
	*/
	if (@@sqlstatus = 1)
       		select @retstat = 1

clean_devcurs:
	close sysdevices_curs
	deallocate cursor sysdevices_curs
	return (@retstat)
end
go


/*
** SP_HACMPCHECKDATABASE
**
** Description:
**	This stored procedure's function is to do compatibility checks related
** to databases across the companions. The following attributes related to 
** databases are checked.
**
**	Attrib ID : 1600 Unique Dbids
**
**	All the user databases that are in primary should have a dbid that
** should not be used up in the local server. If the same database exists
** they better be proxy database pairs of each other.
**
**	It outputs as atribute names 'HA proxy pair" or 'Conflicting Dbid'
** for incompatibilities.
**
**      Attrib ID : 1610 Database options
**
**      All the proxy database pairs across the companions, created due to the
** 'with_proxydb' option, should have the same value for the database option
** 'select into/bulkcopy/pllsort'.
**
**	It outputs as atribute name 'select into/bulkcopy' for 
** incompatibilities.
**
** Parameters:
**		@servername	: Name of the Companion server -- Input
**		@skip_error	: Skip on encountering an error-- Input
**		@check_only	: Check only 		       -- Input
**		@attrib_id	: Attribute ID 		       -- Input
**		@option		: to indicate some context     -- Input 
** Design: 
**
** 
** Error Messages:
**
** Returns:
**		0 on success, 1 on failure.
*/
create procedure sp_hacmpcheckdatabase
@servername varchar(30)  = null,	/* Name of the primary server */
@skip_error int,			/* Skip the check on error */
@check_only int,			/* Check only */	
@attrib_id  int,			/* attribute Id of interest */
@option	    int 			/* Additional option */
as
declare 
	@retstat   int,			/* return value of executing a SQL */
	@attrib_name varchar(80),	/* Attribute name */
	@comment   varchar(255),	/* Comments */
	@dbname	   varchar(32),		/* name of the database */
	@ldbname   varchar(32),		/* name of the database */
	@dbid   int,			/* Dbid */
	@status3   int,			/* Status3 bits for the database */
	@tempdb_mask int,	/* All database status bit for a tempdb */
	@logrecord int,			/* to log or not */
	@attrib_type varchar(32),	/* Base type of the attribute */
        @ldbid      smallint,           /* Database id of local database */
        @rdbid      smallint,           /* Database id of remote database */
	@lstatus    int,                /* Status bits for the local database */
	@rstatus    int,                /* Status bits for the remote database*/
	@lstatus3   int,		/* Status3 bits for the local database*/
	@rstatus3   int,		/*Status3 bits for the remote database*/
	@lvalue	    varchar(32),	/* Local value of dboption(dbid) */
	@rvalue	    varchar(32),        /* Remote value of dboption(dbid) */
	@optmask    int			/* Option mask for database option */

/* 17260, "Can't run %1! from within a transaction." */
if @@trancount != 0
begin
	raiserror 17260, "sp_hacmpcheckdatabase"
	return (1)
end

dbcc istraceon(2227)
if @@error != -1
begin
	print "Proc name = '%1!'", "sp_hacmpcheckdatabase" 
	print "Servername Id = '%1!'", @@servername
	print "Attribute Id = '%1!'", @attrib_id
end

/* Validate Attribute Id */
if @attrib_id = 0 or @attrib_id < 1000
begin
	print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
	return (1)
end

/* Check for valid Base attribute Id */
if @attrib_id != 0
begin
	if not exists (select 1 from tempdb.dbo.ha_advisory_attrs where
				attrib_id = @attrib_id)
	begin
		print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
		return(1)
	end
end

/* Initialize the variables */
select 	@comment = " ", @retstat = 0, @logrecord = 0

select @tempdb_mask = number
	from master.dbo.spt_values
	where type = "D3" and name = "TEMPDB STATUS MASK"

/* Get the attribute type based on the attribure id */
select @attrib_type = attrib_type from tempdb.dbo.ha_advisory_attrs 
			 where attrib_id = @attrib_id
set nocount on

/*
** (unique) Database Ids:
** 	Databases in the current local servers should have a dbid such
** that the user databases in the remote server will be able to aquire
** that in the local servers. In case if it is used up in the local
** server, it better be same database. However, systemdatabases in
** the remote  can have any database id wrt to local ( same or non
** -overlapping ). Why ? After the failover, the user databases should
** be able to maintain the same dbid.
*/
if (@attrib_id = 1600)
begin
	declare sysdatabases_curs cursor for select name, status3, dbid
		from master.dbo.rmt_ha_sysdatabases where 
		name not in ("sybsystemdb", "sybsecurity", "dbccdb", "dbccalt",
				"sybsyntax", "sybsystemprocs",
				"sybmgmtdb", "sybpcidb") and dbid > 3 
	open sysdatabases_curs
	fetch sysdatabases_curs into @dbname, @status3, @dbid
	while (@@sqlstatus = 0)
	begin
		/* Initialize for every record */
		select @logrecord = 0

		/* Check if dbid is being used by other databases */
		if exists (select 1 from master.dbo.sysdatabases where 
					dbid = @dbid or name = @dbname)
		begin
			/* Check if the same database name exists */
			if exists (select 1 from master.dbo.sysdatabases 
					where name = @dbname)
			begin
				/* They better be HA proxy pair */
				if (@status3 & 2 = 2)
				begin
					if not exists ( select 1 from 
							master.dbo.sysdatabases 
							where name = @dbname 
							and status3 & 4 = 4 )
					begin
						/* Log an advisory rec */
						select @logrecord = 1	
					end
				end
				else	
				if (@status3 & 4 = 4)
			   	begin
					if not exists ( select 1 from 
						master.dbo.sysdatabases 
						where name = @dbname 
						and status3 & 2 = 2 )
					begin
					     /* Log an advisory rec */
						select @logrecord = 1	
					end
				end
				/* 
				** These are user or temp database. They
				** can not have same names. Log an advisory.
				*/
				else
				begin
					select @logrecord = 1	
				end	
			end

			/* The dbid is being used by some other database */
			else
			begin
				/*
				** If the Databases are clashing on the dbid
				** space they better be both user tempdbs and 
				** have different name.
				*/
				if (@status3 & @tempdb_mask != 0)
				begin
					if not exists ( select 1 from 
						master.dbo.sysdatabases	
						where dbid = @dbid and 
						status3 & @tempdb_mask != 0)
					begin
						/* Log an advisory rec */
						select @logrecord = 2
					end	

				end		
				else
				begin
					/* Log an advisory rec */
					select @logrecord = 2
				end
			end
		end	

		/* Log the advisory */
		if @logrecord = 1
		begin
			select @attrib_name = "HA proxy pair"
			exec @retstat = sp_ha_logadvisory_rec 
				@attrib_name, @attrib_type, @attrib_id,
				NULL, @dbname, 0,  @dbname, 0, 2 

			if @retstat != 0
				goto clean_dbcurs	
		end

		dbcc istraceon(2202)
		if  (@@error != -1 or @logrecord = 2) 
		begin
			select @attrib_name = "Conflicting Dbids"
			select @ldbname = name from master.dbo.sysdatabases
					where dbid = @dbid

			if @logrecord = 2
				exec @retstat = sp_ha_logadvisory_rec 
					@attrib_name, @attrib_type, @attrib_id,
					NULL, @ldbname, 0,  @dbname, 0, 2
			else 
			if @logrecord != 1
				exec @retstat = sp_ha_logadvisory_rec 
					@attrib_name, @attrib_type, @attrib_id,
					NULL, @ldbname, 0,  @dbname, 0, 0
				
			if @retstat != 0
				goto clean_dbcurs	
		end

		fetch sysdatabases_curs into @dbname, @status3, @dbid
	end

	/*
	** fetch would return 1, if any error  occured. 0 for success
	** and 2 for issuing fetch again on the last row
	*/
	if (@@sqlstatus = 1)
       		select @retstat = 1
end

/*
** CR 263126-1 : Both the databases in the proxy database pairs, created by the
** HA configuration with the 'with_proxydb' option, should have the database 
** option, 'select into/bulkcopy/pllsort' set in order to allow AMC commands to 
** proceed in that database. So, report different values of the database option 
** as an incompatibility.
*/
if (@attrib_id = 1610)
begin
	select @attrib_name = "select into/bulkcopy/pllsort"

	select @optmask = number from master.dbo.spt_values 
			      where name = "select into/bulkcopy/pllsort"

        declare sysdatabases_curs cursor for select name, dbid, status, status3
                from master.dbo.rmt_ha_sysdatabases where
                name not in ("sybsystemdb", "sybsecurity", "dbccdb", "dbccalt",
                                "sybsyntax", "sybsystemprocs",
					"sybmgmtdb", "sybpcidb") and dbid > 3
        open sysdatabases_curs
        fetch sysdatabases_curs into @dbname, @rdbid, @rstatus, @rstatus3

        while (@@sqlstatus = 0)
        begin
		/* If a proxy database pair exists. */
		if exists (select 1 from master.dbo.sysdatabases 
			   where name = @dbname)
                begin
                        select @ldbid = dbid, @lstatus = status,
                                @lstatus3 = status3 from master.dbo.sysdatabases
                                where name = @dbname

			/*
			** And they were created due to the 'with_proxydb' 
			** option. 
			*/
			if (( @lstatus3 & 4 = 4 and @rstatus3 & 2 = 2 ) or
		 	    ( @lstatus3 & 2 = 2 and @rstatus3 & 4 = 4 ))
			begin
				/* Initialize the variables */
				select @lvalue = '0', @rvalue = '0'

				if ( @optmask = @lstatus & @optmask )
					select @lvalue = '1'
				if ( @optmask = @rstatus & @optmask )
					select @rvalue = '1'	

				if (@lvalue != @rvalue)
				begin
                                        select @lvalue = @lvalue +
                                                "(dbid:" +
                                                convert(varchar, @ldbid)
                                                + ")"
                                        select @rvalue = @rvalue +
                                                "(dbid:" +
                                                convert(varchar,@rdbid)
                                                + ")"

					exec @retstat = sp_ha_logadvisory_rec 
						@attrib_name, @attrib_type, 
						@attrib_id, NULL, @lvalue, 0, 
						@rvalue, 0, 2
					if @retstat != 0
						goto clean_dbcurs
				end
			end
		end
		fetch sysdatabases_curs into @dbname, @rdbid, @rstatus, @rstatus3
	end
	/*
        ** fetch would return 1, if any error  occured. 0 for success
        ** and 2 for issuing fetch again on the last row
        */
        if (@@sqlstatus = 1)
                select @retstat = 1
end

clean_dbcurs:
close sysdatabases_curs
deallocate cursor sysdatabases_curs

set nocount off
return (@retstat)
go

/*
** SP_HAVALIDATELOGIN
**
** Description:
**	This stored procedure's function is to do validate the compatibility
**	of the given login from the remote server against the local server.
** 	Refer to sp_hacmpchecklogins for a detailed explanation.
**
** Parameters:
**		@rmt_suid	: suid from the remote server -- Input
**		@rmt_name	: login name from remote server -- Input
**		@attrib_id	: Attribute ID 		       -- Input
**		@logrecord	: Should advisory be logged? -- Input 
**		@advisory	: output advisory -- Output
** 
** Error Messages:
**
** Returns:
**		0 on success, 1 on failure.
*/
create procedure sp_havalidatelogin
@rmt_suid int,			/* suid from a remote server */
@rmt_name varchar(30),		/* login name from a remote server */
@attrib_id  int,		/* attribute Id of interest */
@logrecord tinyint = 1,		/* Should any advisory be logged? */	
@advisory int = 0 output 	/* Output advisory */
as
declare 
	@retstat   int,			/* return value of executing a SQL */
	@attrib_name varchar(80),	/* Attribute name */
	@comment varchar(255),		/* Comments */
	@name  varchar(30),		/* login name in local server */
	@default_login  tinyint,	/* 1 if default login, else 0 */
	@lcharval  varchar(32),		/* local char value */
	@attrib_type varchar(32)	/* Base type of the attribute */

/* Attribute Id should 2100 */
if @attrib_id != 2100
begin
	print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
	return (1)
end
select @attrib_name = "Non Default Logins", @retstat = 0
select @attrib_type = attrib_type from tempdb.dbo.ha_advisory_attrs where
				attrib_id = @attrib_id 
select @name = NULL

if (@rmt_name in ('sa','probe','qcollector','qrepository', 'mon_user')) 
	select @default_login = 1
else
	select @default_login = 0

/* Get the login name on the local with same suid as in remote */
select @name = name from master.dbo.syslogins 
	where suid = @rmt_suid

if (@name is not NULL)	/* same suid exists in the local server */
begin
	/* login name is conflicting with that in the local server */
	if (@name != @rmt_name)
	begin
		/* Non default login */
		if (@default_login = 0)
		begin
			select @advisory = 2
			if (@logrecord = 1)
			begin
				select @comment = "Mismatch in login name"
				exec @retstat = sp_ha_logadvisory_rec 
						@attrib_name, 
						@attrib_type, @attrib_id, NULL, 
						@name, 0, @rmt_name, 0,  
						@advisory, @comment 
				if @retstat != 0
					return (@retstat)
			end
		end
	end
end
else
begin	/* Missing suid on the local server */
	/* If server not in single server mode, flag a soft fault */
	if (@@cmpstate > 0)
	begin
		select @advisory = 1
		if (@logrecord = 1)
		begin
			select @comment = "Missing suid on the local server"
			exec @retstat = sp_ha_logadvisory_rec 
					@attrib_name, 
					@attrib_type, @attrib_id, NULL, 
					NULL, 0, NULL, @rmt_suid,  
					@advisory, @comment 
			if @retstat != 0
				return (@retstat)
		end
	end
end

return (0)

go


/*
** SP_HAVALIDATEALIAS
**
** Description:
**	This stored procedure's function is to do compatibility checks related
** to aliases across the companions. The following checks are done to determine
** the compatibility of the two servers:
**
**	a) For all logins in the remote server, the pair (suid, altsuid) in
**	   sysalternates catalog must match exactly on the local server.  If
**	   not, this is treated as a hard fault.
**
** Parameters:
**		@rmt_suid	: suid from remote server -- Input
**		@attrib_id	: Attribute id (should be 2100) -- Input
**		@logrecord	: Should advisory be logged -- Input
**		@advisory	: Output advisory -- Output
**
** Error Messages:
**
** Returns:
**		0 on success, 1 on failure.
*/
create procedure sp_havalidatealias
@rmt_suid int,				/* suid from remote server */
@attrib_id  int,			/* attribute Id of interest */
@logrecord  tinyint = 1,		/* Should advisory be logged? */
@advisory int = 0 output		/* Ouput advisory */
as
declare 
	@retstat   int,			/* return value of executing a SQL */
	@attrib_name varchar(80),	/* Attribute name */
	@comment varchar(255),		/* Comments */
	@altsuid  int,			/* altsuid in local server */
	@rmt_altsuid  int,		/* altsuid in remote server */
	@suid  int,			/* suid in local server */
	@lcharval  varchar(32),		/* local char value */
	@rcharval  varchar(32),		/* remote char value */
	@attrib_type varchar(32)	/* Base type of the attribute */

/* Initialize the variables */
select 	@attrib_name = "Aliases",
	@retstat = 0

/* Attribute Id should 2100 */
if @attrib_id != 2100
begin
	print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
	return (1)
end

set nocount on
select @attrib_type = attrib_type from tempdb.dbo.ha_advisory_attrs where
				attrib_id = @attrib_id 

select @rmt_altsuid = NULL
select @altsuid = NULL
select @suid = NULL
select @rmt_altsuid = altsuid from master.dbo.rmt_ha_sysalternates 
		where suid = @rmt_suid
if (@rmt_altsuid is not NULL)
begin
	select @altsuid = altsuid, @suid = suid from master.dbo.sysalternates 
		where suid = @rmt_suid 

	/* There's no identical (suid, altsuid) in local server */
	if (@altsuid is not NULL)
	begin
		if (@altsuid != @rmt_altsuid)
		begin
			select @advisory = 2
			if (@logrecord = 1)
			begin
				select @comment = 
					"Alias mismatch in sysalternates"
				select @lcharval = "(" + 
					convert(varchar(11),@suid) + "," +
				   	convert(varchar(11), @altsuid) + ")"
						
				select @rcharval = "(" + 
					convert(varchar(11),@rmt_suid) + "," +
				   	 convert(varchar(11), @rmt_altsuid) + ")"
				exec @retstat = sp_ha_logadvisory_rec 
						@attrib_name, 
						@attrib_type, @attrib_id, NULL, 
						@lcharval, 0, @rcharval, 0,  
						@advisory, @comment 
				if @retstat != 0
					return (@retstat)
			end
		end
	end
	else	/* there is no matching (suid, altsuid) pair in the local */
	begin	/* If server not in single server mode, flag a soft fault */
		if (@@cmpstate > 0)	
		begin
			select @advisory = 1
			if (@logrecord = 1)
			begin
				select @comment = 
					"Missing Alias in local sysalternates"
				select @rcharval = "(" + 
					convert(varchar(11),@rmt_suid) + "," +
				   	convert(varchar(11), @rmt_altsuid) + ")"
				exec @retstat = sp_ha_logadvisory_rec 
						@attrib_name, 
						@attrib_type, @attrib_id, NULL, 
						NULL, 0, @rcharval, 0,  
						@advisory, @comment 
				if @retstat != 0
					return (@retstat)
			end
		end
	end
end 

return (0)

go

/*
** SP_HAVALIDATERMTLOGINS
**
** Description:
**	This stored procedure's function is to do compatibility checks related
** to remote logins across the companions. The following checks are done to 
** determine the compatibility of the two servers:
**
**	a) The entries in the local sysremotelogins should match exactly with 
**	   that in remote server.  
**
** Parameters:
**		@rmt_suid	: suid id from remote server -- Input
**		@rmt_srvid	: remoteserver id from remote server -- Input
**		@rmt_name	: remoteusername from remote server -- Input
**		@attrib_id	: attribute id -- Input
**		@logrecord	: Should advisory be logged -- Input
**		@advisory	: Output advisory -- Output
**
** Error Messages:
**
** Returns:
**		0 on success, 1 on failure.
*/
create procedure sp_havalidatermtlogins
@rmt_suid int,				/* remote suid (sysremotelogins) */
@rmt_srvid smallint,			/* remoteserver id from remote server */
@rmt_name  varchar(30),			/* remoteusername from remote server */
@attrib_id int,				/* attribute id */
@logrecord  tinyint = 1,		/* Should advisory be logged? */
@advisory int = 0 output		/* Ouput advisory */
as
declare 
	@retstat   int,			/* return value of executing a SQL */
	@attrib_name varchar(80),	/* Attribute name */
	@comment varchar(255),		/* Comments */
	@suid  int,			/* suid in local server */
	@name  varchar(30),		/* remoteusername in local server */
	@rcharval  varchar(32),		/* remote char value */
	@attrib_type varchar(32)	/* Base type of the attribute */

/* Initialize the variables */
select 	@attrib_name = "Remote Logins",
	@retstat = 0, @suid = NULL

/* Attribute Id should 2100 */
if @attrib_id != 2100
begin
	print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
	return (1)
end

set nocount on
select @attrib_type = attrib_type from tempdb.dbo.ha_advisory_attrs where
				attrib_id = @attrib_id 

select @suid = suid from master.dbo.sysremotelogins where
	suid = @rmt_suid and remoteserverid = @rmt_srvid and
	remoteusername = @rmt_name

/* 
** If the (server, username) does not exists it is o.k, it will be sync'd up
** at configuration time.  If they exists, they better have the same suid.
*/
if (@suid is not NULL)
begin
	/* Mismatch with (server, username) */
	if (not exists (select 1 from master.dbo.sysremotelogins where 
		remoteserverid = @rmt_srvid and remoteusername = @rmt_name))
	begin
		select @advisory = 2
		select @attrib_name = "Remote Logins"
		select @comment = "Mismatch in Remote logins"
		select @rcharval = "srvid=" + convert(varchar(6), @rmt_srvid)
		exec @retstat = sp_ha_logadvisory_rec @attrib_name, 
				@attrib_type, @attrib_id, NULL, @rcharval, 0, 
				NULL, 0, @advisory, @comment 
		if @retstat != 0
			return (@retstat)
	end
end

return (0)

go

/*
** SP_HACMPCHECKLOGINS
**
** Description:
**	This stored procedure's function is to do compatibility checks related
** to logins across the companions. The following checks are done to determine
** the compatibility of the two servers:
**
**	a) All default logins (sa, probe, qcollector, qrepository, mon_user)
**	   must match exactly on the companion.  If there is any mismatch in
**	   the suid, no advisory will be logged, but appropriate changes will 
**	   have to be made in the secondary to sync up the name/number space of
**	   the default logins at configuration time.
**
**	b) If there are any non default logins on the secondary that conflict
**	   in name/suid with any entry in the primary, it will be signalled as
**	   a hard fault.
**
**	c) If there are any non default logins on the primary that are not
**	   in the secondary, it will be ignored unless the companion state
**	   is > 0 in which case it will be logged as a soft fault.
**
**	d) If there are any non default logins on the secondary that do not 
**	   exists in the primary and although its suid does not conflict with 
**	   any suid on the primary, it will be reported as a hard fault. 
**
**	e) If there are non default logins on the secondary that have exact 
**	   matches on the primary, it will be relaxed and NOT reported as a
**	   fault.
**
**	f) On the companion, any non default users in sysusers catalog is
**	   allowed as long as it is bound to the same suid and belongs to the
**	   same group as that of the primary.  If this check fails, it is a 
**	   serious error and will be reported as a hard fault.  We don't care
**	   about user databases.
**
**	g) On the companion, entries in sysremotelogins is allowed as long as
**	   the serverid, servername and suid match exactly as that on the 
**	   primary.  If this check fails, we report a hard fault.
**
** Parameters:
**		@servername	: Name of the Companion server -- Input
**		@skip_error	: Skip on encountering an error-- Input
**		@check_only	: Check only 		       -- Input
**		@attrib_id	: Attribute ID 		       -- Input
**		@option		: to indicate some context     -- Input 
** Design: 
**
** 	Attribute ID 2100 is for User Logins, 2200 for Remote Logins and
**		     2300 for Aliases
** 
** Error Messages:
**
** Returns:
**		0 on success, 1 on failure.
*/
create procedure sp_hacmpchecklogins
@servername varchar(30)  = null,	/* Name of the primary server */
@skip_error int,			/* Skip the check on error */
@check_only int,			/* Check only */	
@attrib_id  int,			/* attribute Id of interest */
@option	    int 			/* Additional option */
as
declare 
	@retstat   int,			/* return value of executing a SQL */
	@advisory int,			/* Advisory for the attribute */
	@attrib_name varchar(80),	/* Attribute name */
	@comment varchar(255),		/* Comments */
	@rmt_name  varchar(30),		/* login name in remote server */
	@rmt_ug_name  varchar(30),	/* user name in remote server */
	@gname  varchar(30),		/* group name in local server */
	@ug_name  varchar(30),		/* user name in local server */
	@default_ugname  tinyint,	/* Is the user/group default? */
	@rmt_gid  int,			/* gid in remote server */
	@rmt_srvid  smallint,		/* remotesrvid in remote server */
	@gid  int,			/* gid in local server */
	@uid  int,			/* uid in local server */
	@rmt_uid  int,			/* uid in remote server */
	@rmt_suid  int,			/* suid in remote server */
	@altsuid  int,			/* altsuid in local server */
	@name  varchar(30),		/* login name in local server */
	@rmt_gname  varchar(30),	/* login name in local server */
	@suid  int,			/* suid in local server */
	@srvid  smallint,		/* remoteserver id in local server */
	@lcharval  varchar(32),		/* local char value */
	@rcharval  varchar(32),		/* remote char value */
	@logrecord int,			/* to log or not */
	@attrib_type varchar(32)	/* Base type of the attribute */

/* 17260, "Can't run %1! from within a transaction." */
if @@trancount != 0
begin
	raiserror 17260, "sp_hacmpchecklogins"
	return (1)
end

dbcc istraceon(2227)
if @@error != -1
begin
	print "Proc name = '%1!'", "sp_hacmpchecklogins" 
	print "Servername Id = '%1!'", @@servername
	print "Attribute Id = '%1!'", @attrib_id
end

/* Attribute Id should not be a group */
if @attrib_id = 0 or @attrib_id < 1000
begin
	print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
	return (1)
end

/* Check for valid Base attribute Id */
if @attrib_id != 0
begin
	select @attrib_type = attrib_type from 
				tempdb.dbo.ha_advisory_attrs where
				attrib_id = @attrib_id 
	if (@attrib_type is NULL)
	begin
		print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
		return(1)
	end
end

/* Initialize the variables */
select 	@advisory = 0, 
	@retstat = 0, @logrecord = 1

select @attrib_name = "Non Default Logins"

/* Check if trace 2202 is on; or Check only is on, log the record. */	
dbcc istraceon(2202)
if @@error != -1 
begin
	select @logrecord = 1
end

set nocount on

/* cursor on the local syslogins catalog */
declare syslogins_curs cursor for select suid, name from master.dbo.syslogins
open syslogins_curs

/* cursor on the local sysalternates catalog */
declare sysalt_curs cursor for select suid, altsuid from 
	master.dbo.sysalternates
open sysalt_curs

/* cursor on local sysusers catalog */
declare sysusers_curs cursor for select suid, uid, gid, name 
	from master.dbo.sysusers
open sysusers_curs

/* cursor on remote sysusers catalog */
declare rmtsysusers_curs cursor for select suid, uid, gid, name 
	from master.dbo.rmt_ha_sysusers where uid != gid
open rmtsysusers_curs

/* cursor on local sysremotelogins catalog , exclude remote server */
declare rmtlogins_curs cursor for select remoteserverid, remoteusername 
	from master.dbo.sysremotelogins  where remoteserverid not in
	(select srvid from master.dbo.sysservers where srvname  = @servername)
  
open rmtlogins_curs

/* cursor on remote sysremotelogins catalog , exclude local server*/
declare rmt_rmtlogins_curs cursor for select suid, remoteserverid, 
	remoteusername from master.dbo.rmt_ha_sysremotelogins
	where remoteserverid not in (select srvid from 
	master.dbo.rmt_ha_sysservers where srvname = @@servername)
open rmt_rmtlogins_curs

/*cursor on remote syslogins catalog */
declare rmt_ha_syslogins_curs cursor for select suid, name
	from master.dbo.rmt_ha_syslogins
open rmt_ha_syslogins_curs
fetch rmt_ha_syslogins_curs into @rmt_suid, @rmt_name

/* Checking SYSLOGINS */

/* Iterate through each login entry from the remote server */
while (@@sqlstatus = 0)
begin
	/* some failure reading rmt_ha_syslogins */
	if @@error != 0 or @@transtate = 3
	begin
		select @retstat = 1
		goto login_cleanup
	end
	/* validate this login against the local server */
	exec @retstat = sp_havalidatelogin @rmt_suid, @rmt_name, 
			@attrib_id, @logrecord, @advisory output
	if (@retstat != 0)
		goto login_cleanup

	/* validate aliases for this login against the local server */
	exec @retstat = sp_havalidatealias @rmt_suid, @attrib_id, 
			@logrecord, @advisory output
	if (@retstat != 0)
		goto login_cleanup

	fetch rmt_ha_syslogins_curs into @rmt_suid, @rmt_name
end

/* error in fetch */
if @@sqlstatus = 1
begin
	select @retstat = 1
	goto login_cleanup
end

/* 
** If there are extra login entries on the local that are not in 
** the companion, it will be reported as a hard fault
*/
fetch syslogins_curs into @suid, @name

while (@@sqlstatus = 0)
begin
	/* 
	** A login entry in the local does not exist on the remote server 
	** ex: a login like qcollector may be in secondary but might not
	** have been added to primary.  This is considered a hard fault.
	*/
	if (not exists (select 1 from master.dbo.rmt_ha_syslogins where
				name = @name))
	begin
		select @comment = "Missing logins on remote server"
		select @advisory = 2
		exec @retstat = sp_ha_logadvisory_rec 
				@attrib_name, 
				@attrib_type, @attrib_id, NULL, 
				@name, 0, NULL, 0,  
				@advisory, @comment 
		if @retstat != 0
			goto login_cleanup	
	end
	fetch syslogins_curs into @suid, @name
end

/* error in fetch */
if @@sqlstatus = 1
begin
	select @retstat = 1
	goto login_cleanup
end

/* Checking SYSALTERNATES */

/* 
** If there are extra (suid, altsuid) entries on the local that are not in 
** the companion, it will be reported as a hard fault
*/
fetch sysalt_curs into @suid, @altsuid

while (@@sqlstatus = 0)
begin
	/* A (suid,altsuid) pair in the local does'nt exist on remote server */
	if (not exists (select 1 from master.dbo.rmt_ha_sysalternates where
				suid = @suid and altsuid = @altsuid))
	begin
		select @advisory = 2
		if (@logrecord = 1)
		begin
			select @attrib_name = "Aliases"
			select @comment = "Missing Alias on remote server"
			select @lcharval = "altsuid=" +  
					convert(varchar(11), @altsuid)
					
			exec @retstat = sp_ha_logadvisory_rec 
					@attrib_name, 
					@attrib_type, @attrib_id, NULL, 
					@lcharval, 0, NULL, 0,  
					@advisory, @comment 
			if @retstat != 0
				goto login_cleanup	
		end
	end
	fetch sysalt_curs into @suid, @altsuid
end

/* error in fetch */
if @@sqlstatus = 1
begin
	select @retstat = 1
	goto login_cleanup
end

/* Checking SYSUSERS */

/* 
** Any user or group or role that is present on the local server must be also
** present on the remote server.  As far users are concerned, they should be
** tied to the same login and the same group on both the servers.
*/
fetch sysusers_curs into @suid, @uid, @gid, @ug_name
while (@@sqlstatus = 0)
begin
	if (@ug_name in ("guest", "dbo", "probe", "qcollector", 
			"qrepository", "public") or
	   (@ug_name in (select name from master.dbo.syssrvroles
			 where srid < 32 and name like '%role')))
		select @default_ugname = 1
	else
		select @default_ugname = 0

	/* validate the entry if it is a group/role */
	if (@uid = @gid)
	begin
		/* If group does not exist on the remote, it is a hard fault */
		if (not exists (select 1 from master.dbo.rmt_ha_sysusers
				where name = @ug_name))
		begin
			select @advisory = 2
			select @attrib_name = "Users/Groups"
			select @comment = "Missing Group"
			exec @retstat = sp_ha_logadvisory_rec 
					@attrib_name, 
					@attrib_type, @attrib_id, NULL, 
					@ug_name, 0, NULL, 0,  
					@advisory, @comment 
			if @retstat != 0
				goto login_cleanup	
		end
	end
	else	/* It is a user */
	begin
		select @gname = NULL
		select @rmt_ug_name = NULL

		/* get the group name to which this user belongs */
		select @gname = name from master.dbo.sysusers 
			where gid = @gid and uid = gid

		/* get the corresponding row from remote sysusers */
		select @rmt_ug_name = name, @rmt_uid = uid, @rmt_gid  = gid 
			from master.dbo.rmt_ha_sysusers where 
			suid = @suid and name = @ug_name

		/* Mismatch in (suid, name) pair */
		if (@rmt_ug_name is NULL) 
		begin
			if (@default_ugname = 0)
			begin
				select @advisory = 2
				select @attrib_name = "Users/Groups"
				select @comment = "Mismatch in users "
				exec @retstat = sp_ha_logadvisory_rec 
					@attrib_name, @attrib_type, @attrib_id,
					NULL, @ug_name, 0, NULL, 0,  
					@advisory, @comment 
				if @retstat != 0
					goto login_cleanup	
			end
		end
		else  /* user name, suid pair matches correctly */
		begin
			/* get the group name for this user in remote server */
			select @rmt_gname = name from 
				master.dbo.rmt_ha_sysusers 
				where gid = @rmt_gid and uid = gid
			/*
			** The user names matched but they do not belong to
			** the same group which is a hard fault.
			*/
			if (@rmt_gname != @gname)
			begin
				select @advisory = 2
				select @attrib_name = "Users/Groups"
				select @comment = "(user,group) mismatch"
				select @lcharval = "(" + 
					convert(varchar(11),@uid) + "," + 
					convert(varchar(11), @gid) + ")"
				select @rcharval = "(" + 
					convert(varchar(11),@rmt_uid) + "," + 
					convert(varchar(11), @rmt_gid) + ")"
				exec @retstat = sp_ha_logadvisory_rec 
					@attrib_name, @attrib_type, @attrib_id,
					NULL, @lcharval, 0, @rcharval, 0,  
					@advisory, @comment 
				if @retstat != 0
					goto login_cleanup	
			end
		end
	end

	fetch sysusers_curs into @suid, @uid, @gid, @ug_name
end
/* error in fetch */
if @@sqlstatus = 1
begin
	select @retstat = 1
	goto login_cleanup
end

/*
** If a user in the remote server does not exist in the local server but there
** is an entry in the local server with the same uid as that of the remote
** server, it is reported as a hard fault.  We don't care about groups b'cos
** they will get synchronized anyway.
*/
fetch rmtsysusers_curs into @rmt_suid, @rmt_uid, @rmt_gid, @rmt_ug_name
while (@@sqlstatus = 0)
begin
	if (@ug_name in ("guest", "dbo", "probe", "qcollector", 
			"qrepository", "public") or
	   (@ug_name in (select name from master.dbo.syssrvroles
			 where srid < 32 and name like '%role')))
		select @default_ugname = 1
	else
		select @default_ugname = 0

	/* user in the remote server exists in the local */ 
	if (exists (select 1 from master.dbo.sysusers where 
		name = @rmt_ug_name and uid != gid))
	begin
		select @rmt_gname = NULL
		select @ug_name = NULL
		select @gname = NULL

		/* get the group name which this user belongs from remote */
		select @rmt_gname = name from master.dbo.rmt_ha_sysusers 
			where gid = @rmt_gid and uid = gid

		/* get the corresponding row from local sysusers */
		select @ug_name = name, @uid = uid, @gid = gid from 
			master.dbo.sysusers where 
			suid = @rmt_suid and name = @rmt_ug_name

		/* Mismatch in (suid, name) pair */
		if (@ug_name is NULL) 
		begin
			/* default users will get synchronized later on */
			if (@default_ugname = 0)
			begin
				select @advisory = 2
				select @attrib_name = "Users/Groups"
				select @comment = "Mismatch in users "
				exec @retstat = sp_ha_logadvisory_rec 
					@attrib_name, @attrib_type, @attrib_id,
					NULL, NULL, 0, @rmt_ug_name, 0,  
					@advisory, @comment 
				if @retstat != 0
					goto login_cleanup	
			end
		end
		else  /* user name, suid pair matches correctly */
		begin
			/* get the group name for this user in local server */
			select @gname = name from 
				master.dbo.sysusers 
				where gid = @gid and uid = gid
			/*
			** The user names matched but they do not belong to
			** the same group which is a hard fault.
			*/
			if (@rmt_gname != @gname)
			begin
				select @advisory = 2
				select @attrib_name = "Users/Groups"
				select @comment = "(user,group) mismatch"
				select @lcharval = "(" + 
					convert(varchar(11),@uid) + "," + 
					convert(varchar(11), @gid) + ")"
				select @rcharval = "(" + 
					convert(varchar(11),@rmt_uid) + "," + 
					convert(varchar(11), @rmt_gid) + ")"
				exec @retstat = sp_ha_logadvisory_rec 
					@attrib_name, @attrib_type, @attrib_id,
					NULL, @lcharval, 0, @rcharval, 0,  
					@advisory, @comment 
				if @retstat != 0
					goto login_cleanup	
			end
		end
	end
		
	fetch rmtsysusers_curs into @rmt_suid, @rmt_uid, @rmt_gid, @rmt_ug_name
end
/* error in fetch */
if @@sqlstatus = 1
begin
	select @retstat = 1
	goto login_cleanup
end

/* Checking SYSREMOTELOGINS */

fetch rmt_rmtlogins_curs into @rmt_suid, @rmt_srvid, @rmt_name
while (@@sqlstatus = 0)
begin
	exec @retstat = sp_havalidatermtlogins @rmt_suid, @rmt_srvid,
			@rmt_name, @attrib_id, @logrecord, @advisory output
	if @retstat != 0
		goto login_cleanup

	fetch rmt_rmtlogins_curs into @rmt_suid, @rmt_srvid, 
		@rmt_name
end
/* error in fetch */
if @@sqlstatus = 1
begin
	select @retstat = 1
	goto login_cleanup
end

/* 
** There should be no extra entries on the local sysremote logins 
** in single server mode 
*/
fetch rmtlogins_curs into @srvid, @name
while (@@sqlstatus = 0)
begin
	if (not exists (select 1 from master.dbo.rmt_ha_sysremotelogins 
			where remoteserverid = @srvid and 
			remoteusername = @name))
	begin
		if (@@cmpstate = 0)
		begin
			select @advisory = 2
			select @attrib_name = "Remote Logins"
			select @comment = 
				"Remote logins exists on local"
			select @lcharval = "srvid=" + 
				convert(varchar(6), @srvid)
			exec @retstat = sp_ha_logadvisory_rec 
					@attrib_name, 
					@attrib_type, @attrib_id, NULL, 
					@lcharval, 0, NULL, 0,  
					@advisory, @comment 
			if @retstat != 0
				goto login_cleanup
		end
	end
	fetch rmtlogins_curs into @srvid, @name
end
/* error in fetch */
if @@sqlstatus = 1
begin
	select @retstat = 1
	goto login_cleanup
end
			
login_cleanup:
	close rmt_ha_syslogins_curs
	deallocate cursor rmt_ha_syslogins_curs
	close syslogins_curs
	deallocate cursor syslogins_curs
	close sysalt_curs
	deallocate cursor sysalt_curs
	close rmt_rmtlogins_curs
	deallocate cursor rmt_rmtlogins_curs
	close rmtlogins_curs
	deallocate cursor rmtlogins_curs
	close sysusers_curs
	deallocate cursor sysusers_curs
	close rmtsysusers_curs
	deallocate cursor rmtsysusers_curs

/* Check only or the computed advisory is zero, just return */
if @check_only = 1 or @advisory = 0
	return (@retstat)

/* If skip on error, simply return 0 else return 1 */ 
if @skip_error = 1
	return (0)
else
	return (1)

go



/*
** SP_HACMPCHECKROLES
**
** Description:
**	This stored procedure's function is to do compatibility checks related
** to user defined roles across the companions. The following checks are done 
** to determine the compatibility of the two servers:
**
**	a) Any user roles present on the local server should exactly match the 
**	   entries in the remote syssrvroles catalog.
**
** Parameters:
**		@servername	: Name of the Companion server -- Input
**		@skip_error	: Skip on encountering an error-- Input
**		@check_only	: Check only 		       -- Input
**		@attrib_id	: Attribute ID 		       -- Input
**		@option		: to indicate some context     -- Input 
** Design: 
**
** 	Attribute ID 2200 is for Roles 
** 
** Error Messages:
**
** Returns:
**		0 on success, 1 on failure.
*/
create procedure sp_hacmpcheckroles
@servername varchar(30)  = null,	/* Name of the primary server */
@skip_error int,			/* Skip the check on error */
@check_only int,			/* Check only */	
@attrib_id  int,			/* attribute Id of interest */
@option	    int 			/* Additional option */
as
declare 
	@retstat   int,			/* return value of executing a SQL */
	@advisory int,			/* Advisory for the attribute */
	@attrib_name varchar(80),	/* Attribute name */
	@comment varchar(255),		/* Comments */
	@srid  int,			/* srid in local server */
	@suid  int,			/* suid in local server */
	@rmt_srid  int,			/* srid in remote server */
	@rmt_suid  int,			/* suid in remote server */
	@rolename  varchar(30),		/* role name in local server */
	@rmt_rolename  varchar(30),	/* role name in remote server */
	@rmt_login  varchar(30),	/* login name in remote server */
	@lcharval  varchar(32),		/* local char value */
	@rcharval  varchar(32),		/* remote char value */
	@logrecord int,			/* to log or not */
	@is_sysrole tinyint,		/* Is this a system role? */
	@default_login tinyint,		/* Is this a default login? */
	@attrib_type varchar(32)	/* Base type of the attribute */

/* 17260, "Can't run %1! from within a transaction." */
if @@trancount != 0
begin
	raiserror 17260, "sp_hacmpcheckroles"
	return (1)
end

dbcc istraceon(2227)
if @@error != -1
begin
	print "Proc name = '%1!'", "sp_hacmpcheckroles" 
	print "Servername Id = '%1!'", @@servername
	print "Attribute Id = '%1!'", @attrib_id
end

/* Attribute Id should not be a group */
if @attrib_id = 0 or @attrib_id < 1000
begin
	print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
	return (1)
end

/* Check for valid Base attribute Id */
if @attrib_id != 0
begin
	select @attrib_type = attrib_type from 
				tempdb.dbo.ha_advisory_attrs where
				attrib_id = @attrib_id 
	if (@attrib_type is NULL)
	begin
		print "Internal Error: Attribute Id '%1!' not found", @attrib_id
		return(1)
	end
end

/* Initialize the variables */
select 	@advisory = 0, 
	@retstat = 0, @logrecord = 1

select @attrib_name = "User Defined Roles"

/* Check if trace 2202 is on; or Check only is on, log the record. */	
dbcc istraceon(2202)
if @@error != -1 
begin
	select @logrecord = 1
end

set nocount on

/* cursor on local syssrvroles catalog */
declare syssrvroles_curs cursor for select srid, name
	from master.dbo.syssrvroles where srid > 31 order by srid
open syssrvroles_curs

/* cursor on remote syssrvroles catalog */
declare rmtsyssrvroles_curs cursor for select srid, name
	from master.dbo.rmt_ha_syssrvroles where srid > 31 order by srid
open rmtsyssrvroles_curs

/* cursor on local sysloginroles catalog */
declare sysloginroles_curs cursor for select suid, srid 
	from master.dbo.sysloginroles
open sysloginroles_curs

/* cursor on remote sysloginroles catalog */
declare rmtsysloginroles_curs cursor for select suid, srid 
	from master.dbo.rmt_ha_sysloginroles
open rmtsysloginroles_curs

/* Checking SYSSRVROLES */

/* 
** All system roles should have fixed srid and so we check only for user 
** defined roles.  The syssrvroles entries should match exactly between the
** local and remote servers.  This is also true with the sysroles catalog.
*/
fetch syssrvroles_curs into @srid, @rolename
while (@@sqlstatus = 0)
begin

	select @rmt_srid = NULL
	select @rmt_rolename = NULL

	/* get the corresponding entry from remote syssrvroles */
	select @rmt_srid = srid, @rmt_rolename  = name from 
		master.dbo.rmt_ha_syssrvroles where 
		srid = @srid and name = @rolename 

	/* no matching row exists on remote server */
	if (@rmt_rolename is NULL) 
	begin
		select @advisory = 2
		select @comment = "Mismatch in roles on remote server"
		exec @retstat = sp_ha_logadvisory_rec @attrib_name, 
				@attrib_type, @attrib_id, NULL, @rolename, 0, 
				NULL, 0,  @advisory, @comment 
		if @retstat != 0
			goto role_cleanup	
	end

	fetch syssrvroles_curs into @srid, @rolename
end
/* error in fetch */
if @@sqlstatus = 1
begin
	select @retstat = 1
	goto role_cleanup
end

/*
** If a role in the remote does not exist in the local, but its role id is
** not used, it is o.k.  It will get sync'd up at configuration time.  Other
** cases where there is a mismatch is a hard fault.
*/
fetch rmtsyssrvroles_curs into @rmt_srid, @rmt_rolename
while (@@sqlstatus = 0)
begin

	select @srid = NULL
	select @rolename = NULL

	/* get the corresponding entry from local syssrvroles */
	select @srid = srid, @rolename = name from master.dbo.syssrvroles 
		where name = @rmt_rolename 

	/* no matching row exists on local server */
	if (@rolename is NULL) 
	begin
		/* role id is occupied by a different role */
		if (exists (select 1 from master.dbo.syssrvroles where
			srid = @rmt_srid))
		begin
			select @advisory = 2
			select @comment = "Mismatch in roles on local server"
			exec @retstat = sp_ha_logadvisory_rec @attrib_name, 
					@attrib_type, @attrib_id, NULL, NULL, 
					@rmt_srid, @rmt_rolename, 0,  @advisory, 
					@comment 
			if @retstat != 0
				goto role_cleanup	
		end
	end
	else	/* role exists on local server */
	begin
		/* role id is different than on the remote server */
		if (@srid != @rmt_srid)
		begin
			select @advisory = 2
			select @comment = "Mismatch in roles on local server"
			exec @retstat = sp_ha_logadvisory_rec @attrib_name, 
					@attrib_type, @attrib_id, NULL, 
					NULL, @srid, NULL, @rmt_srid,  
					@advisory, @comment 
			if @retstat != 0
				goto role_cleanup	
		end
	end
		
	fetch syssrvroles_curs into @srid, @rolename
end
/* error in fetch */
if @@sqlstatus = 1
begin
	select @retstat = 1
	goto role_cleanup
end

/* Checking sysloginroles */

/* 
** For all logins, the (suid, srid) pairs in the local and remote sysloginroles
** catalog should match.  This ensures that the roles granted to these logins 
** are identical.  If a role is not granted to a login in the local server, it 
** will be sync'd up at configuration time. So, we flag it as a soft fault.
*/ 
fetch rmtsysloginroles_curs into @rmt_suid, @rmt_srid
while (@@sqlstatus = 0)
begin
	select @rmt_login = NULL

	select @rmt_login = name from master.dbo.rmt_ha_syslogins where 
		suid = @rmt_suid

	if (not exists (select 1 from master.dbo.sysloginroles where 
			suid = @rmt_suid and srid = @rmt_srid))
	begin
		/* No matching sysloginroles row on the local server */
		select @advisory = 1
		select @comment = "Role not granted to login"
		select @rcharval = "(" + convert(varchar(11), @rmt_suid) + "," +
				convert(varchar(6), @rmt_srid) + ")"
		exec @retstat = sp_ha_logadvisory_rec 
				@attrib_name, @attrib_type, @attrib_id, NULL, 
				NULL, 0, @rcharval, 0,  @advisory, @comment 
		if @retstat != 0
			goto role_cleanup	
	end
	fetch rmtsysloginroles_curs into @rmt_suid, @rmt_srid
end

/* error in fetch */
if @@sqlstatus = 1
begin
	select @retstat = 1
	goto role_cleanup
end

/*
** If any roles have been granted to some login in the local that has not been 
** done in the remote, it is hard fault 
*/
fetch sysloginroles_curs into @suid, @srid
while (@@sqlstatus = 0)
begin
	if (not exists (select 1 from master.dbo.rmt_ha_sysloginroles where 
			suid = @suid and srid = @srid))
	begin
		/* No matching sysloginroles row on the remote server */
		select @advisory = 2
		select @comment = "Missing/Mismatch in sysloginroles"
		select @lcharval = "(" + convert(varchar(11), @suid) + "," +
				convert(varchar(6), @srid) + ")"
		exec @retstat = sp_ha_logadvisory_rec @attrib_name, 
				@attrib_type, @attrib_id, NULL, @lcharval, 0, 
				NULL, 0, @advisory, @comment 
		if @retstat != 0
			goto role_cleanup	
	end
	fetch sysloginroles_curs into @suid, @srid
end

/* error in fetch */
if @@sqlstatus = 1
begin
	select @retstat = 1
	goto role_cleanup
end
	
role_cleanup:
	close syssrvroles_curs
	deallocate cursor syssrvroles_curs
	close sysloginroles_curs
	deallocate cursor sysloginroles_curs
	close rmtsysloginroles_curs
	deallocate cursor rmtsysloginroles_curs

return (@retstat)

go


/*
** SP_HACMPCHECKAPPRES
**
** Description:
**	This stored procedure does the compatibility checks related to
** successsful execution of primary application in secondary after the
** failover. There are many application related configurations in a 
** server, like remote servers that application uses, languages, charsets
** and sortorders configured etc.
**
** Parameters:
**		@servername	: Name of the Companion server -- Input
**		@skip_error	: Skip on encountering an error-- Input
**		@check_only	: Check only 		       -- Input
**		@attrib_id	: Attribute ID 		       -- Input
**		@option		: to indicate some context     -- Input 
** Design: 
**
**	Attrib ID : 1700 Remote Servers 
**
**	Verifies that all the remote servers in the primary ( remote server)
** are compatible with the secondary (local) server. Server names are unique
** they should have the same server id, network name ( as seen in the
** interfaces file and same class. Any incompatibility will be triggered
** as an error.
**
** 	Attrib ID : 1710, 1720, 1730 Languages, charsets and sortorder
**
** Applications on the companion nodes will be able run seemlessly, if the
** default charset, sort-order and languages are all the same. Changes to
** any one of them usually involves recompilation, rebuilding of indexes
** and procedures. So for 12.0 we will enforce that the current defaults
** should be same.
**
** Default languages, charsets and sortorders are all DYNAMIC values.
** Meaning, if we check the config values in sysconfigures, instead
** of syscurconfigs, we are fine.
**
** We will use the config number for scans instead of a string. We do
** not know at this time the companion's languages, charsets and sort
** order. It is safer to scan using config number. Generally, we do
** not move around the config numbers across the releases.

** Error Messages:
**
** Returns:
**		0 on success, 1 on failure.
*/
create procedure sp_hacmpcheckappres
@servername varchar(30)  = null,	/* Name of the primary server */
@skip_error int,			/* Skip the check on error */
@check_only int,			/* Check only */	
@attrib_id  int,			/* attribute Id of interest */
@option	    int 			/* Additional option */
as
declare 
	@retstat   int,			/* return value of executing a SQL */
	@attrib_name varchar(80),	/* Attribute name */
	@attrib_type varchar(32),	/* Base type of the attribute */
	@comment     varchar(255),	/* Comments */
	@srvname     varchar(32),	/* name of the database */
	@rmtsrvid   int,		/* Remote servers ID */
	@rmtsrvname  varchar(30),	/* name of the remoteserver */
	@localsrvrname  varchar(30),	/* name of the localserver */
	@rmtsrvnetname varchar(32),	/* Network name of remote server */
	@rmtsrvclass   int,		/* Remote servers class */
	@lcharval    varchar(32),	/* Local character value */
	@rintval	int,		/* Remote Integer value */
	@alias	     varchar(30),	/* Alias for the language */
	@langid	   int,			/* Language Id */
	@id 	   int,			/* id of languages, charset/sortorder */
	@csid 	   int,			/* id of languages, charset/sortorder */
	@type 	   int,			/* id of languages, charset/sortorder */
	@name	   varchar(30),		/* Generic name */
	@logrecord int,			/* to log or not */
	@advisory  int			/* Advisory */
	
/* 17260, "Can't run %1! from within a transaction." */
if @@trancount != 0
begin
	raiserror 17260, "sp_hacmpcheckappres"
	return (1)
end

dbcc istraceon(2227)
if @@error != -1
begin
	print "Proc name = '%1!'", "sp_hacmpcheckappres" 
	print "Servername Id = '%1!'", @@servername
	print "Attribute Id = '%1!'", @attrib_id
end

/* Validate Attribute Id */
if @attrib_id = 0 or @attrib_id < 1000
begin
	print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
	return (1)
end

/* Check for valid Base attribute Id */
if @attrib_id != 0
begin
	if not exists (select 1 from tempdb.dbo.ha_advisory_attrs where
				attrib_id = @attrib_id)
	begin
		print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
		return(1)
	end
end

/* Get the attribute type based on the attribure id */
select @attrib_type = attrib_type from tempdb.dbo.ha_advisory_attrs 
			 where attrib_id = @attrib_id

/* Initialize the variables */
select 	@comment = " ", @retstat = 0, @logrecord = 0, @advisory = 0

dbcc istraceon(2202)
if @@error != -1
begin 
	select @logrecord = 1
end

set nocount on

select @localsrvrname = @@servername

/* Cursor on the remote sysservers */
declare  rmt_hasysservers_curs cursor for select srvid, srvname, 
	srvnetname, srvclass  from master.dbo.rmt_ha_sysservers 
	where srvid > 0 and
	srvname not in ('SYB_HACMP', 'SYB_BACKUP', 'local', @localsrvrname) 

/* Cursor on the local sysservers */
declare  local_hasysservers_curs cursor for select srvname from 
	master.dbo.sysservers where srvid > 0 

/* Cursor for language related checks */
declare syslanguages_curs cursor for select name, langid, alias from
	master.dbo.rmt_ha_syslanguages 

/* Cursor for Charset and Sortorder related checks */
declare syscharsets_curs cursor for select type, id, csid, name from 
	master.dbo.rmt_ha_syscharsets where type between 1000 and 2999

open rmt_hasysservers_curs
open local_hasysservers_curs
open syslanguages_curs
open syscharsets_curs

/* (unique) Remote Server entries */
if (@attrib_id = 1700)
begin
	fetch rmt_hasysservers_curs into @rmtsrvid, @rmtsrvname,
					@rmtsrvnetname, @rmtsrvclass
	while (@@sqlstatus = 0)
	begin
		/* Initialize advisory at every iteration */
		select @advisory = 0, @lcharval = NULL

		/* If the remote servername or server Id exists locally */
		select @lcharval = srvname from master.dbo.sysservers where
					srvname = @rmtsrvname or 
					srvid = @rmtsrvid
		if @lcharval is not NULL
		begin
			/* 
			** Servername and server ID should match. At this
			** time the local server entries default should
			** have been arranged to not to conflict
			*/
			if not exists (select 1 from master.dbo.sysservers 
						where srvid = @rmtsrvid and  
						srvname = @rmtsrvname)
			begin
				select  @advisory = 2,
					@attrib_name = "Srvid-Name match",
					@comment = "Srvid, Srvname Mismatch"
				exec @retstat = sp_ha_logadvisory_rec
						@attrib_name, @attrib_type,
						@attrib_id, NULL, @lcharval,
						0, @rmtsrvname, 0,
						@advisory, @comment	
				if @retstat != 0
					goto app_cleanup	
			end
			else  /* Id matches, so check next for netname */
			begin
				if not exists (select 1 from 
						master.dbo.sysservers where 
						srvid = @rmtsrvid and  
						srvname = @rmtsrvname and
						srvnetname = @rmtsrvnetname)
				begin
					select  @advisory = 2,
						@attrib_name = 
							"Interfaces entry",
						@comment =
							"Network name mismatch"
					exec @retstat = sp_ha_logadvisory_rec
						@attrib_name, @attrib_type,
						@attrib_id, NULL, @lcharval,
						0, @rmtsrvname, 0,
						@advisory, @comment	
					if @retstat != 0
						goto app_cleanup	
				end
				else
				begin	
					if not exists (select 1 from 
						master.dbo.sysservers where 
						srvid = @rmtsrvid and  
						srvname = @rmtsrvname and
						srvclass = @rmtsrvclass and 
						srvnetname = @rmtsrvnetname )
					begin
						select  @advisory = 2, 
							@attrib_name = 
							     "Network Class",
							@comment =
							"Network class mismatch"
						exec @retstat = 
							sp_ha_logadvisory_rec
							@attrib_name, 
							@attrib_type, 
							@attrib_id, NULL, 
							@lcharval, 0, 
							@rmtsrvname, 0,
							@advisory, @comment	
						if @retstat != 0
							goto app_cleanup	
					end
				end
			end
		end
		else
		begin
			/* This is a remote entry not synchronized yet */

			select  @attrib_name = "Missing rmtsrvr ",
				@advisory = 1
			exec @retstat = sp_ha_logadvisory_rec
					@attrib_name, @attrib_type,
					@attrib_id, NULL, NULL,
					0, @rmtsrvname, 0,
					@advisory, @comment	
			if @retstat != 0
				goto app_cleanup	
		end

		/* Everything is Ok but logrecord is set (2202) */
		if @advisory = 0 and @logrecord = 1
		begin
			select @attrib_name = "Srvid-Srvname"
			exec @retstat = sp_ha_logadvisory_rec
					@attrib_name, @attrib_type,
					@attrib_id, NULL, @rmtsrvname,
					0, @rmtsrvname, 0,
					@advisory, @comment	
			if @retstat != 0
				goto app_cleanup	
		end

		fetch rmt_hasysservers_curs into @rmtsrvid, @rmtsrvname,
						@rmtsrvnetname, @rmtsrvclass
	end

	if  @@sqlstatus = 1
	begin
		select @retstat = 1
		goto app_cleanup
	end

	/* 
	** Now check the local sysservers, entries. Any non-default entries
	** should be present in the remote server, else it is a hard error 
	*/
	fetch local_hasysservers_curs into @srvname

	while (@@sqlstatus = 0)
	begin
		/* Initialize the advisory */
		select @advisory = 0

		if not exists (select 1 from master.dbo.rmt_ha_sysservers
					where srvname = @srvname)
		begin
			select  @advisory = 2,
				@attrib_name = "Orphan Server entry",
				@comment =  "Missing server entry in remote"
			exec @retstat = sp_ha_logadvisory_rec
					@attrib_name, @attrib_type,
					@attrib_id, NULL, @srvname,
					0, NULL, 0, @advisory, @comment	
			if @retstat != 0
				goto app_cleanup
		end

		fetch local_hasysservers_curs into @srvname
	end

	if  @@sqlstatus = 1
	begin
		select @retstat = 1
		goto app_cleanup
	end
end

/* Check for Languages related configuration */
if (@attrib_id = 1710)
begin
	/* Check for current default Language.  */
	select @id = NULL, @advisory = 0, @rintval = NULL
	select @rintval	= value from master.dbo.rmt_ha_sysconfigures 
				where config = 124
	select @id = value from master.dbo.sysconfigures where config = 124

	if @id != @rintval
	begin
		select @advisory = 2
	end
	
	if @advisory != 0 or @logrecord = 1
	begin
		select @attrib_name = "Default Language"
		select @comment =  "Incompatible default language"
		exec @retstat = sp_ha_logadvisory_rec
				@attrib_name, @attrib_type,
				@attrib_id, NULL, NULL, @id, 
				NULL, @rintval, @advisory, @comment	
		if @retstat != 0
			goto app_cleanup
	end

	/*
	** Check for the language sets that are defined in the current server 
	** against the companion server. All language should be available.
	*/
	fetch syslanguages_curs into @name, @langid, @alias

	while (@@sqlstatus = 0)
	begin
		select @advisory = 0

		/*
		** Because the secondary is a fresh server, we are expecting
		** that it has smaller language set than the primary.
		** Languages have unique name. The langid and the alias to
		** that language should always be same across the companions
		**
		** It is expected that these language modules be installed
		** prior to configuration.
		*/
		if exists (select 1 from master.dbo.syslanguages 
				where name = @name or 
				langid = @langid or
				alias = @alias)
		begin
			/* 
			** The langid, language and alias  are all unique
			** they should represent the same row, else error
			*/ 
			if not exists (select 1 from master.dbo.syslanguages
					where name = @name and
					langid = @langid and
					alias = @alias)
			begin
				select @advisory = 2
			end
		
			if @advisory != 0 or @logrecord = 1
			begin
				select @attrib_name = "Language id/alias"
				select @comment =
					"Conflicting langid, name, alias"
				exec @retstat = sp_ha_logadvisory_rec
					@attrib_name, @attrib_type,
					@attrib_id, NULL, NULL, 0,
					@name, 0, @advisory, @comment	
				if @retstat != 0
					goto app_cleanup
			end	
		end
		else
		begin
			select @attrib_name = "Missing Language"
			select @comment =  "Language module not installed"
			exec @retstat = sp_ha_logadvisory_rec
					@attrib_name, @attrib_type,
					@attrib_id, NULL, NULL, 0,
					@name, 0, @advisory, @comment	
			if @retstat != 0
				goto app_cleanup
		end

		/* Get the next syslanguages row */
		fetch syslanguages_curs into @name, @langid, @alias
	end
	
	/*
	** fetch would return 1, if any error  occured. 0 for success
	** and 2 for issuing fetch again on the last row
	*/
	if (@@sqlstatus = 1)
	begin
		select @retstat = 1
		goto app_cleanup
	end
end

/* Do Charset related checks */
if (@attrib_id = 1720 or @attrib_id = 1730)
begin
	if @attrib_id = 1730
	begin
		select @id = NULL, @advisory = 0, @rintval = NULL

		/* Check for current default sortorder.  */
		select @id = value from master.dbo.sysconfigures 
					where config = 123
		select @rintval = value from master.dbo.rmt_ha_sysconfigures 
					where config = 123
		
		if @id != @rintval
		begin
			select @advisory = 2
		end	
		
		if @advisory != 0 or @logrecord = 1
		begin
			select @attrib_name = "Default sortorder"
			select @comment =  "Incompatible default sortorder"
			exec @retstat = sp_ha_logadvisory_rec
					@attrib_name, @attrib_type,
					@attrib_id, NULL, NULL, @id, 
					NULL, @rintval, @advisory, @comment	
			if @retstat != 0
				goto app_cleanup
		end
	end

	if @attrib_id = 1720
	begin
		select @id = NULL, @advisory = 0, @rintval = NULL

		/* Check for default Character set */
		select @id = value from master.dbo.sysconfigures 
					where config = 131
		select @rintval = value from master.dbo.rmt_ha_sysconfigures 
					where config = 131
		if @id != @rintval
		begin
			select @advisory = 2
		end	

		if @advisory != 0 or @logrecord = 1
		begin
			select @attrib_name = "Default Charset"
			select @comment =  "Incompatible default charset"
			exec @retstat = sp_ha_logadvisory_rec
					@attrib_name, @attrib_type,
					@attrib_id, NULL, NULL, @id,
					NULL, @rintval, @advisory, @comment	
			if @retstat != 0
				goto app_cleanup
		end
	end

	/*
	** Check for the charcter sets that are defined in the current server 
	** against the companion server. All charactersets should be available.
	** Charsets are between type 1000 and 1999. All Sortorder are between
	** 2000 and 2999.
	**
	** The name ( charactser set or sortorder ) is unique. Along with that
	** the composite ( ID, type, csid ) is also unique. All we need to
	** ensure that csid and id are same across the companions.
	*/
	fetch syscharsets_curs into @type, @id, @csid, @name

	while (@@sqlstatus = 0)
	begin
		select @advisory = 0

		/*
		** Type 1000 to 1999 is charsets ids. Make sure that
		** the ID exists in the local server.
		*/
		if not exists(select 1 from master.dbo.syscharsets where 
						name = @name )
		begin			
			if (@type between 1000 and 1999 and @attrib_id = 1720)
			begin
				/* The Local server does not have charset */
				select  @attrib_name = "Missing Charset",
					@comment= 
					"Charset module not installed",
					@advisory = 2
			end

			if (@type between 2000 and 2999 and @attrib_id = 1730)
			begin
				/* The Local server does not have sortorder */
				select  @attrib_name = "Missing sort order",
					@comment =
					"Sort order module not installed",
					@advisory = 2
			end	
		end
		else
		begin
			/* 
			** Got to make sure that the (id, csid) combination
			** is same across the companions for the given charset
			*/
			if not exists ( select 1 from master.dbo.syscharsets
					where name = @name and csid = @csid
					and id = @id )
			begin
				select  @attrib_name = "Mismatched csid/id",
					@comment =
					  "csid and soid are not matching",
					@advisory = 2
			end
		end

		if @advisory != 0 or @logrecord = 1
		begin
			exec @retstat = sp_ha_logadvisory_rec
					@attrib_name, @attrib_type,
					@attrib_id, NULL, NULL, 
					0, @name, 0, @advisory, 
					@comment	
			if @retstat != 0
				goto app_cleanup

		end

		/* Get the next syscharsets row */
		fetch syscharsets_curs into @type, @id, @csid, @name
	end
	
	/*
	** fetch would return 1, if any error  occured. 0 for success
	** and 2 for issuing fetch again on the last row
	*/
	if (@@sqlstatus = 1)
	begin
		select @retstat = 1
		goto app_cleanup
	end
end
	
app_cleanup:

	close rmt_hasysservers_curs
	deallocate cursor rmt_hasysservers_curs
	close local_hasysservers_curs
	deallocate cursor local_hasysservers_curs
	close syslanguages_curs
	deallocate cursor syslanguages_curs
	close syscharsets_curs
	deallocate cursor syscharsets_curs

	return(@retstat)
go

/*
** SP_HACMPCHECKAPPS
**
** Description:
**      This stored procedure's function is to do compatibility checks related
** to java archives (in sysjars), user defined types (in systypes), 
** timeranges (in systimeranges).  Note that sysresourcelimits will not be
** checked for advisory b'cos it is very hard to reconcile this catalog on the
** two servers for the lack of uniquness in the rows of the table.
**
** Parameters:
**              @servername     : Name of the Companion server -- Input
**              @skip_error     : Skip on encountering an error-- Input
**              @check_only     : Check only                   -- Input
**              @attrib_id      : Attribute ID                 -- Input
**              @option         : to indicate some context     -- Input
** Design:
**
**      Attribute ID 1740 for User Types
**		     1750 for Time Ranges
**		     1760 for Java Archives
**
** Error Messages:
**
** Returns:
**              0 on success, 1 on failure.
*/
create procedure sp_hacmpcheckapps
@servername varchar(30)  = null,        /* Name of the primary server */
@skip_error int,                        /* Skip the check on error */
@check_only int,                        /* Check only */
@attrib_id  int,                        /* attribute Id of interest */
@option     int                         /* Additional option */
as
declare
        @retstat   int,                 /* return value of executing a SQL */
        @advisory int,                  /* Advisory for the attribute */
        @attrib_name varchar(80),       /* Attribute name */
        @comment varchar(255),          /* Comments */
        @logrecord int,                 /* to log or not */
	@rmt_usertype smallint,
	@rmt_var bit,
	@rmt_null bit,
	@rmt_type tinyint,
	@rmt_len int,
	@rmt_name varchar(30),
	@rmt_prec tinyint,
	@rmt_scale tinyint,
	@rmt_ident tinyint,
	@rmt_hierarchy tinyint,
	@rmt_jname varchar(30),
	@jname varchar(30),
	@rmt_id smallint,
	@rmt_startday tinyint,
        @rmt_endday tinyint,
        @rmt_starttime varchar(10),
        @rmt_endtime varchar(10),
	@xtutid smallint,
	@xtid int,
	@xtmetatype int,
	@xtstatus int,
	@xtcontainer int,
	@xtname varchar(255),
        @attrib_type varchar(32)        /* Base type of the attribute */

/* 17260, "Can't run %1! from within a transaction." */
if @@trancount != 0
begin
        raiserror 17260, "sp_hacmpcheckapps"
        return (1)
end

dbcc istraceon(2227)
if @@error != -1
begin
        print "Proc name = '%1!'", "sp_hacmpcheckapps"
        print "Servername Id = '%1!'", @@servername
        print "Attribute Id = '%1!'", @attrib_id
end

/* Attribute Id should not be a group */
if @attrib_id = 0 or @attrib_id < 1000
begin
        print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
        return (1)
end

/* Check for valid Base attribute Id */
if @attrib_id != 0
begin
        select @attrib_type = attrib_type from
                                tempdb.dbo.ha_advisory_attrs where
                                attrib_id = @attrib_id
        if (@attrib_type is NULL)
        begin
                print "Internal Error: Attribute Id '%1!' not found", @attrib_id
                return(1)
        end
end

/* Initialize the variables */
select  @advisory = 0, @retstat = 0, @logrecord = 1

/* Check if trace 2202 is on; or Check only is on, log the record. */
dbcc istraceon(2202)
if @@error != -1
begin
        select @logrecord = 1
end

set nocount on

/*
** Sysjars
** The name and id of the java archive file should exists on the local server
** otherwise it is a hard fault.
*/
if (@attrib_id = 1760)
begin
	declare rmtsysjars_curs cursor for
		select jname from master.dbo.rmt_ha_sysjars
	open rmtsysjars_curs
	fetch rmtsysjars_curs into @rmt_jname

	select @attrib_name = 'Jar Files'
	select @attrib_id = attrib_id from tempdb.dbo.ha_advisory_attrs where
		attrib_type = 'Java Archives'

	while (@@sqlstatus = 0)
	begin
		if (not exists (select 1 from master.dbo.sysjars where
				jname = @rmt_jname))
		begin
			select @advisory = 2
			select @comment = "Java Jar files not installed"
			exec @retstat = sp_ha_logadvisory_rec @attrib_name, 
						'Java Archives', @attrib_id, 
						NULL, NULL, 0, @rmt_jname, 0,
						@advisory, @comment
			if @retstat != 0
				break
		end

		fetch rmtsysjars_curs into @rmt_jname
	end

	if (@@sqlstatus = 1)
		select @retstat = 1

	close rmtsysjars_curs
	deallocate cursor rmtsysjars_curs

	if (@retstat = 1)
		return (1)

	/*
	** sysxtypes
	*/
	declare sysxtypes_curs cursor for
		select xtutid, xtid, xtmetatype, xtstatus, xtcontainer, xtname
		from master.dbo.rmt_ha_sysxtypes
	open sysxtypes_curs
	fetch sysxtypes_curs into @xtutid, @xtid, @xtmetatype, @xtstatus, 
		@xtcontainer, @xtname

	select @attrib_name = "Java Types"
	select @attrib_id = attrib_id from tempdb.dbo.ha_advisory_attrs where
		attrib_type = 'Java Archives'

	/* Insert into local tables */
	while (@@sqlstatus = 0)
	begin

		if (not exists(select 1 from master.dbo.sysxtypes
			where xtname = @xtname))
		begin
			select @advisory = 2
			select @comment = "Missing Java objects"
			exec @retstat = sp_ha_logadvisory_rec 
					@attrib_name, 'Java Archives', 
					@attrib_id, NULL, NULL, 0, 
					@xtname, 0, @advisory, 
					@comment
			if @retstat != 0
				return (1)
		end
		else 
		begin
			/* 
			** names match, see if the java classes correspond to
			** the same jar file
			*/
			select @rmt_jname = jname from master.dbo.rmt_ha_sysjars
				where jid = @xtcontainer

			select @jname = jname from master.dbo.sysjars
				where jid in (select xtcontainer from 
				master.dbo.sysxtypes where xtname = @xtname)

			if (@rmt_jname != @jname)
			begin
				select @advisory = 2
				select @comment = "Java Type/JAR file Mismatch"
				exec @retstat = sp_ha_logadvisory_rec 
						@attrib_name, 'Java Archives', 
						@attrib_id, NULL, NULL, 0, 
						@xtname, 0, @advisory, 
						@comment
				if @retstat != 0
					return (1)
			end
			/* names match, check if they match other attributes */
			if (not exists (select 1 from master.dbo.sysxtypes 
				where xtname = @xtname and 
				xtstatus = @xtstatus and 
				xtmetatype = @xtmetatype and 
				xtutid = @xtutid))

			begin
				select @advisory = 2
				select @comment = "Java Types Mismatch"
				exec @retstat = sp_ha_logadvisory_rec 
						@attrib_name, 'Java Archives', 
						@attrib_id, NULL, NULL, 0, 
						@xtname, 0, @advisory, 
						@comment
				if @retstat != 0
					return (1)
			end
		end
		fetch sysxtypes_curs into @xtutid, @xtid, @xtmetatype, 
			@xtstatus, @xtcontainer, @xtname
	end
	if (@@sqlstatus = 1)
		select @retstat = 1

	close sysxtypes_curs
	deallocate cursor sysxtypes_curs
	if (@retstat = 1)
		return (1)
end

/*
** Synchronize Systypes
** All User defined data types have usertype > 100
*/
if (@attrib_id = 1740)
begin
	declare rmtsystypes_curs cursor for select usertype, name, variable, 
		allownulls, type, length, prec, scale, ident, hierarchy 
		from master.dbo.rmt_ha_systypes where 
		usertype > 100 order by usertype

	open rmtsystypes_curs
	fetch rmtsystypes_curs into @rmt_usertype, @rmt_name, @rmt_var, 
		@rmt_null, @rmt_type, @rmt_len, @rmt_prec, @rmt_scale, 
		@rmt_ident, @rmt_hierarchy

	select @attrib_name = "User Defined Types"
	select @attrib_id = attrib_id from tempdb.dbo.ha_advisory_attrs where
		attrib_type = 'User Types'
	/*
	** For every user defined type in the remote, if the same type exists 
	** in the local, it should match in all respects except possibly the 
	** id (usertype).  If that type does not exist in the local, it will 
	** be sync'd up later on during configuration.
	*/
	while (@@sqlstatus = 0)
	begin

		if (exists (select 1 from master.dbo.systypes where 
				name = @rmt_name))
		begin
			if (not exists (select 1 from master.dbo.systypes
				where name = @rmt_name and 
				variable = @rmt_var and 
				allownulls = @rmt_null and type = @rmt_type 
				and length = @rmt_len and prec = @rmt_prec and 
				scale = @rmt_scale and ident = @rmt_ident and
				hierarchy = @rmt_hierarchy))
			begin
				select @advisory = 2
				select @comment = "User Type Mismatch"
				exec @retstat = sp_ha_logadvisory_rec
						@attrib_name, 'User Types',
						@attrib_id, NULL,
						NULL, 0, @rmt_name, 0,
						@advisory, @comment
				if @retstat != 0
					break
			end
		end
		else
		begin
			/* 
			** Missing user type will be sync'd up 
			** during configuration 
			*/
			select @advisory = 1
			select @comment = "Missing User Type"
			exec @retstat = sp_ha_logadvisory_rec
					@attrib_name, 'User Types',
					@attrib_id, NULL,
					NULL, 0, @rmt_name, 0,
					@advisory, @comment
			if @retstat != 0
				break
		end
		fetch rmtsystypes_curs into @rmt_usertype, @rmt_name, 
			@rmt_var, @rmt_null, @rmt_type, @rmt_len, @rmt_prec, 
			@rmt_scale, @rmt_ident, @rmt_hierarchy
	end

	if (@@sqlstatus = 1)
		select @retstat = 1

	close rmtsystypes_curs
	deallocate cursor rmtsystypes_curs
	if (@retstat = 1)
		return (1)

end

/*
** Systimeranges
** This catalog always has an id = 1 for the name 'at all time' which need
** not be synchronized.
*/
if (@attrib_id = 1750)
begin
	declare rmtsystime_curs cursor for
		select name, id, startday, endday, starttime, endtime
		from master.dbo.rmt_ha_systimeranges where id > 1 order by id

	open rmtsystime_curs
	fetch rmtsystime_curs into @rmt_name, @rmt_id, @rmt_startday,
		@rmt_endday, @rmt_starttime, @rmt_endtime

	select @attrib_name = "Time Ranges"
	select @attrib_id = attrib_id from tempdb.dbo.ha_advisory_attrs where
		attrib_type = 'Time Ranges'
	/*
	** For every time range defined in the remote server, If there is an 
	** entry in the local, it should match exactly except possibly for the 
	** id.  If no such entry exists, it will be sync'd up at configuration 
	** time.
	*/
	while (@@sqlstatus = 0)
	begin

		if (exists (select 1 from master.dbo.systimeranges where
				name = @rmt_name))
		begin
			if (not exists (select 1 from master.dbo.systimeranges 
				where name = @rmt_name and 
				startday = @rmt_startday and 
				endday = @rmt_endday and 
				starttime = @rmt_starttime 
				and endtime = @rmt_endtime))

			begin
				select @advisory = 2
				select @comment = "Time Range Mismatch"
				exec @retstat = sp_ha_logadvisory_rec
						@attrib_name, 'Time Ranges',
						@attrib_id, NULL,
						NULL, 0, @rmt_name, 0,
						@advisory, @comment
				if @retstat != 0
					break
			end
		end
		else
		begin
			/* 
			** Missing time range will be sync'd up 
			** during configuration 
			*/
			select @advisory = 1
			select @comment = "Missing Time Range"
			exec @retstat = sp_ha_logadvisory_rec
					@attrib_name, 'Time Ranges',
					@attrib_id, NULL,
					NULL, 0, @rmt_name, 0,
					@advisory, @comment
			if @retstat != 0
				break
		end
		fetch rmtsystime_curs into @rmt_name, @rmt_id, @rmt_startday,
			@rmt_endday, @rmt_starttime, @rmt_endtime
	end

	if (@@sqlstatus = 1)
		select @retstat = 1

	close rmtsystime_curs
	deallocate cursor rmtsystime_curs

	if (@retstat = 1)
        return (1)
end
go

/*
** SP_HACHECKSYSATTRIBS
**
** Description:
**      This stored procedure's function is to do compatibility checks related
** to sysattributes table. Currently, value of only one attribute -
** "allow password downgrade" from this table is verified on companion server.
**
** Parameters:
**              @servername     : Name of the Companion server -- Input
**              @skip_error     : Skip on encountering an error-- Input
**              @check_only     : Check only                   -- Input
**              @attrib_id      : Attribute ID                 -- Input
**              @option         : to indicate some context     -- Input
** Design:
**
**      Attribute ID 1800 for 'allow password downgrade'
**
** Error Messages:
**
** Returns:
**              0 on success, 1 on failure.
*/
create procedure sp_hacmpchecksysattribs
@servername varchar(30)  = null, /* Name of the primary server */
@skip_error int,                 /* Skip the check on error (not used) */
@check_only int,                 /* Check only (not used) */
@attrib_id  int,                 /* attribute Id of interest */
@option     int                  /* Additional option (not used) */
as
declare
        @attrib_name varchar(255),      /* Attribute name */
        @attrib_type varchar(32),       /* Attribute type */
        @passdwngrdclass int,           /* Password downgrade class */
        @lintvalue int,                 /* Local value of type integer */
        @rintvalue int,                 /* Remote value of type integer */
        @retstat  int,
        @advisory int,
        @comment varchar(255)           /* Comments */

/* 17260, "Can't run %1! from within a transaction." */
if @@trancount != 0
begin
        raiserror 17260, "sp_hacmpchecksysattribs"
        return (1)
end

dbcc istraceon(2227)
if @@error != -1
begin
        print "Proc name = '%1!'", "sp_hacmpchecksysattribs"
        print "Servername Id = '%1!'", @servername
        print "Attribute Id = '%1!'", @attrib_id
end

/* Check for valid Base attribute Id */
if @attrib_id != 0
begin
        if not exists (select 1 from tempdb.dbo.ha_advisory_attrs where
                                attrib_id = @attrib_id and @attrib_id > 999)
        begin
                print "Internal Error: Invalid Attribute Id '%1!'", @attrib_id
                return(1)
        end
end

set nocount on

select @passdwngrdclass = object from master..sysattributes
        where char_value = "password downgrade class" AND object_type = "AC"

/* 
** Following query will insert the values of 'allow password downgrade' 
** if present in sysattributes table on either primary or secondary server
*/
create table #sysattributes_temp (int_value int)
insert into #sysattributes_temp
	select a.int_value from master.dbo.sysattributes a
		where a.class = @passdwngrdclass and a.attribute = 0
	union
	select b.int_value from master.dbo.rmt_ha_sysattributes b
		where b.class = @passdwngrdclass and b.attribute = 0

if exists (select * from #sysattributes_temp)
begin
        /* Get the local int value for 'allow password downgrade' attribute */
        select @lintvalue = int_value from master.dbo.sysattributes
                where class = @passdwngrdclass and attribute = 0

        /* 
	** Get the remote int value for 'allow password downgrade' 
	** attribute 
	*/
        select @rintvalue = int_value from master.dbo.rmt_ha_sysattributes
                where class = @passdwngrdclass and attribute = 0

	/*
	** Value of NULL for 'allow password downgrade' on one server and 0 
	** on the other indicate that the servers are in same state. Hence 
	** execute sp_ha_logadvisory_rec only when local values is not equal
	** to the remote value AND above mentioned combination does not exists
	*/
        if ((@lintvalue != @rintvalue) and
		( not (@lintvalue = NULL and @rintvalue = 0)) and
		( not (@lintvalue = 0 and @rintvalue = NULL)))
        begin
                /* Get the attribute type */
                select @attrib_type = attrib_type
                        from tempdb.dbo.ha_advisory_attrs
                        where attrib_id = @attrib_id

                /* Get the attribute name */
                select @attrib_name = char_value from master..sysattributes
                        where object = @passdwngrdclass AND object_type="A"

                select @advisory = 2
                select @comment = "Mismatch in values of " + @attrib_name
                exec @retstat = sp_ha_logadvisory_rec @attrib_name,
                                @attrib_type, @attrib_id, NULL, NULL,
                                @lintvalue, NULL, @rintvalue, @advisory,
                                @comment
                if @retstat != 0
                        return (@retstat)
        end
end
drop table #sysattributes_temp
go
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacmpaccessvrfy')
begin
	drop procedure sp_hacmpaccessvrfy
end
go
print "Installing sp_hacmpaccessvrfy"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
** SP_HACMPACESSVRFY
** This stored procedure verifies that specified remote server is
** configured correctly for remote access from the local server for
** HA Cluster operations. 
**
** Error Messages:
**
** 18748:"Server '%1!' does not have 'SYB_HACMP' server. Please install
**		HA services using 'installhasvss' and try again."	
** 18749:"Server '%1!' does not have HA DLLs loaded. See Administrator
**		manual for How to correct this problem"
** 18752:"Local server name can not be null
**	  Please add the local servername using sp_addserver
**	  Reboot the server for the change to take effect" 
**
** 18753:"HA cluster configurator requires name of companion server
**	  Server name specified is same as local server"
**
** 18754:"Omni-connection not enabled in server '%1!'. 
**	  Please enable it and reboot the server"
**
** 18755:"Server '%1!' does not have '%2!' as one of the remote servers. Please **	  add this server using sp_addsever"
**
** 18805:"Warning: Server '%1!' has been configured or is being configured. 
**	  SYB_HACMP server entry has already been configured."
**
** 18833:"Server name '%1!' specified is different than your current configured
** 	   companion server name '%2!'"
** 18834:"print "Server '%1!' has a local server name different than '%2!'. 
**	  Please rename the server to its original name '%3!' and try again."
*/
create procedure sp_hacmpaccessvrfy
@remoteservername varchar(30)		/* Name of the companion server */
as
declare @suid      int,            	/* suid to be inserted */
	@localservername varchar(30),	/* name of the local server */
	@local_haversion varchar(100),  /* Local HA DLL version */
	@srvnetname varchar(32),	/* Server netname */
	@cfgrunvalue int,		/* cfgrunvalue */
	@retstat int,			/* return status */
	@alivestatus int,		/* Server status */
	@msg varchar(1024)		/* Buffer to print messages */

/* Initialize the defaults */
select @retstat = 0, @localservername = @@servername

/*
** All companion operation require you to specify your companion server 
** not yourself. The local server should have a name. 
*/
if (@localservername is  null)
begin
	raiserror 18752
	return (1)
end

/* Your companion server is not you !! */
if (@remoteservername = @localservername)
begin
	raiserror 18753
	return(1)
end

/* Server should have the 'SYB_HACMP' entry, if HA installation true  */ 
if not exists(select 1 from master.dbo.sysservers where srvname = "SYB_HACMP")
begin
	raiserror 18748, @localservername
	return(1)
end

/* 
** Check if the local server is configured to execute omni-connection 
** connections and do omni/dtm rpc handling. Omni enable is a static value, 
** so if not configured inform the user and exit.
*/
select @cfgrunvalue = a.value from master.dbo.syscurconfigs a, 
			master.dbo.sysconfigures b where 
			a.config = b.config and b.name like 'enable cis'
if (@cfgrunvalue = 0)
begin
	raiserror 18754, @localservername
	return (1)
end

/* Make sure that state machine is running, if not return error */
dbcc ha_admin (' ', 'state_machine')

if @@error = -1
begin
	print "Server '%1!' in is in maintenance state ( halted ).", 
						@localservername
	return(1)
end
 
/*
** If server is already configured, name of the server, should
** match exactly as it is recorded in the @@hacmpservername, else
** there is an error
*/
if @@cmpstate > 0
begin
	/* Remote server specified should be same as your companion server */
	if @@hacmpservername != @remoteservername
	begin
		raiserror 18833, @remoteservername, @@hacmpservername
		return(1)
	end

	/* Flush any stale connection handles */
	dbcc  ha_admin ("SYB_HACMP", "conncheck")
	if (@@error != 0)
	begin
		raiserror 18756
		return(1)
	end

	/* Remote server should exists as local in server */ 
	if not exists (select 1 from master.dbo.rmt_ha_sysservers where 
			srvname = @remoteservername and srvid = 0)
	begin
		raiserror 18834, @remoteservername, @@hacmpservername, 
						@@hacmpservername
		return(1)
	end
end

/*
** Get the DLL version of the server. This would verify that server
** is loaded with the HA DLLs. 
*/
select @local_haversion = ha_get_version()
if (@local_haversion is null)
begin
	raiserror 18749, @localservername
	return(1)
end

/*
** Check to make sure that the current server is configured
** under OS/HA services, else there is no reason to run
** configuration on this server.
*/
select @alivestatus = ha_checkalive(@localservername)
if (@alivestatus != 0)
begin
	/*
	** Decifer the return status to see what is broken
	** We need different kinds of error status saying
	** Monitor - not up
	** Server  - not up
	** Server  - not in cluster
	** Devices - not 'all' sharable
	** Devices - database striped over master device
	** Package - No group configured
	** Packahe - ???
	** Addmore.
	*/
	raiserror 18737, @localservername
       	return (1)
end

/* Display Cluster Access Msg only if the 2201 flag is disabled */
dbcc istraceon(2201)
if @@error = -1
begin
	exec sp_getmessage 18736, @msg output
	print @msg, @localservername
end

/*
** Check if the remote server is added as remote server in local sysservers. 
** If so switch the physical pathname for SYB_HACMP to remote server and 
** verify the ctlib connection using an HA ctlib connection with remote sql 
** ping. We can not use handshake mechanism; as we may have not yet verified 
** the remote server capability and interfaces may not have been set.
*/
if not exists (select 1 from master.dbo.sysservers 
		where srvname like @remoteservername)
begin
	raiserror 18755, @localservername, @remoteservername
	return (1)
end

/*
** If the server is currently being configured by some
** other server, we may destroy the netname, so, if the
** server is in single server mode then the netname of
** SYB_HACMP  must be pointing to self. We need this for
** configuration command only. All other commands are
** checked in verifyargs for their proper companion.
*/
if (@@cmpstate = 0)
begin
	select @srvnetname = srvnetname from master.dbo.sysservers
		where srvname = @localservername

	if not exists (select 1 from master.dbo.sysservers where
			srvname like 'SYB_HACMP' and srvnetname
			like @srvnetname)
	begin
		raiserror 18805, @localservername
		return(1)
	end
end 

select @srvnetname = srvnetname from master.dbo.sysservers
		where srvname = @remoteservername
if not exists (select 1 from master.dbo.sysservers where 
		srvname like 'SYB_HACMP' and 
		srvnetname = @srvnetname)
begin
	exec @retstat =  sp_addserver "SYB_HACMP", null, @srvnetname 	
	if (@retstat != 0)
     		return(1)
end

/*
** Establish an omni connection to be on the defensive side for
** omni to initialize all the relevent Async structures.
*/
exec @retstat = sp_remotesql "SYB_HACMP", 
	"declare @retstat int select @retstat = id from master.dbo.syscharsets where type = 2001"

dbcc  ha_admin ("SYB_HACMP", "conncheck")
if (@@error != 0)
begin
	raiserror 18756
	return(1)
end

/*
** Now check the access using the remote server name
** this will flushout any, stale connection handles that exists
** if any
*/
dbcc  ha_admin (@remoteservername , "conncheck")
if (@@error != 0)
begin
	raiserror 18756
	return(1)
end
return(0)
go
go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_hacluster')
begin
	drop procedure sp_hacluster
end
go
print "Installing sp_hacluster"
go

/*
** SP_HACLUSTER
** This procedure showes or sets the underlying cluster server for the current  
** ASE.
**
** Messages:
** 18704, "Procedure '%1!' requires the server '%2!' booted with
**        -H option. Please refer to System Administartion Manual for
**        High Availability Services."
** 18769, "The HA cluster is currently in use for other cluster operations. 
**        Retry the command later. If the problem persists, it may be due to 
**	  an earlier failed cluster command; check the System Administration
**	  Guide (Error %1!)."
** 18905, "Default cluster is not set, please check if HA is enabled on the 
**	  current server."
** 18906, "The default cluster does not have a name specified in the system 
**	  table. Please report this to Sybase Inc."
** 18907, "The cluster '%1!' has not been supported. Please check the current 
**	  supported cluster list."
** 18908, "The current cluster is set to %1!."
** 18909, "The default cluster is: %1!."
** 18910, "The current cluster does not have a name specified in the system 
**	  table. Please report this to Sybase Inc."
** 18911, "Supported cluster systems for %1! are:"
** 18912, "Supported cluster systems are:"
** 18913, "Setting cluster failed, please check the error log."
*/
create procedure sp_hacluster
@remoteserver	varchar(30),    	/* name of remote server */
@cmd		varchar(20)  = null,	/* desired hacluster cmd */
@option		varchar(20)  = null	/* additional arguments */
as
declare @retstat int                    /* return value of executing a SQL */
declare @msg varchar(1024)              /* temp buffer for messages */
declare @cluster_id int                 /* the cluster id */
declare @os_name varchar(30)            /* operating system name */
declare @cluster_name varchar(30)       /* cluster system name */

/*
** Set the local cluster platform. It doesn't set the cluster platform on 
** other nodes.
** If we want to do a consistent change across servers in this cluster,
** this section should be moved later after checking the access to
** companion server(s) and acquiring the global cluster lock.
*/
if (@cmd = "set_cluster")
begin
	select @retstat = 1

	if (@option = "default" or @option = "DEFAULT" or @option IS NULL)
	begin
		dbcc ha_admin(@remoteserver, "set_cluster", -1)
		if (@@error != 0)
		begin
			exec sp_getmessage 18913, @msg output
			print @msg
                        goto clean_all
		end

		select @retstat = 0

		exec sp_getmessage 18908, @msg output
		print @msg, "default"
		goto clean_all
	end

	/* get the default cluster ID from sysattributes */
	select @cluster_id = -1
	select @cluster_id = int_value
	from master.dbo.sysattributes
	where class = 10 and attribute = 8

	if (@cluster_id < 0)
	begin
		/* the error will be changed later */
		raiserror 18905
		goto clean_all
	end

	/* Get the OS name */
	select @os_name = ""
	select @os_name = name
	from master.dbo.spt_values
	where low = @cluster_id and number < 1000 and type = "ha"

	if (@os_name = "")
	begin
		raiserror 18906
		goto clean_all
	end
	select @cluster_id = charindex("|", @os_name) -1
	select @os_name = substring(@os_name, 1, @cluster_id)

	/* Get the cluster id the user is asking */
	select @cluster_name = @os_name + "|" + @option
	select @cluster_id = -1
	select @cluster_id = low
	from master.dbo.spt_values
	where number < 1000 and type = "ha" and name = @cluster_name

	if (@cluster_id < 0)
	begin
		raiserror 18907, @option
		goto clean_all
	end

	dbcc ha_admin(@remoteserver, "set_cluster", @cluster_id)
	if (@@error != 0)
	begin
		exec sp_getmessage 18913, @msg output
		print @msg
		goto clean_all
	end
	select @retstat = 0

	exec sp_getmessage 18908, @msg output
	print @msg, @option

	goto clean_all
end

/*
** Show the current cluster, default cluster, and all supported
** cluster on the current OS or the given OS
*/
if (@cmd = "show_cluster")
begin
	select @retstat = 1

	/* Get supported clusters for given OS */
	if (@option = "any" or @option = "ANY")
	begin
		exec sp_getmessage 18912, @msg output
		print @msg

		declare cluster_c1 cursor for
		select name from master.dbo.spt_values
		where number < 1000 and type = "ha"

		open cluster_c1

		fetch cluster_c1 into @cluster_name

		while (@@sqlstatus != 2)
		begin
			if (@cluster_name IS NOT NULL)
			begin
				select @cluster_name = stuff(@cluster_name, charindex("|", @cluster_name), 1, "  ")
				print @cluster_name
			end

			fetch cluster_c1 into @cluster_name
		end

		close cluster_c1

		select @retstat = 0
		goto clean_all
	end

	if (@option IS NOT NULL)
	begin
		exec sp_getmessage 18911, @msg output
		print @msg, @option

		declare cluster_c2 cursor for
		select name from master.dbo.spt_values
		where number < 1000 and type = "ha"
				and name like (@option + "|%")

		open cluster_c2

		fetch cluster_c2 into @cluster_name

		while (@@sqlstatus != 2)
		begin
			if (@cluster_name IS NOT NULL)
			begin
				select @cluster_name = stuff(@cluster_name, 1, charindex("|", @cluster_name), NULL)
				print @cluster_name
			end

			fetch cluster_c2 into @cluster_name
		end

                close cluster_c2

		select @retstat = 0
		goto clean_all
	end

	/* get the default cluster */
	select @cluster_id = -1
	select @cluster_id = int_value
	from master.dbo.sysattributes
	where class = 10 and attribute = 8

	if (@cluster_id < 0)
	begin
		raiserror 18905
		goto clean_all
	end

	/* Get the cluster name */
	select @cluster_name = ""
	select @cluster_name = name
	from master.dbo.spt_values
	where low = @cluster_id and number < 1000 and type = "ha"

	if (@cluster_name = "")
	begin
		raiserror 18906
		goto clean_all
	end

	select @os_name = substring(@cluster_name, 1, (charindex("|", @cluster_name) - 1))
	select @cluster_name = substring(@cluster_name, (charindex("|", @cluster_name) + 1), char_length(@cluster_name))

	/* print the default cluster name */
	exec sp_getmessage 18909, @msg output
	print @msg, @cluster_name

	/* Get the current cluster */
	select @cluster_id = -1
	select @cluster_id = int_value
	from master.dbo.sysattributes
	where class = 10 and attribute = 9

	select @cluster_name = ""
	if (@cluster_id >= 0)
	begin
		/* Get the cluster name */
		select @cluster_name = name
		from master.dbo.spt_values
		where low = @cluster_id and number < 1000 and type = "ha"

		if (@cluster_name = "")
		begin
			raiserror 18910
			goto clean_all
		end
	end

	if (@cluster_name = "")
		select @cluster_name = "default"
	else
		select @cluster_name = substring(@cluster_name, (charindex("|", @cluster_name) + 1), char_length(@cluster_name))

	/* print the current cluster name */
	exec sp_getmessage 18908, @msg output
	print @msg, @cluster_name

	/* Get supported clusters for the current OS */
	exec sp_getmessage 18911, @msg output
	print @msg, @os_name
	declare cluster_c3 cursor for
	select name from master.dbo.spt_values
	where number < 1000 and type = "ha"
			and name like (@os_name + "|%")

	open cluster_c3

	fetch cluster_c3 into @cluster_name

	while (@@sqlstatus != 2)
	begin
		if (@cluster_name IS NOT NULL)
		begin
			select @cluster_name = stuff(@cluster_name, 1, charindex("|", @cluster_name), NULL)
			print @cluster_name
		end

		fetch cluster_c3 into @cluster_name
	end

	close cluster_c3
	select @retstat = 0
	goto clean_all

end
clean_all:

        return(@retstat)
go

go
dump tran sybsystemprocs with truncate_only
go
dump transaction sybsystemprocs with truncate_only
go
if exists (select *
	from sysobjects
		where sysstat & 7 = 4
			and name = 'sp_companion')
begin
	drop procedure sp_companion
end
go
print "Installing sp_companion"
go

/* Sccsid = "%Z% sun_svr4/sproc/src/%M% %I% %G%" */
/*
** SP_COMPANION
** This procedure makes the current server as a companion
** secondary of the specified server.
**
** WARNING: Do not add any code that references the tables ha_advisory_attrs
** and ha_advisory as we will get into SP compilations if these tables do not
** exist in tempdb after a server reboot.
**
** Error Messages:
**
** 18703, "Please execute the procedure '%1!' from master database"
** 18704, "Procedure '%1!' requires the server '%2!' booted with
**	  -H option. Please refer to System Administartion Manual for
**	  High Availability Services.
** 18719, "Server '%1!' is configured for HA services"
** 18720, "Server '%1!' is currently in '%2!' mode"
** 18722, "Server is currently configured, drop and retry"
** 18723, "Error 18723:Handshake Failed"
** 18724, "Error 18724:Unable to access Master device path from Companion"
** 18725, "Error 18725:Companion configuration verification failed"
** 18726, "Error 18726:Unable to initialize servers for configuration"
** 18727, "Error 18727:Cannot configure servers, state machine error"
** 18728, "Error 18728:Update to local server catalog failed, retry command"
** 18729, "Error 18729:Update to remote server catalog failed, retry command"
** 18730, "Error 18730:Syncup of Userinfo failed"
** 18731, "Error 18731:Unable to create system proxy databases"
** 18791, "Error 18791:Unable to drop system proxy databases"
** 18732, "Error 18732:Shutdown of failled-over user databases failed"
** 18733, "Error 18733:Shutdown of failled-over master database failed"
** 18734, "Error 18734:Drop of failled-over databases failed"
** 18735, "Error 18735:Drop of failled-over devices failed"
** 18736, "Server '%1!' is alive and cluster configured" 
** 18737, "Server '%1!' is not cluster configured" 
** 18836, "Configuration operation '%1!' can not proceed due to Quorum 
** 	   Advisory Check failure. Please run 'do_advisory' command to find 
**	   the incompatible attribute and fix it"
** 18837, "Could not release the resources back to server '%1!'. Please refer 
**	   to System Administration manual as how to correct this problem.
** 18838, "Procedure 'sp_companion' can not be executed from a session with 
**	   failover property"
** 18839, "Insufficient free open databases or connections for successful 
**	   failover. Please refer to System Administration manual as how to 
**	   correct this problem.
** 18852, "Step: Access verified from Server:'%1!' to Server:'%2!'."
** 18853, "Step: Companion server's configuration check succeeded."
** 18854, "Step: Server handshake succeeded."
** 18855, "Step: Master device accessible from companion."
** 18856, "Could not cluster-configure the servers."
** 18863, "Step: Added the servers '%1!' and '%2!' for cluster configuration."
** 18864, "Step: Server configuration initialization succeeded."
** 18865, "Step: User information synchronization succeeded."
** 18866, "Step: Server configured in normal companion mode."
** 18867, "Error: Could not remove de-cluster servers."
** 18868, "Step: Removed the servers '%1!' and '%2!' from cluster configuration."
** 18869, "Step: syssession information synchronization succeeded."
** 18870, "Step: Primary databases are shutdown in secondary."
** 18871, "Step: Primary databases dropped from current secondary."
** 18872, "Step: Primary devices released from current secondary."
** 18873, "Step: Prepare failback for primary server completed successfully."
*/
create procedure sp_companion
@remoteserver varchar(30)  = null,	/* Name of the primary server */
@cmd	      varchar(20)  = null,	/* desired companion cmd */
@option       varchar(20)  = null,
@srvlogin     varchar(30)  = "sa",	/* server login for HA monitors */
@srvpwd       varchar(31)  = null,	/* server login password */
@cluslogin    varchar(30)  = "sa",	/* clus login for OS/HA */
@cluspwd      varchar(31)  = null	/* clus login password */
as
declare @Lnextstate int			/* next local server state */
declare @Rnextstate int			/* next remote server state */
declare @status	smallint		/* original status */
declare @cfgrunvalue int		/* original status */
declare @retstat int			/* return value of executing a SQL */
declare @sqlstat int			/* return value of executing a SQL */
declare @cmpstate int			/* Current companion server status */
declare @oldstate int			/* Old companion server status */
declare @sortorder_id int		/* current sortorder id */
declare @charset_id int			/* current charset id */
declare @dbid int			/* current database id */
declare @objid int			/* object id */
declare @localserver varchar(30)	/* local server name */
declare @srvnetname varchar(30)		/* server netname */
declare @servermode  varchar(20)	/* local server name */
declare @msg varchar(1024)		/* temp buffer for messages */
declare @dbstatus3 int			/* Status 3 bit of sysdatabases */
declare @clean_cursor int               /* Clean up all the cursors */
declare @sortorder_desc varchar(255)	/* description of default sort order */
declare @advisory int			/* advisory generated */
declare @logoption int			/* various options tracked in this */
declare @advaction varchar(20)		/* desired advisory action */
declare @maxdbid_local int		/* local maximum dbid */
declare @maxdbid_remote int		/* companion maximum dbid */
declare @maxdbid_retry int		/* boolean to control retries */
declare @maxdbid_retry_limit int     	/* retry limit on the retries */

/* Initialize the defaults */
select @retstat = 0, @logoption = 0
select @localserver = @@servername
select @dbid = db_id(), @advisory = 0
select @cmpstate = @@cmpstate

/* If command is 'do_advisory', the default option should be 'compute' */
if (@cmd = "do_advisory")
begin
	if (@srvlogin = "sa")
		select @srvlogin = "compute"
end

/* The default action is to compute advisory unless user asked for 'display' */
select @advaction = "compute"

/*
** README HERE for using 'logoption'
**
** Log options are the options that are passed to routine sp_loglocalstate'
** these inturn translate into desired values in the persistent store.
**
** Currently We are using 
**		01	-- 0x1 	-- for storing the option, that user had
**				   requested a 'with_proxydb' option
**
**		02	-- 0x2  -- for resettting the option 'with_proxydb'
**				   that is there in the persisent store. 
**
**		04	-- 0x4  -- for marking the node that suspend or
**				   the prepare failback command was run
**				   from this node.
**
**		08	-- 0x8	-- for unmarking the node for having run
**				   the suspend or prepare failback command
**				   This will turn off as a result of resume
*/

/*
**  Disallow running sp_companion within a transaction since it might make
**  recovery impossible.
*/
if @@trancount > 0
begin
        /*
        ** 17260, "Can't run %1! from within a transaction."
        */
	raiserror 17260, "sp_companion"
        return (1)
end
else
begin
        set chained off
end

/* Do Execution checks: 
** 	Must have sa_role to run these commands 
** 	Make sure that the procedure is executed from master database 
** 	Make sure the server is booted with -H option 
*/
if (proc_role("ha_role") < 1)
begin
        return (1)
end
if ( @dbid != 1 )
begin
	raiserror 18703, "sp_companion"
	return(1)
end
if (@cmpstate = -2)
begin
	raiserror 18704, "sp_companion", @localserver
	return(1)
end

/* A previous execution might have left behind the stale transtate */
if @@transtate = 3
begin
	begin tran
		select @cmpstate = @@cmpstate
	commit
end
 
/*
** Do not allow connections with -Q (failover property to run sp_companion)
*/
if @@haconnection != 0
begin
	raiserror 18838
	return(1)
end

/* 
** Verify that ha_advisory and ha_advisory_attrs tables exist in tempdb.  
** Otherwise create and initialize them.  Since these tables are in tempdb, it
** is possible that they no longer exist after a server reboot.  Most HA SPs
** will reference these tables and they should exist.
*/
if (not exists (select 1 from tempdb.dbo.sysobjects where
        name = 'ha_advisory_attrs' and type = 'U'))
begin
	dbcc printolog("HA_LOG:Creating/Initializing ha_advisory_attrs table in tempdb")

	exec @retstat = sp_ha_crtbladvisory_attrs
	if (@retstat != 0)
		return(1)
	else
		exec sp_ha_initadvisory_attrs
end

if (not exists (select 1 from tempdb.dbo.sysobjects where
        name = 'ha_advisory' and type = 'U'))
begin
	dbcc printolog("HA_LOG:Creating/Initializing ha_advisory table in tempdb")

	exec @retstat = sp_ha_crtbladvisory
	if (@retstat != 0)
		return(1)
	else
	begin
		exec @retstat = sp_ha_initadvisory "all", "display"
		if (@retstat != 0)
			return(1)
	end
end

/* Verify the arguments to the procedure */
exec @retstat = sp_havrfyargs @remoteserver, @cmd, @option, 
			@srvlogin, @srvpwd, @cluslogin, @cluspwd
if (@retstat != 0)
	return(1)

/* If there was no command specified then just return */
if (@cmd IS NULL)
	return(0)

/*
** First get the local cluster lock
*/
dbcc ha_admin(" ", "clusterlock", "aquire")
if (@@error != 0)
begin
	raiserror 18769, @@error
	return(1)
end

/* set_cluster command */
if (@cmd = "set_cluster")
begin
	exec @retstat = sp_hacluster @remoteserver, @cmd, @option
	if (@retstat !=0)
	begin
		goto clean_all
        end
	dbcc ha_admin(" ", "clusterlock", "release")
        return(@retstat)
end

/* show_cluster command */
if (@cmd = "show_cluster")
begin
	exec @retstat = sp_hacluster @remoteserver, @cmd, @option
	if (@retstat !=0)
	begin
		goto clean_all
	end
	dbcc ha_admin(" ", "clusterlock", "release")
        return(@retstat)
end

/* If user has requested an advisory help return */
if (@cmd = "do_advisory")
begin
	/* If we have already printed the  help information, return */
	if @option IS null or @option = "help"
		goto clean_all
end

/* First verify the proper access to/from the companion server */
if (@cmd != "prepare_failback")
begin
	exec @retstat = sp_hacmpaccessvrfy @remoteserver
	if ((@retstat != 0) or (@@error != 0))
	begin
		select @retstat = 1
		goto clean_all
	end

	/* Ok now obtain the cluster lock */
	dbcc ha_admin("SYB_HACMP", "clusterlock", "aquire")
	if (@@error != 0)
	begin
		raiserror 18769, @@error
		select @retstat = 1
		goto clean_all 
	end
		
	/* Report the Access verification, if cmd is not advisory */
	if @cmd != "do_advisory"
	begin
		/*
		** 18852, "Step: Access verified from Server:'%1!' to 
		** Server:'%2!'"
		*/
		exec sp_getmessage 18852, @msg output
		print @msg, @localserver, @remoteserver
	end

	select @msg = "exec sp_hacmpaccessvrfy  " + @localserver
	exec @retstat = sp_remotesql "SYB_HACMP", @msg
	if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
	begin
		select @retstat = 1
		goto clean_all 
	end

	/* Now both the Local and remote have been initialized */
	
	/* Report the Access verification, if cmd is not 'do_advisory' */
	if @cmd != "do_advisory"
	begin
		/*
		** 18852, "Step: Access verified from Server:'%1!' to 
		** Server:'%2!'"
		*/
		exec sp_getmessage 18852, @msg output
		print @msg, @remoteserver, @localserver
	end
end

/* First verify the proper access to the companion server */
exec @retstat = sp_havrfy @remoteserver, @cmd 
if ((@retstat != 0) or (@@error != 0))
begin
	/* sp_vrfy would have already printed error */
	select @retstat = 1
	goto clean_all 
end

/* If user has requested a advisory check do it now */
if (@cmd = "do_advisory")
begin
	/* if user wants only display, just do that */
	if (@srvlogin = "display")
		select @advaction = "display"

	/* If we have already printed the  help information, return */
	if @option IS NOT null or @option != "help"
		exec @retstat = sp_hacmpadvisory @remoteserver, @option, 
					@advaction, @advisory output
	goto clean_all
end

/* 
** Do essential configuration checks on local server based on
** current server state
*/ 
if (@cmd = "configure")
begin
	/*
	** We need to make sure that the bear essential attributes
	** are checked for companion compatibility. This will be 
	** forced to run for these commands, as we do not want to
	** fail for any incompatibilities  that might exists.
	** give user a chance to clean up
	*/
	dbcc istraceon(2203)
	if @@error = -1		
	begin
		exec @retstat = sp_hacmpadvisory @remoteserver, "all",
					"intcheck", @advisory output
		/*
		** Some thing is not write here, print the generic error msg
		*/
		if @retstat != 0
		begin
			goto clean_all
		end
	end

	/*
	** Check we have any major incompatiility that exists to proceede
	*/
	if @advisory >= 2 
	begin
		/* 
		** If user has not used a force option, then fail it 
		** and display the advisory details
		*/
		dbcc istraceon(2203)
		if @@error = -1		
		begin
			raiserror 18836, @cmd
			select @retstat = 1
			exec sp_ha_displayadvisory "all", "display"
			goto clean_all
		end
	end

	exec @retstat = sp_hacmpcfgvrfy @remoteserver,  @option 
	if ((@retstat != 0) or (@@error != 0))
	begin
		raiserror 18725
		select @retstat = 1
		goto clean_all 
	end

	/* Report the verification step */
	/*
	** 18853, "Step: Companion server's configuration check succeeded."
	*/
	exec sp_getmessage 18853, @msg output
	print @msg
end

/*
** If the command is prepare_failback, check for indoubt transactions and
** also, drop ha proxies
*/
if (@cmd = "prepare_failback")
begin
	dbcc ha_admin(" ", "preparechk_drop", " ")
	if (@@error !=0)
	begin
		select @retstat = 1
		goto clean_all 
	end
end	


if (@cmd = "configure") 	/* configure */
begin
	/*
	** Initialize if option 'with_proxydb' is enabled
	** only when doing a Assymmetric HA ASE configuration
	*/
	if @option = "with_proxydb" and @@cmpstate = 0
		select @logoption  = @logoption | 1
		
	/* If we had turned on the globalflag 2206, then enable it */
	dbcc istraceon(2206)
	if @@error != -1
	begin
		/* Make sense only during the Assymmetric Configuration */
		if @@cmpstate = 0
		begin
			 select @logoption  = @logoption | 1
		end
	end
	
	/*
	** if we reached this far we seem to set locally to do a handshake
	** to the remote server. We do not know yet anthing about the 
	** remote server. Do a handshake. This tests the full-duplex
	** commnication as sa with the same passwords
	*/
	dbcc ha_admin(@remoteserver, handshake)
	if (@@error != 0 )
	begin
		raiserror 18723
		select @retstat = 1	
		goto clean_all 
	end

	/* Report the access across servers using handshake succeeded*/
	/* 18854, "Step: Server handshake succeeded" */
	exec sp_getmessage 18854, @msg output
	print @msg

	/*
	** OK make sure that the master device has different
	** pathnames abd are accessible
	*/
	dbcc ha_admin(@remoteserver, pathname, master)
	if (@@error != 0)
	begin
		raiserror 18724
		select @retstat = 1	
		goto clean_all 
	end

	/* Report the access to master device succeeded */
	/* 18855, "Step: Master device accessible from companion" */
	exec sp_getmessage 18855, @msg output
	print @msg

	/*
	** OK before we begin the extensieve configuration checks
	** and synchronization, lets make them as cluster companions
	*/
	select @retstat = ha_add_companion(@localserver, @remoteserver,
						@srvlogin, @srvpwd,
						@cluslogin, @cluspwd)
	if (@retstat !=0)
	begin
		/* 18856, "Could not cluster-configure the servers." */
		raiserror 18856
		print "Local server:'%1!'", @localserver
		print "Remote server:'%1!'", @remoteserver
		print "Remote Server login:'%1!'", @srvlogin
		print "Remote Server password:'%1!'", @srvpwd
		print "Cluster login:'%1!'", @cluslogin
		print "Cluster password:'%1!'", @cluspwd
		goto clean_all 
	end
	
	/* Display the Message only if the Trace flag 2201 is not ON */
	dbcc istraceon(2201)
	if @@error = -1
	begin
		/* 
		** 18863, "Step: Added the servers '%1!' and '%2!' for cluster 
		** configuration."
		*/
		exec sp_getmessage 18863, @msg output
		print @msg, @localserver, @remoteserver
	end

	/* Ok now begin the state change */
	dbcc ha_admin("SYB_HACMP", state, configure)
	if (@@error != 0)
	begin
		raiserror 18726
		select @retstat = 1	
		goto clean_all 
	end

	/* 
	** OK we have now calculated the next states of the local and
	** remote servers, get it.
	*/
	select @Lnextstate = @@localstate
	select @Rnextstate = @@remotestate

	if (@Lnextstate = -1 or @Rnextstate = -1)
	begin
		raiserror 18727
		raiserror 18722
		select @retstat = 1	
		goto clean_all 
	end

	/* 
	** make sure the local server has resources such as dbts, connections, 
	** etc to handle failover. If not, print error and return.
	*/
	dbcc ha_admin(" ", "reserve_resource")
	if (@@error != 0 )
	begin
		raiserror 18839
		select @retstat = 1	
		goto clean_all		
	end

	/*
	** OK starting from now on we are planning to do everything in
	** distributed DTM mode, so start a master transaction now
	*/
	begin tran configsrvrs
	dbcc printolog("HA_LOG:State Change:Started")
	exec sp_remotesql "SYB_HACMP", 
			" dbcc printolog('HA_LOG:State Change:Started')"

	/*
	** At this statge we have calculated the next states aswell
	** now log the states into sysattributes on individul servers
	*/
	exec @retstat = 
          sp_loglocalstate @localserver, configure, @Lnextstate, 
					@srvlogin, @logoption
	if (@retstat !=0)
	begin
		rollback configsrvrs
		raiserror 18728
		goto clean_all 
	end

	/* 
	** Make sure all of them uses the same connection, hence SYB_HACMP
	** instead of @remoteserver
	*/
	exec @retstat = 
	   sp_logremotestate "SYB_HACMP", configure, @Rnextstate,
					@srvlogin, @logoption

	if (@retstat !=0)
	begin
		rollback configsrvrs
		raiserror 18729
		goto clean_all 
	end
		
	/* Report step for config initialization */
	/* 18864, "Step: Server configuration initialization succeeded." */
	exec sp_getmessage 18864, @msg output
	print @msg

	/*
	** Now syncup from the primary
	*/
	exec @retstat = sp_hasyncuserinfo "SYB_HACMP", 1, 0, 0 
	if (@retstat !=0)
	begin
		rollback configsrvrs
		raiserror 18730
		goto clean_all 
	end

	/* Report Step */
	/* 18865, "Step: User information synchronization succeeded." */
	exec sp_getmessage 18865, @msg output
	print @msg

	commit tran  configsrvrs

	/* Now Log the State Change Complete msg */
	dbcc printolog("HA_LOG:State Change:Completed")
	exec sp_remotesql "SYB_HACMP", 
			" dbcc printolog('HA_LOG:State Change:Completed')"

	/* now exchange the configurations only when in asymmetic secondary */
	if (@Lnextstate = 2)
	begin
		/* 
		** attempt to set the maxdbid on both companion servers.
		** if they are not equal, retry maxdbid_retry_limit times
		** before giving up.
		*/
		select @maxdbid_retry_limit = 3
		select @maxdbid_retry = 1
		while (@maxdbid_retry = 1)
		begin
			select @maxdbid_retry_limit = @maxdbid_retry_limit -1
			dbcc ha_admin(@remoteserver, config_init)

			select @maxdbid_remote = 0, @maxdbid_local = 0
			select @maxdbid_local = object_info3 from 
				master.dbo.sysattributes where class = 10
			select @maxdbid_remote = object_info3 from 
				master.dbo.rmt_ha_sysattributes where class = 10
		
			if ((@maxdbid_local != @maxdbid_remote) or
				(@maxdbid_retry_limit < 0))
				select @maxdbid_retry = 0
		end
		if @maxdbid_local != @maxdbid_remote
		begin
			print "Fatal Error in MAXDBID attribute synchronization"
			print "Please drop the current companion configuration and retry"
			return(1)
		end
		/*
		** Only do HA proxy database creation, if the 'with_proxydb'
		** option was successfully initialized.
		*/ 
		if @logoption & 1 in (1)
		begin
			exec @retstat = sp_haproxydb @remoteserver, "create" 
						
			if ((@retstat != 0) or (@@error != 0))
			begin
				/*
				** 18731, "Error 18731:Unable to create system 
				** proxy databases"
				*/
				raiserror 18731
				select @retstat = 1
				goto clean_all 
			end
		end
	end

	/* Report step */
	/* 18866, "Step: Server configured in normal companion mode." */
	exec sp_getmessage 18866, @msg output
	print @msg

	dbcc ha_admin(" ", "clusterlock", "release")
	
	return(0)
end
else if (@cmd = "drop")
begin
	/* Ok now begin the state change */
	select @cmpstate = @@cmpstate

	dbcc ha_admin("SYB_HACMP", state, "drop")
	if (@@error != 0)
	begin
		raiserror 18726
		select @retstat = 1	
		goto clean_all 
	end

	/* 
	** OK we have now calculated the next states of the local and
	** remote servers, get it.
	*/
	select @Lnextstate = @@localstate
	select @Rnextstate = @@remotestate

	if (@Lnextstate = -1 or @Rnextstate = -1)
	begin
		raiserror 18727
		raiserror 18722
		select @retstat = 1	
		goto clean_all 
	end
	
	/*
	** If we are dropping the configuration to move to single server
	** mode, if proxy is enabled, reset it.
	*/
	if @@crthaproxy = 1 and  @Lnextstate = 0 and  @Rnextstate = 0
		select @logoption  = @logoption | 2

	/*
	** At this statge we have calculated the next states aswell
	** now log the states into sysattributes on individul servers
	*/
	begin tran  configsrvrs
	dbcc printolog("HA_LOG:State Change:Started")
	exec sp_remotesql "SYB_HACMP", 
			" dbcc printolog('HA_LOG:State Change:Started')"

	exec @retstat = sp_loglocalstate @localserver, configure, @Lnextstate, 
						@srvlogin, @logoption
	if ((@retstat != 0) or (@@error != 0))
	begin
		rollback configsrvrs
		raiserror 18728
		select @retstat = 1
		goto clean_all 
	end

	exec @retstat = sp_logremotestate "SYB_HACMP", configure, @Rnextstate, 
						@srvlogin, @logoption
	if (@retstat !=0)
	begin
		rollback configsrvrs
		raiserror 18729
		goto clean_all 
	end

	commit tran configsrvrs

	/* Now Log the State Change Complete msg */
	dbcc printolog("HA_LOG:State Change:Completed")
	exec sp_remotesql "SYB_HACMP", 
			" dbcc printolog('HA_LOG:State Change:Completed')"
	
	/*
	** OK Now that the states have been changed, lets drop the
	** system proxies that we created. Note that drop command
	** is allways executed from the secondary. So only remove
	** the proxies that we created in both the servers, only
	** if go back to single server mode.
	*/
	if (@Rnextstate = 0 and @Lnextstate = 0)
	begin
		exec @retstat = sp_haproxydb "SYB_HACMP", "drop" 
		if ((@retstat != 0) or (@@error != 0))
		begin
			select @retstat = 1
			goto clean_all
		end
	end

	/*
	** OK now that we have dis-associated the configuration for
	** companion ship, we need to inform HA for resource monitoring.
	*/
	select @retstat = ha_remove_companion(@remoteserver)
	if (@retstat !=0)
	begin
		/* 18867, "Error: Could not remove de-cluster servers." */
		raiserror 18867
		print "Local server:'%1!'", @localserver
		print "Remote server:'%1!'", @remoteserver
	end
	
	/*
	** Now change the SYB_HACMP entries to point to local servers netname
	** We got to do this as the last item as we no more require any
	** communication with the companion using the proxy remote tables.
	*/
	if (@Rnextstate = 0 and @Lnextstate = 0)
	begin
		select @srvnetname = srvnetname from master.dbo.sysservers 
				where srvname = @remoteserver
		exec @retstat = sp_remotesql "SYB_HACMP", 
				"sp_addserver SYB_HACMP, null, ", @srvnetname 
		if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
		begin
			select @retstat = 1
			goto clean_all
		end

		select @srvnetname = srvnetname from master.dbo.sysservers where
				srvname = @localserver
		exec sp_addserver "SYB_HACMP", null, @srvnetname
	end
	
	/* Print only if 2201 Trace is not on */
	dbcc istraceon(2201)
	if @@error = -1	
	begin
		/* 
		** 18868, "Step: Removed the servers '%1!' and '%2!' from 
		** cluster configuration."
		*/
		exec sp_getmessage 18868, @msg output
		print @msg, @localserver, @remoteserver
	end
	dbcc ha_admin(" ", "clusterlock", "release")
	return(0)
end
else if (@cmd = "suspend")
begin
	select @cmpstate = @@cmpstate
	/*
	** Before suspending the configuration, check if the
	** state transition is allowed
	*/
	dbcc ha_admin(@remoteserver, state, suspend)
	if (@@error != 0)
	begin
		raiserror 18727
		raiserror 18722
		select @retstat = 1	
		goto clean_all 	
	end

	/* OK we have now calculated the next states of the local and
	** remote servers, get it.
	*/
	select @Lnextstate = @@localstate
	select @Rnextstate = @@remotestate

	/* 
	** We expect a valid values for next states in both local
	** and in remote servers
	*/
	if (@Lnextstate = -1 or @Rnextstate = -1)
	begin
		raiserror 18727
		raiserror 18722
		select @retstat = 1	
		goto clean_all 
	end

	/*
	** Based on the state machine set the server state of the
	** local and remote servers. Do this under a distributed tran
	*/
	begin tran  configsrvrs
	dbcc printolog("HA_LOG:State Change:Started")
	exec sp_remotesql "SYB_HACMP", 
			" dbcc printolog('HA_LOG:State Change:Started')"

	/* 
	** Mark the node that suspend was run from here, need identification
	** only in the case of symmetric mode 
	*/
	if @Lnextstate = 13 
		select @logoption = 4

	exec @retstat = 
	   sp_loglocalstate @localserver, suspend, @Lnextstate, 
			@srvlogin, @logoption
	if (@retstat !=0)
	begin
		rollback configsrvrs
		raiserror 18728
		goto clean_all 
	end

	/* 
	** UnMark the node that suspend was not run from here, 
	** need identification only in the case of symmetric mode 
	*/
	if @Lnextstate = 13 
		select @logoption = 8

	exec @retstat = 
	    sp_logremotestate "SYB_HACMP", suspend, @Rnextstate, 
			@srvlogin, @logoption
	if (@retstat !=0)
	begin
		rollback configsrvrs
		raiserror 18729
		goto clean_all 
	end

	commit tran configsrvrs

	/* Now Log the State Change Complete msg */
	dbcc printolog("HA_LOG:State Change:Completed")
	exec sp_remotesql "SYB_HACMP", 
			" dbcc printolog('HA_LOG:State Change:Completed')"
	dbcc ha_admin(" ", "clusterlock", "release")
	return(0)
end

else if (@cmd = "resume")
begin
	select @cmpstate = @@cmpstate

	/* 
	** If a resume command is issued from a suspended state in
	** a symmetric failback case make sure that, the current node
	** is really marked for it
	*/
	if @cmpstate = 13
	begin
		if not exists ( select 1 from master.dbo.sysattributes where
					object_info2 & 8 in (8) and
					class = 10 and
					attribute = 7 )
		begin
			raiserror 18764
			select @retstat = 1
			goto clean_all
		end
	end

	/* 
	** If the resume command is issued after a prepare failback the
	** remote node should be up and should be marked for having run
	** prepare failback command.
	*/
	if @cmpstate = 14
	begin
		if not exists ( select 1 from master.dbo.rmt_ha_sysattributes 
						where
					object_info2 & 8 in (8) and
					class = 10 and
					attribute = 7 )
		begin
			raiserror 18764
			select @retstat = 1
			goto clean_all
		end
	end
					
	/*
	** Before resuming the configuration, check if the
	** state transition is allowed
	*/
	dbcc ha_admin("SYB_HACMP", state, resume)
	if (@@error != 0)
	begin
		raiserror 18727
		raiserror 18722
		select @retstat = 1	
		goto clean_all 
	end

	/* 
	** OK we have now calculated the next states of the local and
	** remote servers, get it.
	*/
	select @Lnextstate = @@localstate
	select @Rnextstate = @@remotestate

	/* 
	** We expect a valid values for next states in both local
	** and in remote servers
	*/
	if (@Lnextstate = -1 or @Rnextstate = -1)
	begin
		raiserror 18727
		raiserror 18722
		select @retstat = 1	
		goto clean_all 
	end

	/*
	** Based on the state machine set the server state of the
	** local and remote servers. Do this under a distributed tran
	*/
	begin tran  configsrvrs
	dbcc printolog("HA_LOG:State Change:Started")
	exec sp_remotesql "SYB_HACMP", 
			" dbcc printolog('HA_LOG:State Change:Started')"

	/* Unmark the node for running a resume commad */
	select @logoption = 8

	exec @retstat = 
	   sp_loglocalstate @localserver, resume, @Lnextstate, 
				@srvlogin, @logoption
	if (@retstat != 0)
	begin
		rollback configsrvrs
		raiserror 18728
		goto clean_all 
	end

	exec @retstat = 
	   sp_logremotestate "SYB_HACMP", resume, @Rnextstate, 
				@srvlogin, @logoption
	if (@retstat != 0)
	begin
		rollback configsrvrs
		raiserror 18728
		goto clean_all 
	end

	/*
	** OK between the time the servers were suspended it is possible
	** that the user info could have changed. So, we need to make
	** sure that the they are consistent
	*/
	exec @retstat = sp_hasyncuserinfo "SYB_HACMP", 1, 0, 0
	if (@retstat != 0)
	begin
		/* rollback configsrvrs */
		rollback configsrvrs
		raiserror 18730
		goto clean_all 
	end

	/* Report Step */
	/* 18865,  "Step: User information synchronization succeeded." */
	exec sp_getmessage 18865, @msg output
	print @msg

	/*
	** SYSSESSIONS
	** Synchronization of logins should only happen
	** if we float the server from failing back to
	** normal, but not from suspended to normal mode.
	*/
	if @cmpstate in (14, 9)
	begin
		exec @retstat = sp_hasyncssn @remoteserver, 1
		if ((@retstat != 0) or (@@error != 0))
		begin
			/* rollback configsrvrs */
			/* RESOLVE: Get my own message?? */
			rollback configsrvrs
			raiserror 18730
			select @retstat = 1
			goto clean_all 
		end

		/* Report Step */
		/*
		** 18869, "Step: syssession information synchronization 
		** succeeded."
		*/
		exec sp_getmessage 18869, @msg output
		print @msg
	end

	/* Commit the transaction */
	commit tran configsrvrs

	/* Now Log the State Change Complete msg */
	dbcc printolog("HA_LOG:State Change:Completed")
	exec sp_remotesql "SYB_HACMP", 
			" dbcc printolog('HA_LOG:State Change:Completed')"

	/*
	** If the server state is symmetric failback or server
	** state is primary failback; its corresponding secondary
	** would have dropped the proxies for the primarie's database
	** re-create the proxies
	*/
	if (@cmpstate = 9 or @cmpstate = 14)
        begin
		/* Delete the local proxies */
                exec @retstat = sp_haproxydb NULL, "drop" 
                if ((@retstat != 0) or (@@error != 0))
                begin
                        raiserror 18791
			select @retstat = 1
			goto clean_all 
                end
		
		/*
		** Create the HA proxy databases if only it is enabled 
		*/
		if @@crthaproxy = 1
		begin
			/* Create local proxies */
                	exec @retstat = sp_haproxydb "SYB_HACMP", "create" 
						
                	if ((@retstat != 0) or (@@error != 0))
                	begin
                        	raiserror 18731
				select @retstat = 1	
				goto clean_all 
                	end

			/* Create remote proxies */
			select @msg = "sp_haproxydb 'SYB_HACMP', 'create'" 
			exec @retstat = sp_remotesql "SYB_HACMP", @msg
                	if ((@retstat != 0) or (@@error != 0) or (@@transtate = 3))
                	begin
                        	raiserror 18731
				select @retstat = 1
				goto clean_all 
                	end
		end
        end
	
	/*
	** Now we are ready for clients to failback.  Send them over.
	*/
	if @cmpstate in (14, 9)
	begin
		dbcc ha_admin("SYB_HACMP", session, "drop")
		if @@error != 0
		begin
			select @retstat = 1	
			goto clean_all 
		end
	end

	dbcc ha_admin(" ", "clusterlock", "release")

	return(0)
end
else if (@cmd = "prepare_failback")
begin
	select @retstat = 0, @oldstate = @@cmpstate


	/* Ok now do the state change */
	begin tran configsrvrs
	dbcc printolog("HA_LOG:State Change:Started")

	dbcc ha_admin("SYB_HACMP", state, failback)
	if (@@error != 0)
	begin
		raiserror 18730
		rollback configsrvrs
		select @retstat = 1	
		goto clean_all 
	end

	/* 
	** Mark the node that prepare failback was run from here 
	** We need this only when we move from Symmetric failedover
	** to symmetric failback 
	*/
	if @@cmpstate = 12	
	begin
		update master.dbo.sysattributes
			set object_info2 = object_info2 | 8 where 
				class = 10 and
				attribute = 7
	end

	commit tran configsrvrs

	select @cmpstate = @@localstate
	select @msg = "HA_LOG:State Change:Server changing state from  " +
                convert(char(2), @oldstate) + " to " +
                convert(char(2), @cmpstate)

	/* Print the state transition Msg */
	dbcc printolog(@msg)

	/* Now Log the State Change Complete msg */
	dbcc printolog("HA_LOG:State Change:Completed")

	/*
	** The state change above would not have released the update
	** locks on the sysattributes table as the attribute manager
	** holds a statement lock on it and QP does not know about
	** this when executing the above statement. So we do a dummy
	** statement to release all leftbehind statement locks so
	** that dbshutdown() does not land into anysort of undetected
	** deadlock, See bug 199957-1
	*/
	select @retstat = dbid from master.dbo.sysdatabases where
					name = "master"

	/*
	** OK now shutdown the databases pertaining to the primary
	** server. We need to unmount it and move it to its original
	** owner
	*/
	dbcc failback_dbshutdown
	if (@@error != 0)
	begin
		raiserror 18732
		select @retstat = 1	
		goto clean_all 
	end

	/* OK now shutdown the companion master database */
	dbcc dbshutdown(master_companion, 0)
	if (@@error != 0)
	begin
		raiserror 18733
		select @retstat = 1	
		goto clean_all 
	end

	/*
	** 18870, "Step: Primary databases are shutdown in secondary."
	*/
	exec sp_getmessage 18870, @msg output
	print @msg

	/* Now drop the mounted databases */
	dbcc failback_dropdbs
	if (@@error != 0)
	begin
		raiserror 18734
		select @retstat = 1	
		goto clean_all 
	end
	/*
	** "Step: Primary databases dropped from current secondary."
	*/
	exec sp_getmessage 18871, @msg output
	print @msg

	/* now is a good time to release the dbts back to Resource->rdbtfree */
	dbcc ha_admin(" ", "reserve_resource")
	if (@@error = 1)
        begin
                raiserror 18839
        end

	
	/* Now drop the mounted database's devices */
	dbcc failback_dropdevs
	if (@@error != 0)
	begin
		raiserror 18735
		select @retstat = 1	
		goto clean_all 
	end
	/* 18872, "Step: Primary devices released from current secondary" */
	exec sp_getmessage 18872, @msg output
	print @msg

	/* Now inform the cluster to release the ownership of the */
	select @retstat = ha_failback(@remoteserver)
	if (@retstat !=0 )
	begin
		raiserror 18837, @remoteserver
		goto clean_all 
	end
	/* 
	** 18873, "Step: Prepare failback for primary server completed 
	** successfully"
	*/
	exec sp_getmessage 18873, @msg output
	print @msg
	dbcc ha_admin(" ", "clusterlock", "release")

	return(@retstat)
end
begin
	raiserror 18789
end
clean_all:

	/*
	** Release Cluster locks, if held
	*/
	dbcc ha_admin(" ", "clusterlock", "release")

	/*
	** For any 'configuration' ONLY failures, reset SYB_HACMP to point to
	** local. Reset to local should be done only after remote is reset. 
	*/	
	if (@cmpstate = 0)
	begin
		if @cmd = "configure" or @cmd = "do_advisory" 
		begin
			/* If the Local server is not named, simply return */
			if not exists (select 1 
					from master.dbo.sysservers
					where srvid = 0 )	
				return(1)

			/* If the SYB_HACMP does not exists, simply return */
			if not exists (select 1 
					from master.dbo.sysservers
					where srvname = "SYB_HACMP" )	
				return(1)

			/* Check if the local SYB_HACMP points to remote */
			select @srvnetname = srvnetname 
					from master.dbo.sysservers
                                	where srvname = @localserver

			/* If (locals) SYB_HACMP is not pointing to itself */
			if not exists (select 1 
					from master.dbo.sysservers 
					where 	srvname = "SYB_HACMP" and 
						srvnetname = @srvnetname)
			begin
				/* 
				** If the Remote server is not named, 
				** simply return 
				*/
				if not exists (select 1 
					       from master.dbo.rmt_ha_sysservers
					       where srvid = 0 )	
					return(1)

				/* 
				** If the SYB_HACMP does not exists, simply 
				** return 
				*/
				if not exists (select 1 
					       from master.dbo.rmt_ha_sysservers
					       where srvname = "SYB_HACMP" )	
					return(1)

                		select @srvnetname = srvnetname 
						from master.dbo.sysservers 
						where srvname = @remoteserver

				/* 
				** Make sure that current SYB_HACMP is 
				** pointing to remoteserver, that has been 
				** passed in
				*/
				if not exists (select 1 
						from master.dbo.sysservers 
						where srvname = "SYB_HACMP" 
						and srvnetname = @srvnetname)
				begin
					return(1)
				end

				/* 
				** If companions SYB_HACMP is not 
				** pointing to itself 
				*/
				if not exists (select 1 
					       from master.dbo.rmt_ha_sysservers
					       where srvname = "SYB_HACMP" 
					       and srvnetname = @srvnetname)
				begin
					/* 
					** It is possible that the server 
					** might truely pointing to some 
					** one else, not our assumed 
					** local server, so in that case 
					** do not reset it
					*/
					select @srvnetname = srvnetname 
						from master.dbo.sysservers 
						where srvname = @localserver

					if exists (select 1 
					   from master.dbo.rmt_ha_sysservers 
					   where srvname = "SYB_HACMP" 
					   and srvnetname = @srvnetname)
					begin
						select 
						    @srvnetname = srvnetname 
						from 
						    master.dbo.sysservers 
						where 
						    srvname = @remoteserver

                				exec @sqlstat = sp_remotesql 
						     "SYB_HACMP",
                                		     "sp_addserver SYB_HACMP, null, ", @srvnetname
						if ((@sqlstat != 0) or 
							(@@error != 0) or 
						 	    (@@transtate = 3))
							return(1)
					end
				end

				/* Does local SYB_HACMP points to remote? */
				select @srvnetname = srvnetname 
					from master.dbo.sysservers
                                	where srvname = @localserver
			
				/* Now reset the Local server */
				exec @sqlstat = sp_addserver 
					"SYB_HACMP", null, @srvnetname
				if @@error != 0 or @sqlstat !=0
					return(1)
			end
		end
	end

	return(@retstat)
go
go
dump transaction sybsystemprocs with truncate_only
go
dump transaction master with truncate_only
go
sp_configure "allow updates", 0
go
reconfigure with override
go
if exists (select 1
	from tempdb.dbo.sysobjects
		 where name = 'ha_temp_install' and type = 'U')
	drop table tempdb.dbo.ha_temp_install
go
use master
go
if exists (select 1
	from tempdb.dbo.sysobjects
		where name = 'ha__syb_hacmp')
begin
	declare @sqlbuf varchar(255)
	select @sqlbuf = "declare @servernetname varchar(255)
	select @servernetname=srvnetname from tempdb.dbo.ha__syb_hacmp
	exec sp_addserver SYB_HACMP, null, @servernetname"
	exec (@sqlbuf)
	exec ("drop table tempdb.dbo.ha__syb_hacmp")
	dbcc ha_admin("", 'state_machine', 'restart')
end
go
print 'Installhasvss installation is complete.'
go

declare @retval int
exec @retval = sp_version 'installhasvss', NULL, '15.5/EBF 17340 SMP/P/x86_64/Enterprise Linux/ase155/2391/64-bit/OPT/Mon Nov  9 14:15:35 2009', 'end'
if (@retval != 0) select syb_quit()
go

