DatabaseProcApplicationCreatedLinks
sybsystemprocssp_passwordpolicy  31 Aug 14Defects Dependencies

1     
2     /*
3     ** Messages for "sp_passwordpolicy" 
4     ** 17231, "No login with the specified name exists."
5     ** 17260, "Can't run %1! from within a transaction."
6     ** 17925, "You entered an invalid option name. No change was made."
7     ** 17932, "You entered an invalid value. No change was made."
8     ** 18409, "The built-in function '%1!' failed. Please see the other messages printed along with this message."
9     ** 19213, "Invalid argument or unsupported command: %1!."
10    ** 19633, "Network password encryption keypair will be regenerated at %1!."
11    ** 19844, "There is no password protected role like '%1!'."
12    */
13    
14    /* 
15    ** IMPORTANT: Please read the following instructions before
16    **   making changes to this stored procedure.
17    **
18    **      To make this stored procedure compatible with High Availability (HA),
19    **      changes to certain system tables must be propagated 
20    **      to the companion server under some conditions.
21    **      The tables include (but are not limited to):
22    **              syslogins, sysservers, sysattributes, systimeranges,
23    **              sysresourcelimits, sysalternates, sysdatabases,
24    **              syslanguages, sysremotelogins, sysloginroles,
25    **              sysalternates (master DB only), systypes (master DB only),
26    **              sysusers (master DB only), sysprotects (master DB only)
27    **      please refer to the HA documentation for detail.
28    **
29    **      Here is what you need to do: 
30    **      For each insert/update/delete statement, add three sections to
31    **      -- start HA transaction prior to the statement
32    **      -- add the statement
33    **      -- add HA synchronization code to propagate the change to the companion
34    **
35    **      For example, if you are adding 
36    **              insert master.dbo.syslogins ......
37    **      the code should look like:
38    **      1. Before that SQL statement:
39    **              
40    **      2. Now, the SQL statement:
41    **              insert master.dbo.syslogins ......
42    **      3. Add a HA synchronization section right after the SQL statement:
43    **              
44    **
45    **      You may need to do similar change for each built-in function you
46    **      want to add.
47    **
48    **      Finally, add a separate part at a place where it can not
49    **      be reached by the normal execution path:
50    **      cleanup:
51    **              
52    **              return (1)
53    */
54    
55    create procedure sp_passwordpolicy
56        @cmd varchar(30) = null,
57        @opt1 varchar(30) = null,
58        @opt2 varchar(30) = null,
59        @opt3 varchar(30) = null
60    as
61        declare @optname varchar(30), /*
62            ** To store mapped name of the 
63            ** attribute in spt_values
64            */
65            @retval int,
66            @count1 int, /* Temperory variable 1 */
67            @count2 int, /* Temperory variable 2 */
68            @result varchar(5),
69            @validation_step varchar(50),
70            @validation_test varchar(65),
71            @return_status int,
72            @nextregen datetime,
73            @log_for_rep int, /* Replication status of master db */
74            @db_rep_level_all int, /* Replication constants.	   */
75            @db_rep_level_none int,
76            @db_rep_level_l1 int,
77            @lt_rep_get_failed int,
78            @lt_rep_all int,
79            @lt_rep_l1 int,
80            @entered_date datetime, /* Stores datetime specified for
81            ** expiring stale login or role
82            ** passwords
83            */
84            @allow_pwd_dwn_status int,
85            @msg varchar(1024),
86            @allow_pwd_dwn_dt smalldatetime,
87            @allow_pwd_dwn_dt_int int,
88            @specified_datetime varchar(30),
89            @dbname varchar(255),
90            @HA_CERTIFIED tinyint, /* Is the SP HA certified ? */
91            @retstat int,
92            @list_keypair int,
93            @list_nonkeypair int,
94            @dummy varchar(30) /* This is used to pass to the
95        ** password_admin builtin. In future
96        ** any additonal argument to 
97        ** sp_passwordpolicy can be
98        ** replace with it.
99        */
100   
101       select @HA_CERTIFIED = 0
102       select @list_keypair = 0
103       select @list_nonkeypair = 0
104   
105   
106   
107       /* check to see if we are using HA specific SP for a HA enabled server */
108       exec @retstat = sp_ha_check_certified 'sp_passwordpolicy', @HA_CERTIFIED
109       if (@retstat != 0)
110           return (1)
111       /*
112       **  If we're in a transaction, disallow this since it might make recovery
113       **  impossible.
114       */
115   
116       if @@trancount > 0
117       begin
118           /*
119           ** 17260, "Can't run %1! from within a transaction."
120           */
121           raiserror 17260, "sp_passwordpolicy"
122           return (1)
123       end
124       else
125       begin
126           set chained off
127       end
128       set transaction isolation level 1
129   
130       /*
131       **  Begin command processing.
132       */
133   
134       /* 
135       ** Check for sso_role. The built-in proc_role() will audit
136       ** the event.
137       */
138       if (proc_role("sso_role") = 0)
139       begin
140           return (1)
141       end
142   
143       /* 
144       ** Set the command text to lowercase so that we always compare it using
145       ** the same case.
146       */
147       select @cmd = lower(@cmd), @opt1 = lower(@opt1)
148   
149       if (@cmd is null or @cmd = 'help')
150       begin
151           /* Display sp_passwordpolicy usage information */
152           select @retval = 2
153           goto usage
154       end
155       else
156       if (@cmd not in ('set', 'clear', 'list', 'validate password options',
157                   'expire login passwords', 'expire role passwords',
158                   'expire stale login passwords',
159                   'expire stale role passwords', 'regenerate keypair',
160                   'downgrade', 'prepare_downgrade'))
161       begin
162   
163           /*
164           ** 19213, "Invalid argument or unsupported command: %1!."
165           */
166           raiserror 19213, @cmd
167           /* Display sp_passwordpolicy usage information */
168           select @retval = 2
169           goto usage
170       end
171   
172       /* Check if opt1 entered is valid */
173       if (@opt1 is null and (@cmd = 'set' or @cmd = 'expire stale login passwords'
174                   or @cmd = 'expire stale role passwords'))
175       begin
176           /*
177           ** 17932, "You entered an invalid value. No
178           ** change was made."
179           */
180           raiserror 17932
181           select @retval = 2
182           goto usage
183       end
184   
185       /* Lists the option values */
186       if (@cmd = 'list')
187       begin
188           /*
189           ** Traditionally, the names stored in spt_values match some
190           ** internal name in ASE, where the maximum length is 28 to
191           ** account for quoted identifiers. In this case, spt_values
192           ** is used store option names that must match sysattributes
193           ** options with 255 chars names. The option 'systemwide password 
194           ** expiration' is 30 chars long, and it does not fit in spt_values,
195           ** and the name has been chaged to 'password expiration'.
196           ** The variable @opt1 stores the sysattributes option name,
197           ** while the variable @optname stores the mapped name in
198           ** spt_values.
199           */
200           if (@opt1 = 'systemwide password expiration')
201               select @optname = 'password expiration'
202           else
203               select @optname = @opt1
204   
205           if ((@opt1 is not null)
206                   and not exists (select 1 from master.dbo.spt_values
207                       where (type in ('PC', 'PT', 'LG', 'SP'))
208                           and name = @optname))
209           begin
210               /*
211               ** 17925, "You entered an invalid option name.
212               ** No change was made."
213               */
214               raiserror 17925
215               select @retval = 2
216               goto usage
217           end
218           if (@opt2 is not null
219                   or @opt3 is not null)
220           begin
221               /*
222               ** 17932, "You entered an invalid value. No
223               ** change was made."
224               */
225               raiserror 17932
226               select @retval = 2
227               goto usage
228           end
229   
230           if (@opt1 = 'allow password downgrade')
231           begin
232               /*
233               ** when 'allow password downgrade' is set to 0,
234               ** date is recorded in syattributes.object column.
235               ** This column is of data type int.
236               ** To retrieve data from it in date format,
237               ** convert function is used.
238               ** Date is converted to binary first and then to date format, 
239               ** ASE does not support direct date -> int conversion.
240               */
241               select @allow_pwd_dwn_status = int_value,
242                   @allow_pwd_dwn_dt_int = object from sysattributes
243               where class = 31
244               if (@allow_pwd_dwn_status = NULL)
245               begin
246                   /*
247                   ** 19679, New 15.0.2 master database.
248                   */
249                   exec sp_getmessage 19679, @msg output
250                   select 'value' = @allow_pwd_dwn_status,
251                       @msg as message
252               end
253               else if (@allow_pwd_dwn_status = 1)
254               begin
255                   /*
256                   ** 19678, Password downgrade is allowed.
257                   */
258                   exec sp_getmessage 19678, @msg output
259                   select 'value' = @allow_pwd_dwn_status,
260                       @msg as message
261               end
262               else if (@allow_pwd_dwn_status = 0)
263               begin
264                   select @allow_pwd_dwn_dt =
265                       convert(smalldatetime, convert(binary(4),
266                       @allow_pwd_dwn_dt_int))
267                   /*
268                   ** 19680, Last Password downgrade was allowed on
269                   */
270                   exec sp_getmessage 19680, @msg output
271                   select 'value' = @allow_pwd_dwn_status,
272                       @msg + " " +
273                       convert(char(20), @allow_pwd_dwn_dt) as message
274               end
275           end
276   
277           /*
278           ** 'keypair regeneration period' and 'keypair error retry wait'
279           ** accept duration specifiers and so are stored in 
280           ** master.dbo.sysattributes.char_value
281           ** While setting values sp_passwordpolicy allows varchar(30) only
282           */
283           if ((@opt1 in ('keypair regeneration period',
284                           'keypair error retry wait')) or
285                   (@opt1 = null))
286           begin
287               select @list_keypair = 1
288           end
289           if ((@opt1 not in ('allow password downgrade',
290                           'keypair regeneration period', 'keypair error retry wait')) or
291                   (@opt1 = null))
292           begin
293               select @list_nonkeypair = 1
294           end
295   
296           select 'Policy_option' = convert(VARCHAR(30), a.object_cinfo),
297               'Curr_value' = convert(VARCHAR(30), a.char_value), 'Min_value' = s.low,
298               'Max_value' = s.high
299           from master.dbo.spt_values s, master.dbo.sysattributes a,
300               master.dbo.sysmessages m
301           where (@list_keypair = 1
302                   and s.name = a.object_cinfo
303                   and (s.msgnum = m.error)
304                   and (m.langid = null) /* restrict to us_english only */
305                   and (s.type = 'SP')
306                   and (a.object_cinfo = @opt1 or @opt1 is null)
307                   and (a.object_cinfo in ('keypair regeneration period',
308                           'keypair error retry wait')))
309           UNION
310           select 'Policy_option' = convert(VARCHAR(30), a.object_cinfo),
311               'Curr_value' = convert(VARCHAR(30), a.int_value), 'Min_value' = s.low,
312               'Max_value' = s.high
313           from master.dbo.spt_values s, master.dbo.sysattributes a,
314               master.dbo.sysmessages m
315           where (@list_nonkeypair = 1
316                   and ((s.name = a.object_cinfo) or
317                       (a.object_cinfo = 'systemwide password expiration'
318                           and s.name = 'password expiration'))
319                   and (s.msgnum = m.error)
320                   and (m.langid = null) /* restrict to us_english only */
321                   and (s.type in ('PC', 'LG', 'SP'))
322                   and (a.object_cinfo = @opt1 or @opt1 is null)
323                   and (a.object_cinfo not in ('keypair regeneration period',
324                           'keypair error retry wait',
325                           'allow password downgrade')))
326           return 0
327       end
328   
329       if (@cmd like '%downgrade')
330       begin
331           select @retval = password_admin('set', @cmd)
332           return @retval
333       end
334   
335       if (@cmd = 'validate password options')
336       begin
337           /* 
338           ** @opt1 and @opt2 are not passed to password_admin(),
339           ** hence check for null value here itself.
340           */
341           if ((@opt1 is not null) or (@opt2 is not null))
342           begin
343               /*
344               ** 17932, "You entered an invalid value. No
345               ** change was made."
346               */
347               raiserror 17932
348               select @retval = 2
349               goto usage
350           end
351   
352           select @retval = password_admin('set', 'policy', @cmd)
353           select @count1 = 0
354           select @count2 = 1
355           select @return_status = 0
356   
357           /* 
358           ** create a temporary table to store the information of validation 
359           ** tests.
360           */
361           create table #helpdisplay
362           (
363               validation_step varchar(50),
364               result varchar(5),
365               validation_test varchar(65)
366           )
367           /*
368           ** Each validation test is represented by two bits. 
369           ** If odd bit of the corresponding two bits for the test is set to 1,
370           ** the result is NA.
371           ** If even bit is set to 1, then result is Pass
372           ** else if even bit is set to 0, then result is Fail.
373           */
374           while (@count1 <= 10)
375           begin
376               if (@retval & power(2, @count1)) != 0
377                   select @result = "NA"
378               else if (@retval & power(2, @count2)) != 0
379                   select @result = "Pass"
380               else
381               begin
382                   select @result = "Fail"
383                   select @return_status = 1
384               end
385   
386               if @count1 = 0
387               begin
388                   select @validation_step = "min alpha in password"
389                   select @validation_test = "minalpha >= (minupper + minlower)"
390               end
391               else if @count1 = 2
392               begin
393                   select @validation_step = "minimum password length - 1"
394                   select @validation_test = "minlength >= (mindigit + minspc + minalpha)"
395               end
396               else if @count1 = 4
397               begin
398                   select @validation_step = "minimum password length - 2"
399                   select @validation_test = "minlength >= (mindigit + minspc + minupper + minlower)"
400               end
401               else if @count1 = 6
402               begin
403                   select @validation_step = "maximum password length - 1"
404                   select @validation_test = "max password length >= (mindigit + minspc + minalpha)"
405               end
406               else if @count1 = 8
407               begin
408                   select @validation_step = "maximum password length - 2"
409                   select @validation_test = "max password length >= (mindigit + minspc + minupper + minlower)"
410               end
411               else if @count1 = 10
412               begin
413                   select @validation_step = "password exp warn interval"
414                   select @validation_test = "pwdexpwarn <= pwdexp"
415               end
416   
417               insert into #helpdisplay values (@validation_step, @result, @validation_test)
418               select @count1 = @count1 + 2
419               select @count2 = @count2 + 2
420           end
421           exec sp_autoformat @fulltabname = #helpdisplay,
422               @selectlist = "'Validation Step' = validation_step, 'Pass/Fail/NA' = result,
423                          'Validation Test' = validation_test"
424           drop table #helpdisplay
425   
426           return @return_status
427       end
428   
429       /* Initialize constants need for replication */
430       select @db_rep_level_all = - 1,
431           @db_rep_level_none = 0,
432           @db_rep_level_l1 = 1,
433           @lt_rep_get_failed = - 2,
434           @lt_rep_all = 2048,
435           @lt_rep_l1 = 4096
436   
437       if (@opt1 != 'allow password downgrade')
438       begin
439           /* Get the replication status of the 'master' database */
440           select @log_for_rep = getdbrepstat(1)
441   
442           if (@log_for_rep = @lt_rep_get_failed)
443           begin
444               /*
445               ** 18409, "The built-in function getdbrepstat() failed. Please
446               ** see the other messages printed along with this message."
447               */
448               raiserror 18409, "getdbrepstat"
449               return 1
450           end
451   
452           /* Convert the replication status to boolean */
453           if ((@log_for_rep & @lt_rep_all = @lt_rep_all) or
454                   (@log_for_rep & @lt_rep_l1 = @lt_rep_l1))
455   
456               select @log_for_rep = 1
457           else
458               select @log_for_rep = 0
459   
460       end
461       else
462           select @log_for_rep = 0
463   
464       /*
465       ** If we are logging this system procedure for replication, we must be in
466       ** the 'master' database to avoid creating a multi-database transaction
467       ** which could make recovery of the 'master' database impossible.
468       */
469       if (@log_for_rep = 1) and (upper(db_name()) != upper("master"))
470       begin
471           /*
472           ** 18388, "You must be in the master database in order to
473           **	   run '%1!'"
474           */
475           raiserror 18388, "sp_passwordpolicy"
476           return (1)
477       end
478   
479       /* 
480       ** If replication is active, open the transaction.
481       **
482       ** IMPORTANT: The name rs_logexec is significant and is used by
483       ** replication.
484       */
485       if (@log_for_rep = 1)
486       begin
487           begin tran rs_logexec
488       end
489   
490       if (@cmd = 'expire login passwords')
491       begin
492           /* 
493           ** @opt2 is not passed to password_admin(),
494           ** hence check for null value here itself.
495           */
496           if (@opt2 is not null)
497           begin
498               /*
499               ** 17932, "You entered an invalid value. No
500               ** change was made."
501               */
502               raiserror 17932
503               select @retval = 2
504               goto usage
505           end
506   
507           if (@opt1 is null)
508           begin
509               select @opt1 = '%'
510           end
511   
512           if not exists (select name from master.dbo.syslogins
513                   where name like @opt1
514                       and ((status & 512) != 512)) /* not LOGIN PROFILE */
515           begin
516               /*
517               ** 17231, "No login with the specified name exists."
518               **      (was "Invalid Login user.")
519               */
520               raiserror 17231
521               select @retval = 1
522           end
523           else
524           begin
525               select @retval = password_admin('set', 'policy', @cmd, @opt1)
526           end
527       end
528       else if (@cmd = 'expire role passwords')
529       begin
530           /* 
531           ** @opt2 is not passed to password_admin(),
532           ** hence check for null value here itself.
533           */
534           if (@opt2 is not null)
535           begin
536               /*
537               ** 17932, "You entered an invalid value. No
538               ** change was made."
539               */
540               raiserror 17932
541               select @retval = 2
542               goto usage
543           end
544   
545           if (@opt1 is null)
546           begin
547               select @opt1 = '%'
548           end
549   
550           if not exists (select name from master.dbo.syssrvroles
551                   where name like @opt1 and password is not null)
552           begin
553               /*
554               ** 19844, "There is no password protected role like '%1!'."
555               */
556               raiserror 19844, @opt1
557               select @retval = 1
558           end
559           else
560           begin
561               select @retval = password_admin('set', 'policy', @cmd, @opt1)
562           end
563       end
564       else if ((@cmd = 'expire stale login passwords') or
565               (@cmd = 'expire stale role passwords'))
566       begin
567           /* 
568           ** @opt2 is not passed to password_admin(),
569           ** hence check for null value here itself.
570           */
571           if (@opt2 is not null)
572           begin
573               /*
574               ** 17932, "You entered an invalid value. No
575               ** change was made."
576               */
577               raiserror 17932
578               select @retval = 2
579               goto usage
580           end
581   
582           select @entered_date = @opt1
583   
584           /* 
585           ** Convert the entered date and time into required form 
586           ** of mm dd yy hh:mm:ss:zzzAM(PM) using style number 9
587           */
588           select @opt1 = convert(char(30), @entered_date, 9)
589   
590           select @retval = password_admin('set', 'policy', @cmd, @opt1)
591       end
592   
593   
594   
595       /* Changes or inserts the option value as specified. */
596       if (@cmd in ('set', 'regenerate keypair'))
597       begin
598           if (@cmd = 'regenerate keypair')
599           begin
600               /* If no datetime is specified then generate keypair now */
601               if (@opt1 is null)
602               begin
603                   select @opt1 = getdate()
604               end
605               /*
606               ** If only time is specified and it is passed,
607               ** generate keypair next day at @opt1 time.
608               ** Note: For only time: datepart() assume January 1, 1900
609               */
610               else if ((datepart(yy, @opt1) = 1900 and
611                           datepart(mm, @opt1) = 1 and
612                           datepart(dd, @opt1) = 1 and
613                           /* Dont't mislead with datetime like January 1, 1900 01:45AM */
614                           charindex("1900", @opt1) = 0)
615                       and
616                       (datepart(hh, @opt1) < datepart(hh, getdate()) or
617                           (datepart(hh, @opt1) = datepart(hh, getdate()) and
618                               datepart(mi, @opt1) < datepart(mi, getdate()))))
619               begin
620                   select @specified_datetime = substring(convert(char(20), getdate(), 0), 1, 12) + @opt1
621                   select @opt1 = dateadd(dd, 1, @specified_datetime)
622               end
623               select @retval = password_admin('set', 'regenerate keypair',
624                       @opt1)
625           end
626           else
627           begin
628               select @retval = password_admin(@cmd, 'policy', @opt1,
629                       @opt2, @opt3, @dummy)
630           end
631   
632           if ((@retval = 0) and ((@cmd = 'regenerate keypair') or
633                       (@opt1 = 'keypair regeneration period')))
634           begin
635               /* Display the current date if none was specified, i.e. NOW. */
636               if @opt1 = NULL
637                   select @nextregen = getdate()
638               else
639                   select @nextregen = @@nextkpgendate
640               /*
641               ** 19633, "Network password encryption keypair will be 
642               ** regenerated at %1!."
643               */
644               raiserror 19633, @nextregen
645           end
646   
647   
648       end
649   
650       /* Changes the option values to hardcoded values */
651       else if (@cmd = 'clear')
652       begin
653           /* 
654           ** @opt2 is not passed to password_admin(),
655           ** hence check for null value here itself.
656           */
657           if (@opt2 is not null
658                   or @opt3 is not null)
659           begin
660               /*
661               ** 17932, "You entered an invalid value. No
662               ** change was made."
663               */
664               raiserror 17932
665               select @retval = 2
666               goto usage
667   
668           end
669           else if (@opt1 = 'allow password downgrade')
670           begin
671               /*
672               ** 19658, "Option 'allow password downgrade' cannot be 
673               ** unset using 'clear' command"
674               */
675               raiserror 19658
676               select @retval = 2
677               goto usage
678           end
679           else
680           begin
681               select @retval = password_admin(@cmd, 'policy', @opt1)
682   
683   
684           end
685       end
686   
687       if (@retval = 0)
688       begin
689           /*
690           ** If the 'master' database is marked for replication, the T-SQL builtin
691           ** logexec(), will log the execution of this system procedure.
692           */
693           if (@log_for_rep = 1)
694           begin
695               if (logexec(1) != 1)
696               begin
697                   /*
698                   ** 17756, "The execution of the stored procedure '%1!'
699                   ** 	   in database '%2!' was aborted because there
700                   **	   was an error in writing the replication log
701                   **	   record."
702                   */
703                   raiserror 17756, "sp_passwordpolicy", "master"
704                   goto cleanup
705               end
706           end
707   
708   
709           commit transaction
710           return 0
711       end
712   
713   usage:
714       if (@retval = 2)
715       begin
716           print "sp_ passwordpolicy Usage: sp_passwordpolicy 'help'"
717           print "sp_ passwordpolicy Usage: sp_passwordpolicy command [, option1 [, option2 [, option3]]]"
718           print "sp_passwordpolicy commands:"
719           print "sp_passwordpolicy 'set',"
720           print "                  {'enable last login updates' | 'disallow simple passwords' |"
721           print "                   'min digits in password' | 'min alpha in password' |"
722           print "                   'min special char in password' | 'min upper char in password' |"
723           print "                   'min lower char in password' | 'password exp warn interval' |"
724           print "                   'systemwide password expiration' | 'minimum password length' |"
725           print "                   'maximum failed logins' | 'expire login' |"
726           print "                   'allow password downgrade' | 'keypair error retry wait' |"
727           print "			  'keypair error retry count'},"
728           print "                  'value'"
729           print "sp_passwordpolicy 'set', 'keypair regeneration period',"
730           print "			 {'regeneration_period' |"
731           print "			  null, 'datetime' | "
732           print "			  'regeneration_period', 'datetime'}"
733           print "sp_passwordpolicy 'list',"
734           print "                  ['enable last login updates' | 'disallow simple passwords' |"
735           print "                   'min digits in password' | 'min alpha in password' |"
736           print "                   'min special char in password' | 'min upper char in password' |"
737           print "                   'min lower char in password' | 'password exp warn interval' |"
738           print "                   'systemwide password expiration' | 'minimum password length' |"
739           print "                   'maximum failed logins' | 'expire login' |"
740           print "                   'allow password downgrade' |"
741           print "			  'keypair error retry wait' | 'keypair error retry count' |"
742           print "			  'keypair regeneration period']"
743           print "sp_passwordpolicy 'clear',"
744           print "                  {'enable last login updates' | 'disallow simple passwords' |"
745           print "                   'min digits in password' | 'min alpha in password' |"
746           print "                   'min special char in password' | 'min upper char in password' |"
747           print "                   'min lower char in password' | 'password exp warn interval' |"
748           print "                   'systemwide password expiration' | 'minimum password length' |"
749           print "                   'maximum failed logins' | 'expire login' |"
750           print "			  'keypair error retry wait' |"
751           print "			  'keypair error retry count' | 'keypair regeneration period'}"
752           print "sp_passwordpolicy 'expire login passwords'[, '{loginame | wildcard}']"
753           print "sp_passwordpolicy 'expire role passwords'[, '{rolename | wildcard}']"
754           print "sp_passwordpolicy 'expire stale login passwords', 'datetime'"
755           print "sp_passwordpolicy 'expire stale role passwords', 'datetime'"
756           print "sp_passwordpolicy 'regenerate keypair'[, 'datetime']"
757           print "sp_passwordpolicy 'validate password options'"
758       end
759   
760   cleanup:
761   
762   
763       if (@log_for_rep = 1)
764       begin
765           rollback tran rs_logexec
766       end
767   
768       if (@cmd = 'help')
769       begin
770           return 0
771       end
772       else
773       begin
774           return 1
775       end
776   


exec sp_procxmode 'sp_passwordpolicy', 'AnyMode'
go

Grant Execute on sp_passwordpolicy to public
go
RESULT SETS
sp_passwordpolicy_rset_004
sp_passwordpolicy_rset_003
sp_passwordpolicy_rset_002
sp_passwordpolicy_rset_001

DEFECTS
 MCTR 4 Conditional Begin Tran or Commit Tran 487
 MCTR 4 Conditional Begin Tran or Commit Tran 709
 MINU 4 Unique Index with nullable columns master..sysattributes master..sysattributes
 MINU 4 Unique Index with nullable columns master..sysmessages master..sysmessages
 MINU 4 Unique Index with nullable columns sybsystemprocs..sysattributes sybsystemprocs..sysattributes
 MTYP 4 Assignment type mismatch @nextregen: datetime = int 639
 MUSP 4 Unquoted String Parameter sybsystemprocs..sp_autoformat: @fulltabname 421
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: spt_values.spt_valuesclust clustered
(number, type)
Intersection: {type}
207
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use JOIN Candidate index: sysattributes.csysattributes unique clustered
(class, attribute, object_type, object, object_info1, object_info2, object_info3, object_cinfo)
Intersection: {object_cinfo}
Uncovered: [class, attribute, object_type, object, object_info1, object_info2, object_info3]
302
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: spt_values.spt_valuesclust clustered
(number, type)
Intersection: {type}
305
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysattributes.csysattributes unique clustered
(class, attribute, object_type, object, object_info1, object_info2, object_info3, object_cinfo)
Intersection: {object_cinfo}
306
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use JOIN Candidate index: sysattributes.csysattributes unique clustered
(class, attribute, object_type, object, object_info1, object_info2, object_info3, object_cinfo)
Intersection: {object_cinfo}
Uncovered: [class, attribute, object_type, object, object_info1, object_info2, object_info3]
316
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: sysattributes.csysattributes unique clustered
(class, attribute, object_type, object, object_info1, object_info2, object_info3, object_cinfo)
Intersection: {object_cinfo}
317
 QPUI 4 Join or Sarg with Un-Rooted Partial Index Use SARG Candidate index: spt_values.spt_valuesclust clustered
(number, type)
Intersection: {type}
318
 QTYP 4 Comparison type mismatch Comparison type mismatch: smallint vs int 243
 TNOU 4 Table with no unique index master..spt_values master..spt_values
 VRUN 4 Variable is read and not initialized @dummy 629
 MGTP 3 Grant to public master..spt_values  
 MGTP 3 Grant to public master..sysattributes  
 MGTP 3 Grant to public master..syslogins  
 MGTP 3 Grant to public master..sysmessages  
 MGTP 3 Grant to public master..syssrvroles  
 MGTP 3 Grant to public sybsystemprocs..sp_passwordpolicy  
 MGTP 3 Grant to public sybsystemprocs..sysattributes  
 MNAC 3 Not using ANSI 'is null' 244
 MNAC 3 Not using ANSI 'is null' 285
 MNAC 3 Not using ANSI 'is null' 291
 MNAC 3 Not using ANSI 'is null' 304
 MNAC 3 Not using ANSI 'is null' 320
 MNAC 3 Not using ANSI 'is null' 636
 MNER 3 No Error Check should check return value of exec 249
 MNER 3 No Error Check should check return value of exec 258
 MNER 3 No Error Check should check return value of exec 270
 MNER 3 No Error Check should check @@error after insert 417
 MNER 3 No Error Check should check return value of exec 421
 MUCO 3 Useless Code Useless Brackets 109
 MUCO 3 Useless Code Useless Brackets 110
 MUCO 3 Useless Code Useless Brackets 122
 MUCO 3 Useless Code Useless Brackets 138
 MUCO 3 Useless Code Useless Brackets 140
 MUCO 3 Useless Code Useless Brackets 149
 MUCO 3 Useless Code Useless Brackets 156
 MUCO 3 Useless Code Useless Brackets 173
 MUCO 3 Useless Code Useless Brackets 186
 MUCO 3 Useless Code Useless Brackets 200
 MUCO 3 Useless Code Useless Brackets 205
 MUCO 3 Useless Code Useless Brackets 218
 MUCO 3 Useless Code Useless Brackets 230
 MUCO 3 Useless Code Useless Brackets 244
 MUCO 3 Useless Code Useless Brackets 253
 MUCO 3 Useless Code Useless Brackets 262
 MUCO 3 Useless Code Useless Brackets 283
 MUCO 3 Useless Code Useless Brackets 289
 MUCO 3 Useless Code Useless Brackets 301
 MUCO 3 Useless Code Useless Brackets 315
 MUCO 3 Useless Code Useless Brackets 329
 MUCO 3 Useless Code Useless Brackets 335
 MUCO 3 Useless Code Useless Brackets 341
 MUCO 3 Useless Code Useless Brackets 374
 MUCO 3 Useless Code Useless Brackets 437
 MUCO 3 Useless Code Useless Brackets 442
 MUCO 3 Useless Code Useless Brackets 453
 MUCO 3 Useless Code Useless Brackets 476
 MUCO 3 Useless Code Useless Brackets 485
 MUCO 3 Useless Code Useless Brackets 490
 MUCO 3 Useless Code Useless Brackets 496
 MUCO 3 Useless Code Useless Brackets 507
 MUCO 3 Useless Code Useless Brackets 528
 MUCO 3 Useless Code Useless Brackets 534
 MUCO 3 Useless Code Useless Brackets 545
 MUCO 3 Useless Code Useless Brackets 564
 MUCO 3 Useless Code Useless Brackets 571
 MUCO 3 Useless Code Useless Brackets 596
 MUCO 3 Useless Code Useless Brackets 598
 MUCO 3 Useless Code Useless Brackets 601
 MUCO 3 Useless Code Useless Brackets 610
 MUCO 3 Useless Code Useless Brackets 632
 MUCO 3 Useless Code Useless Brackets 651
 MUCO 3 Useless Code Useless Brackets 657
 MUCO 3 Useless Code Useless Brackets 669
 MUCO 3 Useless Code Useless Brackets 687
 MUCO 3 Useless Code Useless Brackets 693
 MUCO 3 Useless Code Useless Brackets 695
 MUCO 3 Useless Code Useless Brackets 714
 MUCO 3 Useless Code Useless Brackets 763
 MUCO 3 Useless Code Useless Brackets 768
 MUIN 3 Column created using implicit nullability 361
 QAFM 3 Var Assignment from potentially many rows 241
 QCRS 3 Conditional Result Set 250
 QCRS 3 Conditional Result Set 259
 QCRS 3 Conditional Result Set 271
 QCRS 3 Conditional Result Set 296
 QCTC 3 Conditional Table Creation 361
 QGWO 3 Group by/Distinct/Union without order by 296
 QISO 3 Set isolation level 128
 QNAJ 3 Not using ANSI Inner Join 299
 QNAJ 3 Not using ANSI Inner Join 313
 QPNC 3 No column in condition 301
 QPNC 3 No column in condition 306
 QPNC 3 No column in condition 315
 QPNC 3 No column in condition 322
 QPRI 3 Join or Sarg with Rooted Partial Index Use SARG Candidate index: sysattributes.csysattributes unique clustered
(class, attribute, object_type, object, object_info1, object_info2, object_info3, object_cinfo)
Intersection: {class}
243
 QPRI 3 Join or Sarg with Rooted Partial Index Use JOIN Candidate index: sysmessages.ncsysmessages unique
(error, dlevel, langid)
Intersection: {error}
Uncovered: [dlevel]
303
 QPRI 3 Join or Sarg with Rooted Partial Index Use JOIN Candidate index: sysmessages.ncsysmessages unique
(error, dlevel, langid)
Intersection: {error}
Uncovered: [dlevel]
319
 QSWV 3 Sarg with variable @optname, Candidate Index: spt_values.spt_valuesclust clustered(number, type) U 208
 QUNI 3 Check Use of 'union' vs 'union all' 296
 VNRD 3 Variable is not read @db_rep_level_all 430
 VNRD 3 Variable is not read @db_rep_level_none 431
 VNRD 3 Variable is not read @db_rep_level_l1 432
 VUNU 3 Variable is not used @dbname 89
 MRST 2 Result Set Marker 250
 MRST 2 Result Set Marker 259
 MRST 2 Result Set Marker 271
 MRST 2 Result Set Marker 296
 MSUB 2 Subquery Marker 206
 MSUB 2 Subquery Marker 512
 MSUB 2 Subquery Marker 550
 MTR1 2 Metrics: Comments Ratio Comments: 35% 55
 MTR2 2 Metrics: Cyclomatic Complexity Cyclo: 73 = 82dec - 11exi + 2 55
 MTR3 2 Metrics: Query Complexity Complexity: 343 55
 PRED_QUERY_COLLECTION 2 {a=master..sysattributes, m=master..sysmessages, sv=master..spt_values} 0 296
 PRED_QUERY_COLLECTION 2 {a=master..sysattributes, m=master..sysmessages, sv=master..spt_values} 0 310

DEPENDENCIES
PROCS AND TABLES USED
reads table master..sysattributes (1)  
reads table master..sysmessages (1)  
reads table master..syslogins (1)  
calls proc sybsystemprocs..sp_autoformat  
   read_writes table tempdb..#colinfo_af (1) 
   calls proc sybsystemprocs..sp_namecrack  
   reads table tempdb..systypes (1)  
   calls proc sybsystemprocs..sp_autoformat  
   reads table master..systypes (1)  
   reads table tempdb..syscolumns (1)  
   reads table master..syscolumns (1)  
reads table master..syssrvroles (1)  
reads table master..spt_values (1)  
calls proc sybsystemprocs..sp_ha_check_certified  
   reads table tempdb..sysobjects (1)  
calls proc sybsystemprocs..sp_getmessage  
   reads table master..sysmessages (1)  
   calls proc sybsystemprocs..sp_validlang  
      reads table master..syslanguages (1)  
   reads table sybsystemprocs..sysusermessages  
   reads table master..syslanguages (1)  
writes table tempdb..#helpdisplay (1) 
reads table sybsystemprocs..sysattributes  

CALLERS
called by proc sybsystemprocs..sp_downgrade