Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl -wT
- use strict;
- use CGI;
- use CGI::Carp 'fatalsToBrowser';
- use POSIX qw(strftime);
- use Mail::Mailer qw(sendmail);
- use Net::NIS;
- use Net::LDAPS;
- use Net::LDAP qw(LDAP_SUCCESS LDAP_ALREADY_EXISTS);
- use Unicode::Map8;
- use Unicode::String qw(utf16);
- $CGI::POST_MAX = 1024 * 100; # max 100K posts
- $CGI::DISABLE_UPLOADS = 1; # no uploads
- $ENV{PATH} = '/bin:/usr/bin';
- use constant ROOTDN => 'OU=User Accounts,DC=internal,DC=XXXX,DC=com';
- use constant DOMAIN => 'internal.XXXX.com';
- use constant SERVER => ['wdc01.' . DOMAIN, 'wdc02.' . DOMAIN, 'wdc03.' . DOMAIN];
- use constant ADMIN => 'XXXXX';
- use constant ADMPW => 'YYYYY';
- use constant NORMAL_ACCOUNT => 0x200;
- # the JavaScript code for validating web form
- use constant JSCRIPT => '
- // has the user entered mail and username already?
- var mail_changed = false;
- var user_changed = false;
- // verify that mandatory fields have been filled out
- function check(aForm) {
- if (aForm.first.value.length < 2) {
- alert("Please enter first name!");
- aForm.first.focus();
- return false;
- }
- if (aForm.last.value.length < 2) {
- alert("Please enter last name!");
- aForm.last.focus();
- return false;
- }
- if (aForm.user.value.length < 3) {
- alert("Please enter username!");
- aForm.user.focus();
- return false;
- }
- if (aForm.password.value.length < 8) {
- alert("Please enter random password!");
- aForm.password.focus();
- return false;
- }
- if (aForm.mail.value.length < 5) {
- alert("Please enter user mail address!");
- aForm.mail.focus();
- return false;
- }
- return true;
- }
- // generate mail address and username - unless user has entered them already
- function generate(aForm) {
- if (aForm.first.value.length < 2 ||
- aForm.last.value.length < 2)
- return;
- // use the 1st letter of first name + last name to generate user name
- if (! user_changed)
- aForm.user.value =
- aForm.first.value.substring(0, 1).toLowerCase() +
- aForm.last.value.substring(0, 7).toLowerCase();
- // use first name + last name to generate the mail address
- if (! mail_changed)
- aForm.mail.value =
- ("XXXX" == aForm.company.value ? "" : "ext-") +
- aForm.first.value + "." + aForm.last.value;
- }
- ';
- my @CITIES = qw(Bochum Berlin Bayern);
- my @COMPANIES = qw(
- XXXX
- YYYY_Consulting
- ZZZZ
- );
- my @VOWELS = split //, 'AEUaeiou34';
- my @CONSONANTS = split //, 'CDFGHJKLMNPQRSTVWXbcdfhjkmnprstvwx25679';
- sub genpass($) {
- my ($len, $pass);
- $len = shift;
- do {
- $pass = '';
- do {
- $pass .= $CONSONANTS[rand @CONSONANTS];
- $pass .= $VOWELS[rand @VOWELS];
- } while (length $pass < $len);
- # escape here when generating 2-chars salt
- last if $len < 8;
- # make sure the password contains 2 digit and 2 letters
- } while ($pass =~ tr/0-9// < 2 ||
- $pass =~ tr/a-z// < 2 ||
- $pass =~ tr/A-Z// < 2);
- return $pass;
- }
- my ($query, $cookie, %defaults, %passwd, $maxuid, $ldap, $result, $mta,
- $charmap, $unipwd, $rot13, $user, $first, $last, $mail, $city, $company,
- $pass, $crypt, $inform, $fullname, $dn, $date, $home, $pst, $gid);
- $query = new CGI;
- # untaint user input
- $first = $1 if $query->param('first') =~ /(\w[\w -]{1,10}\w)/;
- $last = $1 if $query->param('last') =~ /(\w[\w -]{1,10}\w)/;
- $user = $1 if $query->param('user') =~ /(\w{3,12})/;
- $password = $1 if $query->param('password') =~ /(\w{8})/;
- $mail = "\L$1\@XXXX.com" if $query->param('mail') =~ /([\w.-]{3,30})/;
- $inform = "\L$1\@XXXX.com" if $query->param('inform') =~ /([\w.-]{3,30})/;
- for (@COMPANIES) {
- if ($query->param('company') =~ /($_)/) {
- $company = $1;
- last;
- }
- }
- for (@CITIES) {
- if ($query->param('city') =~ /($_)/) {
- $city = $1;
- last;
- }
- }
- unless ($user and $password and $first and $last and
- $city and $company and $mail) {
- print $query->header,
- $query->start_html(-title => 'Create new user / Enter data',
- -script => JSCRIPT),
- '<p><img src="/XXXX.png" width=241 height=50 alt="XXXX"></p>';
- # retrieve saved values from the cookie
- %defaults = $query->cookie('defaults');
- $defaults{company} = 'XXXX' unless $defaults{company};
- $defaults{city} = 'Bochum' unless $defaults{city};
- print $query->start_multipart_form(-onsubmit => 'return check(this)'),
- '<table cellpadding=4>',
- '<tr><td colspan=2>Optional batch file:</td></tr>',
- '<tr><td colspan=2>',
- $query->filefield(-name => 'uploaded_file',
- -size => 14),
- '</td></tr>',
- '<tr><td colspan=2><hr></td></tr>',
- '<tr><td>First name:</td><td>',
- $query->textfield(-name => 'first',
- -onchange => 'generate(this.form);',
- -size => 12),
- '</td></tr>',
- '<tr><td>Last name:</td><td>',
- $query->textfield(-name => 'last',
- -onchange => 'generate(this.form);',
- -size => 12),
- '</td></tr>',
- '<tr><td>Username:</td><td>',
- $query->textfield(-name => 'user',
- -onchange => 'user_changed = true;',
- -size => 12,
- -maxlength => 8),
- '</td></tr>',
- '<tr><td>Password:</td><td>',
- $query->textfield(-name => 'password',
- -value => genpass(8),
- -override => 1,
- -size => 12),
- '</td></tr>',
- '<tr><td>Company:</td><td>',
- $query->scrolling_list(-name => 'company',
- -onchange => 'generate(this.form);',
- -values => \@COMPANIES,
- #-default => 'XXXX',
- -default => $defaults{company},
- -size => 6),
- '</td></tr>',
- '<tr><td>City:</td><td>',
- $query->scrolling_list(-name => 'city',
- -values => \@CITIES,
- #-default => 'Bochum',
- -default => $defaults{city},
- -size => 4),
- '</td></tr>',
- '<tr><td colspan=2>User mail address:</td></tr>',
- '<tr><td colspan=2>',
- $query->textfield(-name => 'mail',
- -style => 'text-align: right',
- -onchange => 'mail_changed = true;',
- -size => 24),
- '@XXXX.com</td></tr>',
- '<tr><td colspan=2>Also send password to:</td></tr>',
- '<tr><td colspan=2>(this input is optional)</td></tr>',
- '<tr><td colspan=2>',
- $query->textfield(-name => 'inform',
- -style => 'text-align: right',
- -value => $defaults{inform},
- -size => 24),
- '@XXXX.com</td></tr>',
- '<tr><td> </td><td>',
- $query->submit(-value => 'Create user'),
- '</td></tr>',
- $query->end_form;
- } else {
- # save the entered values for a day
- %defaults = (company => $company,
- city => $city,
- inform => $query->param('inform'));
- print $query->header(-cookie => $query->cookie(-name => 'defaults',
- -value => \%defaults,
- -expires =>'+1d')),
- $query->start_html(-title => 'Create new user / Data submitted'),
- '<p><img src="/XXXX.png" width=241 height=50 alt="XXXX"></p>';
- # create the new user in active directory
- ($rot13 = ADMPW) =~ y/A-Za-z/N-ZA-Mn-za-m/;
- $ldap = Net::LDAPS->new(SERVER) or
- die('Can not connect to LDAP server');
- $ldap->bind(ADMIN . '@' . DOMAIN, password => $rot13) or
- die('Can not bind to LDAP server as ' . ADMIN);
- $fullname = "$first $last";
- $dn = "cn=$user," . ROOTDN;
- $charmap = Unicode::Map8->new('latin1') or die $!;
- $unipwd = $charmap->tou(qq{"$password"})->byteswap()->utf16();
- $result = $ldap->add($dn,
- attr => [
- objectClass => 'user',
- sAMAccountName => $user,
- userPrincipalName => $user . '@' . DOMAIN,
- givenName => $first,
- sn => $last,
- displayName => "$last $first ($company/$city)",
- description => $fullname,
- mail => $mail,
- l => $city,
- physicalDeliveryOfficeName => $city,
- company => $company,
- # Must set password later because of policy
- #unicodePwd => $unipwd,
- homeDrive => 'H:',
- homeDirectory =>
- "\\\\internal.XXXX.com\\home\\$user",
- ]
- );
- if (LDAP_SUCCESS != $result->code) {
- if (LDAP_ALREADY_EXISTS == $result->code) {
- print "<p>User $user already exists!</p>\n",
- $query->end_html;
- exit;
- }
- die 'Failed to add user: ', $result->error;
- }
- $result = $ldap->modify($dn, replace => { unicodePwd => $unipwd } );
- $result->code && die 'Failed to modify user: ', $result->error;
- $result = $ldap->modify($dn, replace => { pwdLastSet => 0 } );
- $result->code && die 'Failed to modify user: ', $result->error;
- $result = $ldap->modify($dn,
- replace => { userAccountControl => NORMAL_ACCOUNT } );
- $result->code && die 'Failed to enable user: ', $result->error;
- $ldap->unbind();
- #goto SKIPMAIL;
- # send the mail to the new user and the inform person
- $mta = Mail::Mailer->new();
- die "Can not send mail: $!\n" unless $mta->open({
- From => q{"XXXX IT" <it@XXXX.com>},
- To => $mail,
- # send a copy to IT and eventually to contact person
- Cc => join(',', 'it@XXXX.com', $inform),
- Subject => "IT-INFOS: Windows account infos for $first $last",
- });
- print $mta qq{
- Dear $first $last,
- the XXXX Windows account infos for you are:
- User name: INTERNAL\\$user
- Password: $password
- Your home directory
- \\\\internal.XXXX.com\\home\\$user
- will be mounted as drive H:
- Regards,
- XXXX IT team
- PS: If you have received the account infos
- for $first $last because
- you are listed as the contact person
- for him/her, then please forward the login
- data and treat it as highly confidential!
- };
- $mta->close();
- #SKIPMAIL:
- # print instructions for creating Unix dirs
- $date = strftime '%F', localtime;
- $home = "/mnt/nas02/hom01/home/$user";
- $pst = "/mnt/nas02/pst01/home_pst/$user";
- # use group XXXX (5675) for internals
- # and XXXX_ext (5579) for externals
- $gid = ($company eq 'XXXX' ? '5675' : '5579');
- # find the max uid in NIS
- tie %passwd, 'Net::NIS', 'passwd.byname' or
- die "Cannot tie to passwd YP map: $yperr\n";
- $maxuid = 0;
- while (my ($key, $value) = each %passwd) {
- my $uid = (split ':', $value)[2];
- $maxuid = $uid if $uid > $maxuid;
- }
- $maxuid++;
- $crypt = crypt($pass, genpass(2));
- printf '<p>The user <b>%s</b> with password <b>%s</b> ' .
- 'has been created in Active Directory under %s</p> ' .
- '<p>Please <b>ssh root@XXX01</b> and issue the commands:</p>',
- $user, $pass, ROOTDN;
- print qq{
- <p><b>echo '${user}:$crypt:${maxuid}:${gid}:${first} ${last},joined $date,,,,:/home/$user:/bin/bash' >> /var/nis/passwd</b></p>
- <p><b>make -C /var/yp</b><br></p>};
- # apache ALL=(ALL) NOPASSWD: /bin/mkdir, /bin/chmod, /bin/chown
- system('sudo', '/bin/mkdir', '-p', $home) and die $?;
- system('sudo', '/bin/chmod', '2700', $home) and die $?;
- system('sudo', '/bin/chown', "${maxuid}:$gid", $home) and die $?;
- system('sudo', '/bin/mkdir', '-p', $pst) and die $?;
- system('sudo', '/bin/chmod', '2700', $pst) and die $?;
- system('sudo', '/bin/chown', "${maxuid}:$gid", $pst) and die $?;
- printf qq{<hr><p><a href="%s">Add another user</a></p>}, $query->url(-absolute => 1);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement