r2802: a better provisioning script
authorAndrew Tridgell <tridge@samba.org>
Sun, 3 Oct 2004 10:02:41 +0000 (10:02 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:59:35 +0000 (12:59 -0500)
(This used to be commit f5560f961d5b806c2f70feba568d640e6baac2f9)

source4/script/provision.pl

index d99cb6906c862ed8aef9e8e303f0aec23920eb61..60ab5653a0b24bd484ae5f3a4b3cc7a4261746a4 100755 (executable)
@@ -1,14 +1,15 @@
 #!/usr/bin/perl -w
 
 use strict;
+use Getopt::Long;
 
-my $hostname = `hostname`;
-chomp $hostname;
-my $realm = "bludom.tridgell.net";
-my $domain = "BLUDOM";
-my $dnsname = "$hostname.$realm";
-
-my $basedn = "DC=" . join(",DC=", split(/\./, $realm));
+my $opt_hostname = `hostname`;
+chomp $opt_hostname;
+my $opt_realm;
+my $opt_domain;
+my $opt_adminpass;
+my $dnsname;
+my $basedn;
 
 # return the current NTTIME as an integer
 sub nttime()
@@ -41,6 +42,18 @@ sub randsid()
 
 my $domainsid = randsid();
 
+# generate a random password. Poor algorithm :(
+sub randpass()
+{
+       my $pass = "";
+       my $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%\$!~";
+       for (my $i=0;$i<8;$i++) {
+               my $c = int(rand(length($chars)));
+               $pass .= substr($chars, $c, 1);
+       }
+       return $pass;
+}
+
 sub ldaptime()
 {
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) =  gmtime(time);
@@ -63,15 +76,15 @@ sub substitute($)
        }
 
        if ($var eq "DOMAIN") {
-               return $domain;
+               return $opt_domain;
        }
 
        if ($var eq "REALM") {
-               return $realm;
+               return $opt_realm;
        }
 
        if ($var eq "HOSTNAME") {
-               return $hostname;
+               return $opt_hostname;
        }
 
        if ($var eq "DNSNAME") {
@@ -86,6 +99,10 @@ sub substitute($)
                return randguid();
        }
 
+       if ($var eq "ADMINPASS") {
+               return $opt_adminpass;
+       }
+
        if ($var eq "NTTIME") {
                return "" . nttime();
        }
@@ -93,6 +110,18 @@ sub substitute($)
        die "ERROR: Uknown substitution variable $var\n";
 }
 
+#####################################################################
+# write a string into a file
+sub FileSave($$)
+{
+    my($filename) = shift;
+    my($v) = shift;
+    local(*FILE);
+    open(FILE, ">$filename") || die "can't open $filename";    
+    print FILE $v;
+    close(FILE);
+}
+
 #####################################################################
 # read a file into a string
 sub FileLoad($)
@@ -108,15 +137,114 @@ sub FileLoad($)
     return $data;
 }
 
+#######################################################################
+# add a foreign security principle
+sub add_foreign($$)
+{
+       my $sid = shift;
+       my $desc = shift;
+       return "
+dn: CN=$sid,CN=ForeignSecurityPrincipals,\${BASEDN}
+objectClass: top
+objectClass: foreignSecurityPrincipal
+cn: $sid
+description: $desc
+distinguishedName: CN=$sid,CN=ForeignSecurityPrincipals,\${BASEDN}
+instanceType: 4
+whenCreated: \${LDAPTIME}
+whenChanged: \${LDAPTIME}
+uSNCreated: 1
+uSNChanged: 1
+showInAdvancedViewOnly: TRUE
+name: $sid
+objectGUID: \${NEWGUID}
+objectSid: $sid
+objectCategory: CN=Foreign-Security-Principal,CN=Schema,CN=Configuration,\${BASEDN}
+
+";
+}
+
+############################################
+# show some help
+sub ShowHelp()
+{
+       print "
+Samba4 provisioning
+
+provision.pl [options]
+  --realm     REALM       set realm
+  --domain    DOMAIN      set domain
+  --hostname  HOSTNAME    set hostname
+  --adminpass PASSWORD    choose admin password (otherwise random)
+
+You must provide at least a realm and domain
+
+";
+       exit(1);
+}
+
+my $opt_help;
+
+GetOptions(
+           'help|h|?' => \$opt_help, 
+           'realm=s' => \$opt_realm,
+           'domain=s' => \$opt_domain,
+           'hostname=s' => \$opt_hostname,
+           'adminpass=s' => \$opt_adminpass,
+           );
+
+if ($opt_help || 
+    !$opt_realm ||
+    !$opt_domain ||
+    !$opt_hostname) {
+       ShowHelp();
+}
+
+print "Provisioning host '$opt_hostname' for domain '$opt_domain' in realm '$opt_realm'\n";
+
+print "generating ldif ...\n";
+
+$dnsname = "$opt_hostname.$opt_realm";
+$basedn = "DC=" . join(",DC=", split(/\./, $opt_realm));
 
 my $data = FileLoad("provision.ldif") || die "Unable to load provision.ldif\n";
 
+$data .= add_foreign("S-1-5-7", "Anonymous");
+$data .= add_foreign("S-1-5-18", "System");
+$data .= add_foreign("S-1-5-11", "Authenticated Users");
+
+if (!$opt_adminpass) {
+       $opt_adminpass = randpass();
+       print "chose random Administrator password '$opt_adminpass'\n";
+}
+
 my $res = "";
 
+print "applying substitutions ...\n";
+
 while ($data =~ /(.*?)\$\{(\w*)\}(.*)/s) {
        my $sub = substitute($2);
        $res .= "$1$sub";
        $data = $3;
 }
+$res .= $data;
+
+print "saving ldif to newsam.ldif ...\n";
+
+FileSave("newsam.ldif", $res);
+
+unlink("newsam.ldb");
+
+print "creating newsam.ldb ...\n";
+
+# allow provisioning to be run from the source directory
+$ENV{"PATH"} .= ":bin";
+
+system("ldbadd -H newsam.ldb newsam.ldif");
+
+print "done
+
+Please move newsam.ldb to sam.ldb in the lib/private/ directory of your
+Samba4 installation
+";
 
-print $res . $data;