Quantcast
Channel: SCN : All Content - SAP Adaptive Server Enterprise (SAP ASE) for Custom Applications
Viewing all articles
Browse latest Browse all 757

sp_extrapwdchecks causing corruption in syslogins

$
0
0

sp_extrapwdchecks is causing corruption is syslogins but cant figure out why , below is the corruption message and store procedure.

The error is not consistent , we just drop the procedure and then everything seems to be fine .

Code looks ok not sure how it can cause corruption or under what scenhowever if some one can suggest better way to handle it as we need the historical password check feature from the proc

 

 

logs

==========================================

06:00000:00724:2015/10/28 13:07:26.31 kernel  [Handler pc: 0x00000001006b97b0 s_handle+0x0 installed by the following function:-]

06:00000:00724:2015/10/28 13:07:26.31 kernel  pc: 0x00000001004dcfd4 sequencer+0x234()

06:00000:00724:2015/10/28 13:07:26.32 kernel  pc: 0x00000001005662a8 tdsrecv_language+0xb8()

06:00000:00724:2015/10/28 13:07:26.32 kernel  [Handler pc: 0x00000001006ae9bc ut_handle+0x0 installed by the following function:-]

06:00000:00724:2015/10/28 13:07:26.32 kernel  pc: 0x00000001004df48c conn_hdlr__fdpr_6+0x3c()

06:00000:00724:2015/10/28 13:07:26.32 kernel  end of stack trace, spid 724, kpid 6422915, suid 20862

06:00000:00724:2015/10/28 13:07:26.32 server  Error: 644, Severity: 21, State: 5

06:00000:00724:2015/10/28 13:07:26.32 server  Index row entry for data row id (409, 17) is missing from index page 1465 of index id 2 of table 'syslogins' in database 'master'. Xactid is (113623,19). Drop and re-create the index.

*** Completed showing top 100 lines from output ***

 

 

Proc sp_extrapwdchecks

==========================

 

use master

go

 

create proc sp_extrapwdchecks

(

@caller_password varchar(30), -- the current password of caller

@new_password    varchar(30), -- the new password of the target acct

@loginame        varchar(30)  -- user to change password on

)

as

 

 

begin

declare @errno         int,

        @pwdlen        int,

        @min_length    int,

        @name          varchar(30),

        @c             int,

        @lastchar      int,

        @run           int,

        @msg           varchar(1024),

        @defdb         varchar(30),             /* default db for the new user */

        @deflanguage   varchar(30),             /* default language for the new user */

        @fullname      varchar(30),             /* account owner's full name */

        @passwdexp     int,                     /* value of password expiration */

        @minpwdlen     int,                     /* value of minimum password length */

        @maxfailedlogins int                    /* value of maximum failed logins */

 

 

select @errno = 0

 

 

if @loginame is NULL

        select  @name = suser_name()

else

        select  @name = @loginame

 

 

declare @changing_my_own char(1)

 

 

if @loginame is NULL or @loginame = suser_name()

        select  @changing_my_own = "Y"

else

        select  @changing_my_own = "N"

 

 

declare @new_id_flag   char(1)

select @new_id_flag = "N"

 

 

if not exists (select 1 from security.dbo.logins

               where name = @name)

   and @changing_my_own = "N"

begin

        insert  security..logins

        select  suid,           /* server user id */

                name,           /* account name */

                getdate(),      /* crdate */

                suser_name(),   /* creator */

                NULL,           /* last_login */

                NULL,           /* lock_date */

                NULL,           /* unlock_date */

                "N",            /* pw_changed_by_user */

                0,              /* failed_login_count */

                "N",            /* lock_account flag */

                0               /* lock reason */

        from    master.dbo.syslogins

        where   name = @name

 

 

        select @new_id_flag = "Y"  /* Bugfix 9680 */

 

 

        select @defdb           = dbname,

               @deflanguage     = language,

               @fullname        = fullname

        from master.dbo.syslogins

        where name = @name

 

 

        select @passwdexp = int_value

        from master.dbo.sysattributes

        where class = 14

        and   attribute = 0

        and   object_type = "PS"

        and   object_cinfo = "login"

        and   object = suser_id(@name)

 

 

        select @minpwdlen = int_value

        from master.dbo.sysattributes

        where class = 14

        and   attribute = 1

        and   object_type = "PS"

        and   object_cinfo = "login"

        and   object = suser_id(@name)

 

 

        select @maxfailedlogins = int_value

        from master.dbo.sysattributes

        where class = 14

        and   attribute = 2

        and   object_type = "PS"

        and   object_cinfo = "login"

        and   object = suser_id(@name)

 

 

        select  @msg =  "SMS Add Login: "

                        + rtrim(@loginame)

                        + ", defaultdb: "

                        + rtrim(@defdb)

        if @deflanguage is not null

                select @msg =   @msg

                                + ", defaultlang: "

                                + rtrim(@deflanguage)

        if @fullname is not null

                select @msg =   @msg

                                + ", full name: "

                                + rtrim(@fullname)

        if @passwdexp is not null

                select @msg =   @msg

                                + ", pwd exp: "

                                + rtrim(convert(varchar,@passwdexp))

        if @minpwdlen is not null

                select @msg =   @msg

                                + ", pwd len: "

                                + rtrim(convert(varchar,@minpwdlen))

        if @maxfailedlogins is not null

                select @msg =   @msg

                                + ", max failed logins: "

                                + rtrim(convert(varchar,@maxfailedlogins))

 

 

        execute sp_addauditrecord @text = @msg

end

 

 

 

 

if @changing_my_own = "Y" and suser_name() != "sa"

    and exists (select 1 from security.dbo.logins

                where name = @name

                and pw_changed_by_user = 'Y')

begin

        if exists

        (select 1

        from    master.dbo.syslogins

        where   datediff(hour,pwdate,getdate()) < 24

        and             name = @name)

        begin

                select  @errno = 30001,

                        @msg  = "You have already changed your password in the last 24 hours."

                goto FAIL

        end

end

 

 

/* must not have leading or trailing spaces */

 

 

if @new_password != ltrim(@new_password) or

        ascii(substring(@new_password,datalength(@new_password),1)) = 32

begin

        select  @errno = 30002,

                @msg  = "Password must not have leading or trailing spaces."

        goto FAIL

end

 

 

/* must not be same as name or reverse of name */

 

 

select  @pwdlen = datalength(@new_password)

 

 

if @loginame is NULL

        select  @name = suser_name()

else

        select  @name = @loginame

 

 

if upper(@new_password) = upper(substring(@name,1,@pwdlen))

        or upper(@new_password) = upper(substring(reverse(@name),1,@pwdlen))

begin

        select  @errno = 30003,

                @msg  = "Password cannot be same as login name."

        goto FAIL

end

 

 

/* password must not be in history for this user */

 

 

if exists

(select 1

from    security.dbo.password_history

where   name = @name

and     password = internal_encrypt(@new_password))

begin

        select  @errno = 30005,

                @msg  = "Password exists in history file"

        goto FAIL

end

 

 

/* password must not be in exclusions list */

 

 

if exists

(select 1

from    security.dbo.password_exclusions

where   password = lower(@new_password))

begin

        select  @errno = 30006,

                @msg  = "Password disallowed."

        goto FAIL

end

 

 

/* must not have any repeating char sequences > 2 */

 

 

select  @c      = 2,

        @lastchar = ascii(substring(@new_password,1,1)),

        @run    = 1

 

 

while (@c <= datalength(@new_password))

begin

        if ascii(substring(@new_password,@c,1)) = @lastchar

        begin

                select @run = @run + 1

                if @run > 2

                begin

                        select  @errno = 30007,

                                @msg  = "Password contains prohibited repeating character sequence."

                        goto FAIL

                end

        end

        else

                select @run = 1

 

 

        select  @lastchar = ascii(substring(@new_password,@c,1)),

                @c = @c + 1

end

 

 

/* must not have any ascending sequences > 3 chars */

 

 

select  @c      = 2,

        @lastchar = ascii(substring(@new_password,1,1)),

        @run    = 1

 

 

while (@c <= datalength(@new_password))

begin

        if ascii(substring(@new_password,@c,1)) = @lastchar+1

        begin

                select @run = @run + 1

                if @run > 3

                begin

                        select  @errno = 30007,

                                @msg  = "Password contains prohibited ascending character sequence."

                        goto FAIL

                end

        end

        else

                select @run = 1

 

 

        select  @lastchar = ascii(substring(@new_password,@c,1)),

                @c = @c + 1

end

 

 

/* must not have any descending sequences > 3 chars */

 

 

select  @c      = 2,

        @lastchar = ascii(substring(@new_password,1,1)),

        @run    = 1

 

 

while (@c <= datalength(@new_password))

begin

        if ascii(substring(@new_password,@c,1)) = @lastchar-1

        begin

                select @run = @run + 1

                if @run > 3

                begin

                        select  @errno = 30008,

                                @msg  = "Password contains prohibited descending character sequence."

                        goto FAIL

                end

        end

        else

                select @run = 1

 

 

        select  @lastchar = ascii(substring(@new_password,@c,1)),

                @c = @c + 1

end

 

 

/*

** now update password_history list in security IF we have the old

** password.  We don't have it if the password is being reset for the user by

** sa or sso, in which case there's a hole in the history.  We can't do anything

** about this until Sybase enhance the encryption to make it available to T-SQL

*/

 

 

if @changing_my_own = "Y"

begin

        /*

        ** make an entry in the password history table

        */

 

 

        insert  security.dbo.password_history

        values  (@name,         /* name - account name being modified */

                 0,             /* password_version - will be corrected by trigger */

                 isnull(internal_encrypt(@caller_password),"NULL"), /* previous password */

                 getdate(),     /* change_date */

                 suser_name())  /* changed_by - who changed the password */

 

 

        /*

        ** update security logins table to show user changed his own password

        */

 

 

        update  security.dbo.logins

        set     pw_changed_by_user = "Y"

        where   name = @name

end

else

begin

        /*

        ** password is being changed for user by sa or other, so just make entry in

        ** in history if password is unknown.

        */

 

 

        insert  security.dbo.password_history

        select  @name,          /* name - account name being modified */

                0,              /* password_version - will be corrected by trigger */

                isnull(password, internal_encrypt("[UNKNOWN]")),        /* previous password */

                getdate(),      /* change_date */

                suser_name()    /* changed_by - who changed the password */

        from master.dbo.syslogins

        where name = @name

 

 

        /*

        ** update security logins table to show user had password changed for him by sso/sa

        ** and reset login failure indicators

        */

 

 

        update  security.dbo.logins

        set     pw_changed_by_user = "N",

                failed_login_count = 0

        where   name = @name

 

 

        /*

        ** if the account is locked, might as well unlock it

        */

 

 

        if exists

        (select 1

        from    master.dbo.syslogins

        where   name = @name

        and     status & 2 = 2)

        begin

                execute sp_locklogin @name, 'unlock'

        end

end

 

 

select @errno = @@ERROR

if @errno > 0

        goto FAIL

 

 

/*

** check if we need to expire the password straight away

**

** we need to expire password if this is called from sp_addlogin, or an sso

** is changing somebody's password for them.  In either case @loginame is NOT NULL

** and is not equal to the current user.  However, this feature does not happen

** to "sa" activity

*/

 

 

-- this update does not seem to work in sp_extrapwdchecks, logic to use pw_changed_by_user

-- from security.dbo.logins used in above 24-hour check.

--if @changing_my_own = "N"

--      update  master.dbo.syslogins

--      set     pwdate = "Jan 1 1990"   /* should cover even the most lax regime */

--      where   name = @loginame

 

 

if @changing_my_own = "N"               /* only audit sso changing other people's pwds */

begin

        select  @msg = "SMS Password Change: " + rtrim(@loginame)

        execute sp_addauditrecord       @text = @msg

end

 

 

return (0)

 

 

/*

** The raiserror must be at end of the procedure, else it does not seem to return a non-zero value to the

** set_password function in sp_password.

** Do NOT add a "return (@errno)" after raiserror.

** Conjecture: In 12.5.4, set_password calls sp_extrapwdchecks and then looks for @@error from raiserror.

** A return statement after raiserror, resets @@error to 0, so set_password thinks it's okay (???).

*/

 

 

FAIL:

 

 

        if @errno != 0 and @errno != 30021 /* 30021 = warning from password_history trigger */

        begin

             /** Begin Modification 9680 - rollback the newly inserted ID from security.dbo.logins**/

             if exists (select 1 from security.dbo.logins

                        where name = @name )

             and @changing_my_own = "N"

             and @new_id_flag = "Y"

             begin

                   delete security.dbo.logins

                   where name = @name

             end

             /** End Modification 9680 **/

 

 

             raiserror @errno @msg   /* do NOT have a return after this raiserror for 12.5.4 */

        end

        else

        begin

                return (0)

        end

end

 

 

go

 

 

grant execute on sp_extrapwdchecks to public

go


Viewing all articles
Browse latest Browse all 757

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>