PERL   68

migrate_passwd.pl

Guest on 28th July 2022 02:01:09 AM

  1. #!/usr/bin/perl
  2. #
  3. # $Id: migrate_passwd.pl,v 1.17  lukeh Exp $
  4. #
  5. # Copyright (c)  Luke Howard.
  6. # All rights reserved.
  7. #
  8. # Redistribution and use in source and binary forms, with or without
  9. # modification, are permitted provided that the following conditions
  10. # are met:
  11. # 1. Redistributions of source code must retain the above copyright
  12. #       notice, this list of conditions and the following disclaimer.
  13. # 2. Redistributions in binary form must reproduce the above copyright
  14. #       notice, this list of conditions and the following disclaimer in the
  15. #       documentation and/or other materials provided with the distribution.
  16. # 3. All advertising materials mentioning features or use of this software
  17. #       must display the following acknowledgement:
  18. #               This product includes software developed by Luke Howard.
  19. # 4. The name of the other may not be used to endorse or promote products
  20. #       derived from this software without specific prior written permission.
  21. #
  22. # THIS SOFTWARE IS PROVIDED BY THE LUKE HOWARD ``AS IS'' AND
  23. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. # ARE DISCLAIMED.  IN NO EVENT SHALL LUKE HOWARD BE LIABLE
  26. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32. # SUCH DAMAGE.
  33. #
  34. #
  35. # Password migration tool. Migrates /etc/shadow as well, if it exists.
  36. #
  37. # Thanks to Peter Jacob Slot <peter@vision.auk.dk>.
  38. #
  39. # UTF8 support by Jonas Smedegaard <dr@jones.dk>.
  40.  
  41. require 'migrate_common.ph';
  42.  
  43. $PROGRAM = "migrate_passwd.pl";
  44. $NAMINGCONTEXT = &getsuffix($PROGRAM);
  45.  
  46. &parse_args();
  47. &read_shadow_file();
  48. &open_files();
  49.  
  50. while(<INFILE>)
  51. {
  52.         chop;
  53.         next if /^\s*$/;
  54.         next if /^#/;
  55.         next if /^\+/;
  56.  
  57.         local($user, $pwd, $uid, $gid, $gecos, $homedir, $shell) = split(/:/);
  58.  
  59.         next if (int($IGNORE_UID_BELOW) and int($uid) < int($IGNORE_UID_BELOW));
  60.         next if (int($IGNORE_UID_ABOVE) and int($uid) > int($IGNORE_UID_ABOVE));
  61.         next if (int($IGNORE_GID_BELOW) and int($gid) < int($IGNORE_GID_BELOW));
  62.         next if (int($IGNORE_GID_ABOVE) and int($gid) > int($IGNORE_GID_ABOVE));
  63.  
  64.         if ($use_stdout) {
  65.                 &dump_user(STDOUT, $user, $pwd, $uid, $gid, $gecos, $homedir, $shell);
  66.         } else {
  67.                 &dump_user(OUTFILE, $user, $pwd, $uid, $gid, $gecos, $homedir, $shell);
  68.         }
  69. }
  70.  
  71. sub dump_user
  72. {
  73.         local($HANDLE, $user, $pwd, $uid, $gid, $gecos, $homedir, $shell) = @_;
  74.         local($name,$office,$wphone,$hphone)=split(/,/,$gecos);
  75.         local($sn);    
  76.         local($givenname);     
  77.         local($cn);
  78.         local(@tmp);
  79.  
  80.         if ($name) { $cn = $name; } else { $cn = $user; }
  81.  
  82.         $_ = $cn;
  83.         @tmp = split(/\s+/);
  84.         $sn = $tmp[$#tmp];
  85.         pop(@tmp);
  86.         $givenname=join(' ',@tmp);
  87.  
  88.         print $HANDLE "dn: uid=$user,$NAMINGCONTEXT\n";
  89.         print $HANDLE "uid: $user\n";
  90.         &print_utf8($HANDLE, "cn", $cn);
  91.  
  92.         if ($EXTENDED_SCHEMA) {
  93.                 if ($wphone) {
  94.                         &print_utf8($HANDLE, "telephoneNumber", $wphone);
  95.                 }
  96.                 if ($office) {
  97.                         &print_utf8($HANDLE, "roomNumber", $office);
  98.                 }
  99.                 if ($hphone) {
  100.                         &print_utf8($HANDLE, "homePhone", $hphone);
  101.                 }
  102.                 if ($givenname) {
  103.                         &print_utf8($HANDLE, "givenName", $givenname);
  104.                 }
  105.                 &print_utf8($HANDLE, "sn", $sn);
  106.                 if ($DEFAULT_MAIL_DOMAIN) {
  107.                         print $HANDLE "mail: $user\@$DEFAULT_MAIL_DOMAIN\n";
  108.                 }
  109.                 if ($DEFAULT_MAIL_HOST) {
  110.                         print $HANDLE "mailRoutingAddress: $user\@$DEFAULT_MAIL_HOST\n";
  111.                         print $HANDLE "mailHost: $DEFAULT_MAIL_HOST\n";
  112.                         print $HANDLE "objectClass: inetLocalMailRecipient\n";
  113.                 }
  114.                 print $HANDLE "objectClass: person\n";
  115.                 print $HANDLE "objectClass: organizationalPerson\n";
  116.                 print $HANDLE "objectClass: inetOrgPerson\n";
  117.         } else {
  118.                 &print_utf8($HANDLE, "sn", $sn);
  119.                 print $HANDLE "objectClass: account\n";
  120.         }
  121.  
  122.         print $HANDLE "objectClass: person\n";
  123.         print $HANDLE "objectClass: organizationalPerson\n";
  124.         print $HANDLE "objectClass: inetOrgPerson\n";
  125.         print $HANDLE "objectClass: posixAccount\n";
  126.         print $HANDLE "objectClass: top\n";
  127.  
  128.         if ($DEFAULT_REALM) {
  129.                 print $HANDLE "objectClass: krb5Principal\n";
  130.         }
  131.  
  132.         if ($shadowUsers{$user} ne "") {
  133.                 &dump_shadow_attributes($HANDLE, split(/:/, $shadowUsers{$user}));
  134.         } else {
  135.         }
  136.  
  137.         if ($DEFAULT_REALM) {
  138.                 print $HANDLE "krb5PrincipalName: $user\@$DEFAULT_REALM\n";
  139.         }
  140.  
  141.         if ($shell) {
  142.                 print $HANDLE "loginShell: $shell\n";
  143.         }
  144.  
  145.         if ($uid ne "") {
  146.                 print $HANDLE "uidNumber: $uid\n";
  147.         } else {
  148.                 print $HANDLE "uidNumber:\n";
  149.         }
  150.  
  151.         if ($gid ne "") {
  152.                 print $HANDLE "gidNumber: $gid\n";
  153.         } else {
  154.                 print $HANDLE "gidNumber:\n";
  155.         }
  156.  
  157.         if ($homedir) {
  158.                 print $HANDLE "homeDirectory: $homedir\n";
  159.         } else {
  160.                 print $HANDLE "homeDirectory:\n";
  161.         }
  162.  
  163.         if ($gecos) {
  164.                 &print_ascii($HANDLE, "gecos", $gecos);
  165.         }
  166.  
  167.         print $HANDLE "\n";
  168. }
  169.  
  170. close(INFILE);
  171. if (OUTFILE != STDOUT) { close(OUTFILE); }
  172.  
  173. sub read_shadow_file
  174. {
  175.         open(SHADOW, "/etc/shadow") || return;
  176.         while(<SHADOW>) {
  177.                 chop;
  178.                 ($shadowUser) = split(/:/, $_);
  179.                 $shadowUsers{$shadowUser} = $_;
  180.         }
  181.         close(SHADOW);
  182. }
  183.  
  184. sub dump_shadow_attributes
  185. {
  186.         local($HANDLE, $user, $pwd, $lastchg, $min, $max, $warn, $inactive, $expire, $flag) = @_;
  187.  
  188.         print $HANDLE "objectClass: shadowAccount\n";
  189.         if ($pwd) {
  190.         }
  191.         if ($lastchg ne "") {
  192.                 print $HANDLE "shadowLastChange: $lastchg\n";
  193.         }
  194.         if ($min) {
  195.                 print $HANDLE "shadowMin: $min\n";
  196.         }
  197.         if ($max) {
  198.                 print $HANDLE "shadowMax: $max\n";
  199.         }
  200.         if ($warn) {
  201.                 print $HANDLE "shadowWarning: $warn\n";
  202.         }
  203.         if ($inactive) {
  204.                 print $HANDLE "shadowInactive: $inactive\n";
  205.         }
  206.         if ($expire) {
  207.                 print $HANDLE "shadowExpire: $expire\n";
  208.         }
  209.         if ($flag) {
  210.                 print $HANDLE "shadowFlag: $flag\n";
  211.         }
  212. }
  213.  
  214. sub print_utf8
  215. {
  216.         my($HANDLE, $attribute, $content) = @_;
  217.  
  218.         if (&validate_ascii($content)) {
  219.                 print $HANDLE "$attribute: $content\n";
  220.         } elsif ($USE_UTF8) {
  221. #               $content = &recode_custom_to_utf8($content);
  222.                 $content = &recode_latin1_to_utf8($content);
  223.                 if (&validate_utf8($content)) {
  224.                         $content = &encode_base64($content, "");
  225.                         print $HANDLE "$attribute\:: $content\n";
  226.                 } else {
  227.                         die "ERROR: Illegal character(s) in UTF-8 string: \"$content\"";
  228.                 }
  229.         } else {
  230.                 &print_ascii($HANDLE, "$attribute", "$content");
  231.         }
  232. }
  233.  
  234. sub print_ascii
  235. {
  236.         my($HANDLE, $attribute, $content) = @_;
  237.  
  238.         if (&validate_utf8($content)) {
  239.                 $content = &recode_utf8_to_latin1($content);
  240.         } else {
  241.                 $content = &recode_latin1_to_utf8($content);
  242.                 $content = &recode_utf8_to_latin1($content);
  243.         }
  244.         $content = &recode_custom_to_ascii($content);
  245.         if (&validate_ascii($content)) {
  246.                 print $HANDLE "$attribute: $content\n";
  247.         } else {
  248.                 my $badchars = $content;
  249.                 for ($badchars) {
  250.                         s/[\x20-\x7E]//g;
  251.                 }
  252.                 die "ERROR: Illegal character(s) \"$badchars\" in ASCII string: \"$content\"";
  253.         }
  254. }
  255.  
  256. sub recode_latin1_to_utf8
  257. {
  258.         my ($content) = @_;
  259.         for ($content) {
  260.                 s/([\x80-\xFF])/chr(0xC0|ord($1)>>6).chr(0x80|ord($1)&0x3F)/eg;
  261.         }
  262.         return ($content)
  263. }
  264.  
  265. sub recode_utf8_to_latin1
  266. {
  267.         my ($content) = @_;
  268.         for ($content) {
  269.                 s/([\xC2\xC3])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg;
  270.         }
  271.         return ($content)
  272. }
  273.  
  274. sub recode_custom_to_ascii
  275. {
  276.         my ($content) = @_;
  277.         for ($content) {
  278.                 s/\xc0/A/g; # latin capital letter a with grave
  279.                 s/\xc1/A/g; # latin capital letter a with acute
  280.                 s/\xc2/A/g; # latin capital letter a with circumflex
  281.                 s/\xc3/A/g; # latin capital letter a with tilde
  282.                 s/\xc4/Ae/g; # latin capital letter a with diaeresis
  283.                 s/\xc5/Aa/g; # latin capital letter a with ring above
  284.                 s/\xc6/Ae/g; # latin capital letter ae
  285.                 s/\xc7/C/g; # latin capital letter c with cedilla
  286.                 s/\xc8/E/g; # latin capital letter e with grave
  287.                 s/\xc9/E/g; # latin capital letter e with acute
  288.                 s/\xca/E/g; # latin capital letter e with circumflex
  289.                 s/\xcb/Ee/g; # latin capital letter e with diaeresis
  290.                 s/\xcc/I/g; # latin capital letter i with grave
  291.                 s/\xcd/I/g; # latin capital letter i with acute
  292.                 s/\xce/I/g; # latin capital letter i with circumflex
  293.                 s/\xcf/Ie/g; # latin capital letter i with diaeresis
  294.                 s/\xd0/Dh/g; # latin capital letter eth (icelandic)
  295.                 s/\xd1/N/g; # latin capital letter n with tilde
  296.                 s/\xd2/O/g; # latin capital letter o with grave
  297.                 s/\xd3/O/g; # latin capital letter o with acute
  298.                 s/\xd4/O/g; # latin capital letter o with circumflex
  299.                 s/\xd5/O/g; # latin capital letter o with tilde
  300.                 s/\xd6/Oe/g; # latin capital letter o with diaeresis
  301.                 s/\xd8/Oe/g; # latin capital letter o with stroke
  302.                 s/\xd9/U/g; # latin capital letter u with grave
  303.                 s/\xda/U/g; # latin capital letter u with acute
  304.                 s/\xdb/U/g; # latin capital letter u with circumflex
  305.                 s/\xdc/Ue/g; # latin capital letter u with diaeresis
  306.                 s/\xdd/Y/g; # latin capital letter y with acute
  307.                 s/\xde/TH/g; # latin capital letter thorn (icelandic)
  308.                 s/\xdf/ss/g; # latin small letter sharp s (german)
  309.                 s/\xe0/a/g; # latin small letter a with grave
  310.                 s/\xe1/a/g; # latin small letter a with acute
  311.                 s/\xe2/a/g; # latin small letter a with circumflex
  312.                 s/\xe3/a/g; # latin small letter a with tilde
  313.                 s/\xe4/ae/g; # latin small letter a with diaeresis
  314.                 s/\xe5/aa/g; # latin small letter a with ring above
  315.                 s/\xe6/ae/g; # latin small letter ae
  316.                 s/\xe7/c/g; # latin small letter c with cedilla
  317.                 s/\xe8/e/g; # latin small letter e with grave
  318.                 s/\xe9/e/g; # latin small letter e with acute
  319.                 s/\xea/e/g; # latin small letter e with circumflex
  320.                 s/\xeb/ee/g; # latin small letter e with diaeresis
  321.                 s/\xec/i/g; # latin small letter i with grave
  322.                 s/\xed/i/g; # latin small letter i with acute
  323.                 s/\xee/i/g; # latin small letter i with circumflex
  324.                 s/\xef/ii/g; # latin small letter i with diaeresis
  325.                 s/\xf0/dh/g; # latin small letter eth (icelandic)
  326.                 s/\xf1/n/g; # latin small letter n with tilde
  327.                 s/\xf2/o/g; # latin small letter o with grave
  328.                 s/\xf3/o/g; # latin small letter o with acute
  329.                 s/\xf4/o/g; # latin small letter o with circumflex
  330.                 s/\xf5/o/g; # latin small letter o with tilde
  331.                 s/\xf6/oe/g; # latin small letter o with diaeresis
  332.                 s/\xf8/oe/g; # latin small letter o with stroke
  333.                 s/\xf9/u/g; # latin small letter u with grave
  334.                 s/\xfa/u/g; # latin small letter u with acute
  335.                 s/\xfb/u/g; # latin small letter u with circumflex
  336.                 s/\xfc/ue/g; # latin small letter u with diaeresis
  337.                 s/\xfd/y/g; # latin small letter y with acute
  338.                 s/\xfe/th/g; # latin small letter thorn (icelandic)
  339.                 s/\xff/ye/g; # latin small letter y with diaeresis
  340.         }
  341.         return ($content);
  342. }
  343.  
  344. sub encode_base64
  345. # Found in email by Baruzzi Giovanni <giovanni.baruzzi@allianz-leben.de> on openldap mailinglist
  346.  
  347. # Historically this module has been implemented as pure perl code.
  348. # The XS implementation runs about 20 times faster, but the Perl
  349. # code might be more portable, so it is still here.
  350. {
  351.         my $res = "";
  352.         my $eol = $_[1];
  353.         $eol = "\n" unless defined $eol;
  354.         pos($_[0]) = 0; # ensure start at the beginning
  355.         while ($_[0] =~ /(.{1,45})/gs) {
  356.                 $res .= substr(pack('u', $1), 1);
  357.                 chop($res);
  358.         }
  359.         $res =~ tr|` -_|AA-Za-z0-9+/|;               # `# help emacs
  360.         # fix padding at the end
  361.         my $padding = (3 - length($_[0]) % 3) % 3;
  362.         $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
  363.         # break encoded string into lines of no more than 76 characters each
  364.         if (length $eol) {
  365.                 $res =~ s/(.{1,76})/$1$eol/g;
  366.         }
  367.         $res;
  368. }
  369.  
  370. sub validate_ascii
  371. {
  372.         my ($content) = @_;
  373.         $content =~ /^[\x20-\x7E]*$/;
  374. }
  375.  
  376. sub validate_utf8
  377. {
  378.         my ($content) = @_;
  379.         if (&validate_ascii($content)) {
  380.                 return 1;
  381.         }
  382.         if ($] >= 5.8) {
  383.                 ## No Perl support for UTF-8! ;-/
  384.                 return undef;
  385.         }
  386.         $content =~ /^[\x20-\x7E\x{0080}-\x{FFFF}]*$/;
  387. }

Raw Paste


Login or Register to edit or fork this paste. It's free.