home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / cops_104.zip / cops_104 / docs / readme.C2 / passwd.file.chk < prev   
Text File  |  1992-03-10  |  8KB  |  227 lines

  1. #!/bin/sh
  2. #
  3. #   passwd.file.chk
  4. #
  5. #  Check passsword file -- /etc/passswd -- for incorrect number of fields,
  6. # duplicate uid's, non-alphanumeric uids, and non-numeric group id's.
  7. #
  8. # Awk part from _The AWK Programming Language_, page 78
  9. #
  10. #  Mechanism:  Passwd.check uses awk to ensure that each line of the file
  11. # has 7 fields, as well as examining the file for any duplicate users
  12. # by using "sort -u".  It also checks to make sure that the password
  13. # field (the second one) is either a "*", meaning the group has no password,
  14. # or a non-null field (which would mean that the account has a null
  15. # password.)  It then checks to ensure that all uids are alphanumeric,
  16. # and that all user id numbers are indeed numeric.  For yellow pages
  17. # passwords, it does the same checking, but in order to get a listing of
  18. # all members of the password file, it does a "ypcat passwd > ./$$" and
  19. # uses that temporary file for a passfile.  It removes the tmp file after
  20. # using it, of course.
  21. #   The /etc/passwd file has a very specific format, making the task
  22. # fairly simple.  Normally it has lines with 7 fields, each field
  23. # separated by a colon (:).  The first field is the user id, the second
  24. # field is the encrypted password (an asterix (*) means the user id has no
  25. # password, otherwise the first two characters are the salt), the third
  26. # field is the user id number, the fourth field is the group id number,
  27. # the fifth field is the GECOS field (basically holds miscellaneous
  28. # information, varying from site to site), the sixth field is the home
  29. # directory of the user, and lastly the seventh field is the login shell
  30. # of the user.  No blank lines should be present.
  31. #   The SUN /etc/security/passwd.adjunct file also has a very specific 
  32. # format, making the check task simple. Each entry has 7 fields, each field 
  33. # separated by a colon (:). The first field is the user name which matches 
  34. # the user name contained in the /etc/passwd file. The second field is the 
  35. # encrypted password (an asterix (*) means the user login is disabled,
  36. # otherwise the first two characters are the salt). The password contained
  37. # in the /etc/passwd file is comprised of ##user_id where the user_id 
  38. # matches the entry of the first field in both password files. The third
  39. # through fifth specify the minimum, maximum, and default security labels
  40. # for the user. The sixth and seventh fields specify which auditing flags
  41. # should be always or never monitored.
  42. #   If a line begins with a plus sign (+), it is a yellow pages entry.
  43. # See passwd(5) for more information, if this applies to your site.
  44. #
  45.  
  46. #
  47. # Parameters
  48. #
  49. passwd_file=$1
  50. passwd_adjunct_file=$2
  51. SUN_SECURITY=$3
  52.  
  53. #
  54. # Utilities
  55. #
  56. AWK=/bin/awk
  57. DIFF=/usr/bin/diff
  58. ECHO=/bin/echo
  59. JOIN=/usr/bin/join
  60. RM=/bin/rm
  61. SORT=/usr/bin/sort
  62. TEST=/bin/test
  63. UNIQ=/usr/bin/uniq
  64.  
  65. #
  66. # Important files:
  67. #
  68. join_passwd_1=./pwd$$.1.join
  69. join_passwd_2=./pwd$$.2.join
  70. sort_passwd=./pwd$$.sort
  71. sort_secure_passwd=./spwd$$.sort
  72.  
  73. #
  74. # Testing the passwd file for problems
  75. #
  76. result=`$AWK -F: '{print $1}' $passwd_file | $SORT -t: | $UNIQ -d`
  77. if $TEST "$result"
  78.     then
  79.     $ECHO
  80.     $ECHO "Warning!  Duplicate uid(s) found in password file:"
  81.     for USER in $result
  82.     do
  83.         $ECHO "    $USER"
  84.     done
  85. fi
  86.  
  87. #
  88. #   First line is for a yellow pages entry in the password file.
  89. # It really should check for correct yellow pages syntax....
  90. #
  91. $AWK 'BEGIN {FS = ":" } \
  92.     {if (substr($1,1,1) != "+") { \
  93.     if ($0 ~ /^[     ]*$/) { printf("\nWarning!  Password file, line %d, is blank\n", NR) } else {
  94.     if (NF != 7) {
  95.         printf("\nWarning!  Password file, line %d, does not have 7 fields: \n\t%s\n", NR, $0) } \
  96.     if ($1 !~ /[A-Za-z0-9]/) {
  97.         printf("\nWarning!  Password file, line %d, nonalphanumeric login: \n\t%s\n", NR, $0) } \
  98.     if ($2 == "") {
  99.         printf("\nWarning!  Password file, line %d, no password: \n\t%s\n", NR, $0) } \
  100.      if ("'$SUN_SECURITY'" == "TRUE" && "##"$1 != $2) {
  101.         printf("\nWarning!  Password file, line %d, invalid password field for SUN C2 Security: \n\t%s\n", NR, $0) } \
  102.     if ($3 !~ /[0-9]/) {
  103.         printf("\nWarning!  Password file, line %d, nonnumeric user id: \n\t%s\n", NR, $0) } \
  104.     if ($3 == "0" && $1 != "root") {
  105.         printf("\nWarning!  Password file, line %d, user %s has uid = 0 and is not root\n\t%s\n", NR, $1, $0) } \
  106.     if ($4 !~ /[0-9]/) {
  107.         printf("\nWarning!  Password file, line %d, nonnumeric group id: \n\t%s\n", NR, $0) } \
  108.     if ($6 !~ /^\//) {
  109.         printf("\nWarning!  Password file, line %d, invalid login directory: \n\t%s\n", NR, $0) } \
  110.     }}}' $passwd_file
  111.  
  112. #
  113. # Perform checks on the security enhanced version of SUNOS
  114. #
  115. if $TEST $SUN_SECURITY = "TRUE"
  116.     then
  117.     result=`$AWK -F: '{print $1}' $passwd_adjunct_file | $SORT -t: | $UNIQ -d`
  118.     if $TEST "$result"
  119.         then
  120.         $ECHO
  121.         $ECHO "Warning!  Duplicate uid(s) found in password adjunct file:"
  122.         for USER in $result
  123.         do
  124.             $ECHO "    $USER"
  125.         done
  126.     fi
  127.     #
  128.     # Check that for each entry in the passwd file that there is a matching
  129.     # entry in the passwd.adjunct file.
  130.     #
  131.     $SORT -t: -o $sort_passwd $passwd_file
  132.     $SORT -t: -o $sort_secure_passwd $passwd_adjunct_file
  133.     $JOIN -t: $sort_passwd $sort_secure_passwd > $join_passwd_1
  134.     $JOIN -t: -a1 $sort_passwd $sort_secure_passwd > $join_passwd_2
  135.     result=`$DIFF $join_passwd_1 $join_passwd_2`
  136.     if $TEST "$result"
  137.         then
  138.         $ECHO
  139.         $ECHO "Warning!  Matching record(s) in password adjunct file not found for"
  140.         $ECHO "these records in password file:"
  141.         PREV=$$
  142.         for USER in $result
  143.         do
  144.             if $TEST $PREV = ">"
  145.                 then
  146.                 $ECHO "    $USER"
  147.             fi
  148.             PREV=$USER
  149.         done
  150.     fi
  151.     #
  152.     # Check that for each entry in the passwd.adjunct file that there is a 
  153.     # matching entry in the passwd file.
  154.     #
  155.     $RM -f $join_passwd_2
  156.     $JOIN -t: -a2 $sort_passwd $sort_secure_passwd > $join_passwd_2
  157.     result=`$DIFF $join_passwd_1 $join_passwd_2`
  158.     if $TEST "$result"
  159.         then
  160.         $ECHO
  161.         $ECHO "Warning!  Matching record(s) in password file not found for"
  162.         $ECHO "these records in password adjunct file"
  163.         PREV=$$
  164.         for USER in $result
  165.         do
  166.             if $TEST $PREV = ">"
  167.                 then
  168.                 $ECHO "    $USER"
  169.             fi
  170.             PREV=$USER
  171.         done
  172.     fi
  173.     #
  174.     # Test the fields in the passwd.adjunct file for validity
  175.     #
  176.     $AWK 'BEGIN {FS = ":" } \
  177.         {if (substr($1,1,1) != "+") { \
  178.         if ($0 ~ /^[     ]*$/) { printf("\nWarning!  Password adjunct file, line %d, is blank\n", NR) } else {
  179.         if (NF != 7) {
  180.             printf("\nWarning!  Password adjunct file, line %d, does not have 7 fields: \n\t%s\n", NR, $0) } \
  181.         if ($1 !~ /[A-Za-z0-9]/) {
  182.             printf("\nWarning!  Password adjunct file, line %d, nonalphanumeric login: \n\t%s\n", NR, $0) } \
  183.         if ($2 == "") {
  184.             printf("\nWarning!  Password adjunct file, line %d, no password: \n\t%s\n", NR, $0) } \
  185.         #
  186.         # Fields 3-5 are ignored since they deal with labels which are
  187.         # currently unused on the SUN (perhaps a future B-level??)
  188.         #
  189.         # Fields 6+7 contain audit flags for the user and are selected
  190.         # from the following: dr, dw, dc, da, lo, ad, p0, p1, and all.
  191.         # More than 1 flag can be selected by separating flags with a 
  192.         # comma (,).
  193.         #
  194.         if ($6 != "") {
  195.             j=1
  196.             len=length($6)
  197.             for (i=1; i<=len; i++) {
  198.                 if ((substr($6,i,1) != ",") && (i < len)) 
  199.                     continue
  200.                 if (i == len)
  201.                     token=substr($6,j,i-j+1)
  202.                 else
  203.                     token=substr($6,j,i-j)
  204.                 j=i+1
  205.                 if (token == "dr") continue
  206.                 if (token == "dw") continue
  207.                 if (token == "dc") continue
  208.                 if (token == "da") continue
  209.                 if (token == "lo") continue
  210.                 if (token == "ad") continue
  211.                 if (token == "p0") continue
  212.                 if (token == "p1") continue
  213.                 if (token == "all") continue
  214.             printf("\nWarning!  Password adjunct file, line %d, invalid audit flag: %s\n\t%s\n", NR, token, $0) } \
  215.             }
  216.         }}}' $passwd_adjunct_file
  217. fi
  218.  
  219. #
  220. # Clean up after ourself
  221. #
  222. $RM -f $join_passwd_1
  223. $RM -f $join_passwd_2
  224. $RM -f $sort_passwd
  225. $RM -f $sort_secure_passwd
  226. # end
  227.