March 2, 2005 at 11:22 am
SQL Server 2000, SP3
Windows 2000, SP4
I'm working on a project where we upgraded SQL Server from one box to the next. We didn't want to retore master to the new box because we were suspect of problems in master.
We were able to script out all the logins and reattach databases. We also scripted out all the linked servers and added those as well.
The problem comes when attempting to run the scripts to restore the linked server logins. Everything works great except for the passwords.
The sp_addlinkedsrvlogin doesn't allow for an encrypted password. I can probably dig the passwords up and enter them in manually but I wanted to script the whole thing out.
I also tried exporting sysxlogins data to a text file using the following query in a DTS package from the old server:
select l.srvid,
l.sid,
l.xstatus,
l.xdate1,
l.xdate2,
l.name,
l.password,
l.dbid,
l.language
from sysxlogins l
inner join sysservers s on l.srvid = s.srvid
where l.srvid is not null
and l.sid is not null
and s.srvname != @@SERVERNAME
Then I reimported them into the new server using the following code.
create table #tsysxlogins (
[srvid] [smallint] NULL ,
[sid] [varbinary] (85) NULL ,
[xstatus] [smallint] NOT NULL ,
[xdate1] [datetime] NOT NULL ,
[xdate2] [datetime] NOT NULL ,
[name] [sysname] NULL ,
[password] [varbinary] (256) NULL ,
[dbid] [smallint] NOT NULL ,
[language] [sysname] NULL
 
--Look at options for BULK INSERT
BULK INSERT #tsysxlogins
FROM '\\devts061\e$\nicduc\RemoteLogins.txt'
WITH
(
FIELDTERMINATOR = '|',
ROWTERMINATOR = '\n'
)
--(I made sure the srvid matched in both server first)
EXEC sp_configure 'allow updates', '1'
go
RECONFIGURE WITH OVERRIDE
go
insert into sysxlogins
select * from #tsysxlogins
go
EXEC sp_configure 'allow updates', '0'
go
RECONFIGURE WITH OVERRIDE
The remote logins get added to the correct linked servers but the access fails. I know it a password issue because if I change the password manually it works fine.
Any help would be much appreciated.
> Nick Duckstein
March 2, 2005 at 12:22 pm
This is untested, but since you have already hacked the system tables, try this:
In sp_addlogins, there is a section of code:
if @encryptopt = 'skip_encryption_old'
begin
select @xstatus = @xstatus | 0x800, -- old-style encryption
@passwd = convert(sysname, convert(varbinary(30), convert(varchar(30), @passwd)))
end
The meaning of 'skip_encryption_old' is described in Books OnLine as:
The supplied password was encrypted by a previous version of SQL Server. SQL Server should store the value without re-encrypting it. This option is provided for upgrade purposes only.
So try to set xstatus as xstatus | 0x800
Since there is a UNIQUE INDEX on sysxlogins for columns srvid, name, and sid, try:
Update sysxlogins
set xstatus = xstatus | 0x800
where exists
(select 1
from #tsysxlogins
where #tsysxlogins.srvid = sysxlogins.srvid
and #tsysxlogins.name = sysxlogins.name
and #tsysxlogins.sid = sysxlogins.sid
 
SQL = Scarcely Qualifies as a Language
March 2, 2005 at 3:45 pm
I tried that but the login still fails. Instead of exporting to a text file I'm going to export to a SQL Server table and import to that to see if it makes a difference.
I'll let you know how it turns out.
> Nick Duckstein
March 4, 2005 at 11:47 am
Note: the system turned one of my Close parens into a weird happy face.
I have used this script to pull passwords off one server ( the old production server) and put them into the new production server. You of course have to configure your server to allow direct updates to the system tables. The convert(varbinary(255), XX) seems to be the magic command required to get the transffer to work. Just run this on the new server with the old server info name and password Put into the remort rowset querry. I would sugest running this as a select first to see what Logins will be updated.
update sx
set password = convert(varbinary(255), rem_sysxlogins.password)
/*select
* */
from sysxlogins sx
inner join syslogins s on
s.sid = sx.sid
inner join
OPENROWSET
(
'SQLOLEDB',
'severname';'sa';'XXXXXXXXXXX',
'select * from master.dbo.sysxlogins'
  as rem_sysxlogins on
rem_sysxlogins.name = s.name
inner join
OPENROWSET
(
'SQLOLEDB',
'servername';'sa';'xxxxxxxxx',
'select * from master.dbo.syslogins'
) as rem_syslogins on
rem_syslogins.sid = rem_sysxlogins.sid
where
sx.xstatus = 2
March 4, 2005 at 2:13 pm
This is actually the query I want. The sid don't match and xstatus !=2. If I run your query everything BUT logins defined for linked servers. The query below returns the one record I want but with a NULL password.
select ss.srvname,
sx.name,
convert(varbinary(255), rem_sysxlogins.password),
rem_sysxlogins.password
from sysxlogins sx
inner join syslogins s on s.sid = sx.sid
inner join sysservers ss on sx.srvid = ss.srvid
inner join
OPENROWSET
(
'SQLOLEDB',
'devts061\tac';'sa';'xxx',
'select * from master.dbo.sysxlogins') as rem_sysxlogins on rem_sysxlogins.name = s.name
-- inner join
-- OPENROWSET
-- (
-- 'SQLOLEDB',
-- 'devts061\tac';'sa';'xxx',
-- 'select * from master.dbo.syslogins') as rem_syslogins on rem_syslogins.sid = rem_sysxlogins.sid
where 0=0
-- and sx.xstatus = 2
and sx.xstatus = 64
and sx.srvid is not null
and sx.sid is not null
and ss.srvname = 'DEVESQ01'
order by ss.srvname
> Nick Duckstein
March 4, 2005 at 2:28 pm
The query I wrote assumes:
1. The logins are already on both servers
2. The logins have the same "Name" on both servers
3. Only the password is transffered
4. It is transffered from the remote comuter that has the correct password, unto the local server where the query is actual run.
I am not sure from your response, but did you get this to work?
March 4, 2005 at 2:47 pm
No I didn't get it to work. All of your assumptions are true except for the logins existing on both servers. They do and they don't.
Let me try explaining the problem a different way. On the ServerA, at some point in the past the following was executed:
EXEC sp_addlinkedserver
@server = 'DEVESQ01',
@provider = 'SQLOLEDB',
@srvproduct = '',
@datasrc = 'DEVESQ01'
EXEC sp_addlinkedsrvlogin
@rmtsrvname = 'DEVESQ01',
@useself = 'false',
@locallogin = 'SAFECO_MASTER\NICDUC',
@rmtuser = 'Test',
@rmtpassword = 'TestPwd'
What I want to do is script out this linked server and login so that I can execute it on ServerB. Everything works great except for scripting out the value for @rmtpassword = 'TestPwd'. The remote login gets added to the linked server properly, but access is denied. If I then type in the password manually, it works fine.
In a nutshell, "Test" exists on
Is that more clear?
Nick
> Nick Duckstein
March 4, 2005 at 3:07 pm
Am not quite sure about this. The script I have is just for getting the encpyted password off one server and updating the password on another. We had other scripts as part of the backup and restore process that would transffer everything else, so I wrote this script to move only the actual password. The actual password is stored as binary. If you select it out it looks something like like '0X1A6B735B...'. to get it back into the table once you have matched up the right place to put it, you should be able to update the password like this:
set password = convert(varbinary(255), '0X1A6B735B....')
from sysxlogins sx
where sx.sid = xxx
try this with one password from your existing database by just selecting it out and copying the value. Then put it into the correct sid for the login you are trying to update. You should then be able to login to that server with the copied password. Once you get this to work for one login you should be able to write the script based on how you need to match the data up.
March 4, 2005 at 3:16 pm
I looked at your script and I think I now see the problem:
change this table to
create table #tsysxlogins (
[srvid] [smallint] NULL ,
[sid] [varbinary] (85) NULL ,
[xstatus] [smallint] NOT NULL ,
[xdate1] [datetime] NOT NULL ,
[xdate2] [datetime] NOT NULL ,
[name] [sysname] NULL ,
[password] [varchar] (256) NULL ,
[dbid] [smallint] NOT NULL ,
[language] [sysname] NULL)
insert into sysxlogins(
srvid ,
sid ,
xstatus ,
xdate1 ,
xdate2 ,
name ,
password ,
dbid ,
language)
select
srvid ,
sid ,
xstatus ,
xdate1 ,
xdate2 ,
name ,
convert(varbinary(255), password) ,
dbid ,
language
from #tsysxlogins
the issue is that when the sever scripts out the password it converts it to a character string. You have to add the code to convert it back.
March 4, 2005 at 4:48 pm
I gave that a whirl and it didn't work either. This time instead of exporting to a text file and importing that, I exported to a table and imported from there.
I tried both ways too, i.e. converting to varbinary and straight across.
You are a trooper for helping me with this.
Any other ideas. Can you get it to work on your end? It is a simple test. Just execute the two commands below on one server.
EXEC sp_addlinkedserver
@server = 'DEVESQ01',
@provider = 'SQLOLEDB',
@srvproduct = '',
@datasrc = 'DEVESQ01'
EXEC sp_addlinkedsrvlogin
@rmtsrvname = 'DEVESQ01',
@useself = 'false',
@locallogin = 'SAFECO_MASTER\NICDUC',
@rmtuser = 'Test',
@rmtpassword = 'TestPwd'
On a second server the sp_addlinkedserver proc exactly the same. Execute the sp_addlinkedsrvlogin as follows:
EXEC sp_addlinkedsrvlogin
@rmtsrvname = 'DEVESQ01',
@useself = 'false',
@locallogin = 'SAFECO_MASTER\NICDUC',
@rmtuser = 'Test',
@rmtpassword = <script from first server>
> Nick Duckstein
Viewing 10 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic. Login to reply