[Fedora-directory-commits] ldapserver/ldap/admin/src cfg_sspt.c, 1.11, 1.12 create_instance.c, 1.57, 1.58 ds_newinst.pl.in, 1.6, 1.7

Richard Allen Megginson (rmeggins) fedora-directory-commits at redhat.com
Thu Jun 7 22:40:17 UTC 2007


Author: rmeggins

Update of /cvs/dirsec/ldapserver/ldap/admin/src
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv25184/ldapserver/ldap/admin/src

Modified Files:
	cfg_sspt.c create_instance.c ds_newinst.pl.in 
Log Message:
Resolves: bug 243205
Description: allow instance creation with no .inf file; allow pre-hashed RootDNPwd
Reviewed by: nhosoi (Thanks!)
Fix Description: You can now use ds_newinst.pl without (or with) a .inf file like this:
 ds_newinst.pl General.SuiteSpotUserID=nobody slapd.ServerPort=3890 ....
The parameters can be supplied via the command line.  The format of the parameter is section.param=value.  Normal shell quoting rules apply, so you still have to do something like this:
 ds_newinst.pl "slapd.Suffix=dc=example, dc=com"
for embedded spaces and the like.  If you supply a filename (or '-'), it must be the first argument after ds_newinst.pl.  If you then supply additional arguments after the filename, these will override the settings in the given inf file.  So, for example, you could reuse the same .inf file, except provide a different hostname:
 ds_newinst.pl basefile.inf General.FullMachineName=bar.example.com
This allows you to use the same base .inf file for several machines, and only change certain parameters on a per-machine basis.
ds_newinst.pl will now fill in some default values - it will use Net::Domain::hostfqdn for FullMachineName, and your login ID for SuiteSpotUserID (however, not if running ds_newinst.pl as root), and will construct the Suffix and ServerIdentifier based on the FullMachineName.  RootDN will default to cn=Directory Manager.  ServerRoot is no longer required.
Another enhancement is the ability to provide a pre-hashed password for the RootDNPwd parameter, to avoid having to pass around the clear text directory manager password.  However, some caveats apply.  If the password begins with one of the well known hash algorithms (e.g. {SHA, {SSHA, etc.), ds_newinst will assume it is already hashed.  This may cause problems if users expect to be able to provide a clear text password such as {SSHA}text, but I seriously doubt anyone does that (famous last words . . .).  Another problem is that the code as it currently stands uses the clear text password to bind to the server after starting the server to add some additional entries and ACIs.  This cannot be done if a pre-hashed password is provided (but we're working on a solution to that problem too).
write_ldap_info() is no longer needed.
Finally, a couple of minor bug fixes.
Platforms tested: RHEL4
Flag Day: no
Doc impact: Yes.  There will be some documentation changes required.



Index: cfg_sspt.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/cfg_sspt.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- cfg_sspt.c	10 Nov 2006 23:44:33 -0000	1.11
+++ cfg_sspt.c	7 Jun 2007 22:40:14 -0000	1.12
@@ -1362,39 +1362,6 @@
 	return connection;
 }
 
-static int
-write_ldap_info(SLAPD_CONFIG* slapd, char* base, char* admnm)
-{
-	FILE* fp;
-	int ret = 0;
-
-	char* fmt = "%s/shared/config/ldap.conf";
-	char* infoFileName = PR_smprintf(fmt, slapd->slapd_server_root);
-
-	if ((fp = fopen(infoFileName, "w")) == NULL)
-	{
-		ret = -1;
-	}
-	else
-	{
-		fprintf(fp, "url\tldap://%s:%d/",
-				slapd->host, slapd->port);
-    
-		if (base)
-			fprintf(fp, "%s", base);
-
-		fprintf(fp, "\n");
-
-		fprintf(fp, "admnm\t%s\n", admnm);
-
-		fclose(fp);
-	}
-  
-	PR_smprintf_free(infoFileName);
-
-	return ret;
-}
-
 #ifdef TEST_CONFIG
 int
 config_configEntry(LDAP* connection, QUERY_VARS* query)
@@ -1630,12 +1597,6 @@
 												value_hostPreferencesOU, 0,
 												0, 0, 0);
 		}
-
-		/*
-		** Write the ldap.info file and the SuiteSpot.ldif file
-		*/
-
-		write_ldap_info(slapd, query->suffix, query->ssAdmID);
 	}
 
 #ifdef TEST_CONFIG


Index: create_instance.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/create_instance.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -r1.57 -r1.58
--- create_instance.c	7 Jun 2007 21:23:54 -0000	1.57
+++ create_instance.c	7 Jun 2007 22:40:14 -0000	1.58
@@ -144,7 +144,6 @@
 static char *ds_gen_gw_conf(char *sroot, char *cs_path, server_config_s *cf, int conf_type);
 static char *install_ds(char *sroot, server_config_s *cf, char *param_name);
 
-static int write_ldap_info(char *slapd_server_root, server_config_s *cf);
 #if defined (BUILD_PRESENCE)
 static char *gen_presence_init_script(char *sroot, server_config_s *cf, 
                                          char *cs_path);
@@ -4123,9 +4122,6 @@
         }
     }
 
-    /* write ldap.conf */
-    write_ldap_info( sroot, cf );
-
 #ifdef XP_UNIX
     ds_become_localuser_name (cf->servuser);
 #endif
@@ -4143,6 +4139,17 @@
     }
 #endif /* XP_WIN32 */
 
+    /* if an already hashed password is given, we cannot do the configure_suitespot()
+       stuff below, because that requires the clear text password in order to
+       bind to the server.  This also means that default entries and default
+       acis will not be added to the server.
+    */
+    if (cf->rootpw == cf->roothashedpw) {
+        if (status)
+            return make_error ("Could not configure server (%d).", status);
+        return NULL;
+    }
+
     memset( &query_vars, 0, sizeof(query_vars) );
     if (!cf->use_existing_user_ds)
         query_vars.suffix = create_instance_strdup( cf->suffix );
@@ -4199,48 +4206,6 @@
     return(NULL);
 }
 
-/* write_ldap_info() : writes ldap.conf */
-
-static int
-write_ldap_info( char *slapd_server_root, server_config_s *cf)
-{
-    FILE* fp;
-    int ret = 0;
-
-    char* fmt = "%s/shared/config/ldap.conf";
-    char* infoFileName;
-
-    if (!slapd_server_root) {
-      return -1;
-    }
-    
-    infoFileName = PR_smprintf(fmt, slapd_server_root);
-
-    if ((fp = fopen(infoFileName, "w")) == NULL)
-    {
-        ret = -1;
-    }
-    else
-    {
-        fprintf(fp, "url\tldap://%s:%d/",
-                cf->servname, atoi(cf->servport));
-    
-        if (cf->suffix)
-            fprintf(fp, "%s", cf->suffix);
-
-        fprintf(fp, "\n");
-        
-        if (cf->cfg_sspt_uid) {
-            fprintf(fp, "admnm\t%s\n", cf->cfg_sspt_uid);
-        }
-
-        fclose(fp);
-    }
-    PR_smprintf_free(infoFileName);
-
-    return ret;
-}
-
 /* ----------- Create a new server from configuration variables ----------- */
 
 
@@ -4542,8 +4507,17 @@
 
             cf->rootpw = pw1;
         }
-        /* Encode the password in SSHA by default */
-        cf->roothashedpw = (char *)ds_salted_sha1_pw_enc (cf->rootpw);
+        if (strchr(cf->rootpw, '}') &&
+            (!PL_strncasecmp(cf->rootpw, "{SHA", 4) ||
+             !PL_strncasecmp(cf->rootpw, "{SSHA", 5) ||
+             !PL_strncasecmp(cf->rootpw, "{CRYPT}", 7) ||
+             !PL_strncasecmp(cf->rootpw, "{MD5}", 5))) {
+            /* assume the password is already hashed */
+            cf->roothashedpw = cf->rootpw;
+        } else { /* assume cleartext password */
+            /* Encode the password in SSHA by default */
+            cf->roothashedpw = (char *)ds_salted_sha1_pw_enc (cf->rootpw);
+        }
     }
 
     cf->admin_domain = ds_a_get_cgi_var("admin_domain", NULL, NULL);
@@ -4555,7 +4529,7 @@
     }
 
     if ((temp = ds_a_get_cgi_var("use_existing_user_ds", NULL, NULL))) {
-        cf->use_existing_config_ds = atoi(temp);
+        cf->use_existing_user_ds = atoi(temp);
     } else {
         cf->use_existing_user_ds = 0; /* we are creating it */
     }


Index: ds_newinst.pl.in
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/ds_newinst.pl.in,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ds_newinst.pl.in	7 Jun 2007 21:23:54 -0000	1.6
+++ ds_newinst.pl.in	7 Jun 2007 22:40:14 -0000	1.7
@@ -35,6 +35,7 @@
 # Copyright (C) 2005 Red Hat, Inc.
 # All rights reserved.
 # END COPYRIGHT BLOCK
+use Net::Domain qw(hostfqdn);
 use IPC::Open2;
 use Symbol;
 use CGI::Util qw(escape);
@@ -43,9 +44,28 @@
 
 sub usage {
 	my $msg = shift;
-	print "Error: $msg\n";
-	print "Usage: $0 [-|filename.inf]\n";
-	print "Use - to read from stdin\n";
+    print <<EOF;
+Error: $msg
+Usage: $0 [-|filename.inf] [args]
+The filename, if any, should be specified first.  After the filename, other args
+can be provided to override settings in the provided file in this format:
+    section.param=value
+e.g.
+    General.FullMachineName=foo.example.com
+or
+    "slapd.Suffix=dc=example, dc=com"
+
+So, for example, if you use
+    $0 filename.inf General.FullMachineName=bar.example.com
+And your filename.inf file has
+    [General]
+    FullMachineName= foo.example.com
+$0 will use bar.example.com for FullMachineName since that was the one passed on the command line
+
+$0 will attempt to generate reasonable default values for some of the parameters, but there are a couple that must be specified:
+    slapd.ServerPort slapd.RootDNPwd
+Also General.SuiteSpotUserID must be specified if running as root.  If not running as root, the uid of the user will be used.
+EOF
 	exit 1
 }
 
@@ -69,7 +89,7 @@
 
 # fakes out the ds_newinst program into thinking it is getting cgi input
 sub cgiFake {
-  my ($sroot, $verbose, $prog, $args) = @_;
+  my ($verbose, $prog, $args) = @_;
   # construct content string
   my ($content, $length) = &getCgiContentAndLength($args);
 
@@ -87,9 +107,12 @@
   chdir $dir;
   my $input = gensym();
   my $output = gensym();
+  # make sure the child exit code is reset before starting the fake
+  # cgi program
+  $? = 0;
   my $pid = open2($input, $output, "./$exe");
   sleep(1); # allow prog to init stdin read buffers
-  print $output $content, "\n";
+  print $output $content;
   close $output;
 
   if ($?) {
@@ -136,48 +159,81 @@
 	$dest->{$dkey} = $source->{$ssec}->{$skey};
 }
 
-my $filename = $ARGV[0];
-usage("$filename not found") if ($filename ne "-" && ! -f $filename);
+sub readInfFile {
+    my $filename = shift;
+    my $fh;
+    if ($filename eq "-") {
+        $fh = \*STDIN;
+    } else {
+        open(IN, $filename) or usage("could not open file $filename: $!");
+        $fh = \*IN;
+    }
+    while (<$fh>) {
+        # e.g. [General]
+        if (/^\[(.*?)\]/) {
+            $curSection = $1;
+        } elsif (/^\s*$/) {
+            next; # skip blank lines
+        } elsif (/^\s*\#/) {
+            next; # skip comment lines
+        } elsif (/^\s*(.*?)\s*=\s*(.*?)\s*$/) {
+            $table{$curSection}->{$1} = $2;
+        }
+    }
+    if ($filename ne "-") {
+        close IN;
+    }
+}
+
+usage("No arguments given") if (!@ARGV);
+
+# process command line arguments
+for (@ARGV) {
+    if (/^(\w+).(\w+)=(.*)$/) { # e.g. section.param=value
+        $table{$1}->{$2} = $3;
+    } else { # file?
+        readInfFile($_);
+    }
+}
 
-my $curSection;
-# each key in the table is a section name
-# the value is a hash ref of the items in that section
-#   in that hash ref, each key is the config param name,
-#   and the value is the config param value
-my %table = ();
-
-my $fh;
-if ($filename eq "-") {
-    $fh = \*STDIN;
-} else {
-    open(IN, $filename);
-    $fh = \*IN;
+#printhash (\%table);
+
+# set default values
+if (!$table{General}->{FullMachineName}) {
+    $table{General}->{FullMachineName} = hostfqdn;
 }
-while (<$fh>) {
-	# e.g. [General]
-	if (/^\[(.*?)\]/) {
-		$curSection = $1;
-	} elsif (/^\s*$/) {
-		next; # skip blank lines
-	} elsif (/^\s*\#/) {
-		next; # skip comment lines
-	} elsif (/^\s*(.*?)\s*=\s*(.*?)\s*$/) {
-		$table{$curSection}->{$1} = $2;
-	}
+
+if (!$table{General}->{SuiteSpotUserID}) {
+    if ($> != 0) { # if not root, use the user's uid
+        $table{General}->{SuiteSpotUserID} = getlogin;
+    }
+    # otherwise, the uid must be specified
 }
-if ($filename ne "-") {
-    close IN;
+
+if (!$table{slapd}->{RootDN}) {
+    $table{slapd}->{RootDN} = "cn=Directory Manager";
 }
 
-#printhash (\%table);
+if (!$table{slapd}->{Suffix}) {
+    my $suffix = $table{General}->{FullMachineName};
+    # convert fqdn to dc= domain components
+    $suffix = "dc=$suffix";
+    $suffix =~ s/\./, dc=/g;
+    $table{slapd}->{Suffix} = $suffix;
+}
+
+if (!$table{slapd}->{ServerIdentifier}) {
+    my $servid = $table{General}->{FullMachineName};
+    # strip out the leftmost domain component
+    $servid =~ s/\..*$//;
+    $table{slapd}->{ServerIdentifier} = $servid;
+}
 
 # next, construct a hash table with our arguments
 
 my %cgiargs = ();
 my $package_name = "@package_name@";
-
 # the following items are always required
-addAndCheck(\%cgiargs, "sroot", \%table, "General", "ServerRoot");
 addAndCheck(\%cgiargs, "servname", \%table, "General", "FullMachineName");
 addAndCheck(\%cgiargs, "servuser", \%table, "General", "SuiteSpotUserID");
 addAndCheck(\%cgiargs, "rootdn", \%table, "slapd", "RootDN");
@@ -185,6 +241,12 @@
 addAndCheck(\%cgiargs, "servid", \%table, "slapd", "ServerIdentifier");
 addAndCheck(\%cgiargs, "suffix", \%table, "slapd", "Suffix");
 
+if (defined($table{"General"}->{"ServerRoot"})) {
+    $cgiargs{"sroot"} = $table{"General"}->{"ServerRoot"};
+} else {
+    $cgiargs{"sroot"} = '@serverdir@';
+}
+
 # either servport or ldapifilepath must be specified - the server must
 # listen to something . . .
 my $canlisten = 0;
@@ -200,7 +262,7 @@
     $cgiargs{"ldapifilepath"} = $table{"slapd"}->{"ldapifilepath"};
 }
 if (! $canlisten) {
-    usage("Either ServerPort or ldapifilepath must be specified in the slapd section of $filename");
+    usage("Either ServerPort or ldapifilepath must be specified in the slapd section");
 }
 
 # the following items are optional
@@ -227,6 +289,15 @@
 } else {
     $cgiargs{"config_dir"} = "@instconfigdir@/slapd-" . $table{"slapd"}->{"ServerIdentifier"};
 }
+
+# check to see if this instance already exists
+if (-d $cgiargs{"config_dir"}) {
+    print STDERR "Error: the server already exists at ", $cgiargs{"config_dir"}, "\n";
+    print STDERR "Please remove it first if you really want to recreate it,\n";
+    print STDERR "or use a different ServerIdentifier to create another instance.\n";
+    exit 1;
+}
+
 # port number for Admin Server - used to configure some web apps
 $cgiargs{adminport} = $table{admin}->{Port};
 
@@ -300,15 +371,12 @@
     # server-side default is on
 }
 
-my $sroot = $cgiargs{sroot};
-
 my $prog = "@bindir@/ds_newinst";
 if (! -x $prog) {
     $prog = "@libdir@/$package_name/ds_newinst";
 }
 
-my $rc = &cgiFake($sroot, $verbose,
-				  $prog, \%cgiargs);
+my $rc = &cgiFake($verbose, $prog, \%cgiargs);
 
 if (!$rc) {
 	print "Success!  Your new directory server instance was created\n";
@@ -316,6 +384,8 @@
 	print "Error: Could not create new directory server instance\n";
 }
 
+exit $rc;
+
 sub printhash {
 	my $table = shift;
 




More information about the Fedora-directory-commits mailing list