[PATCH] (issue86) Install into default directories on Linux

Wald Commits scm-commit at wald.intevation.org
Fri Aug 29 13:00:06 CEST 2014


# HG changeset patch
# User Andre Heinecke <andre.heinecke at intevation.de>
# Date 1409309984 -7200
# Node ID b3695a3399de9f9a0e51f5650a3b55fb1e9dea54
# Parent  cbd32175c56c57dc4f3105bcb4d18db64fb303a9
(issue86) Install into default directories on Linux

    If the mozilla process is now started as root it will
    try to write into the default directories for NSS Shared
    and mozilla / thunderbird profiles.

    Cinst will now start the mozilla process once as root.

diff -r cbd32175c56c -r b3695a3399de cinst/mozilla.c
--- a/cinst/mozilla.c	Fri Aug 29 10:26:10 2014 +0200
+++ b/cinst/mozilla.c	Fri Aug 29 12:59:44 2014 +0200
@@ -26,6 +26,10 @@
  * This tool tries to find all NSS databases the user has
  * access to and to execute the instructions on all of them.
  *
+ * If the tool is executed with a UID of 0 or with admin privileges under
+ * windows it will not look into the user directories but instead try
+ * to write the system wide defaults.
+ *
  * If there are other processes accessing the databases the caller
  * has to ensure that those are terminated before this process is
  * executed.
@@ -44,7 +48,7 @@
  */
 
 /**
- * @brief Needs to eb defined to get strnlen()
+ * @brief Needs to be defined to get strnlen()
  */
 #define _POSIX_C_SOURCE 200809L
 
@@ -71,12 +75,17 @@
 #include "portpath.h"
 #include "strhelp.h"
 #include "nss-secitemlist.h"
+#include "util.h"
 
 #ifndef _WIN32
 #define CONFDIRS ".mozilla", ".thunderbird"
+/* Default installation directory of ubuntu 14.4 is respected */
+#define MOZILLA_DEFAULTS "/etc/thunderbird", "/etc/firefox"
 #define NSSSHARED ".pki/nssdb"
+#define NSSSHARED_GLOBAL "/etc/pki/nssdb"
 #define TARGET_LINUX 1
 #else
+#define MOZILLA_DEFAULTS 0
 #define CONFDIRS "Mozilla", "Thunderbird"
 #define NSSSHARED ""
 #define TARGET_LINUX 0
@@ -199,7 +208,7 @@
                   if (relative_path)
                     xasprintf(&path, "%s/%s", inifile_dirname, value);
                   else
-                    xasprintf(&path, "%s", value); /* FIXME: LOOKS STUPID! */
+                    xasprintf(&path, "%s", value);
                   if ((fqpath = port_realpath(path)) != NULL)
                     {
                       DEBUGPRINTF("Found profile path: '%s'\n", fqpath);
@@ -294,6 +303,71 @@
 }
 
 /**
+ * @brief Collect the default profile directories for mozilla software
+ *
+ * If the default directory is found but not the profiles subdirectory
+ * this will create the profiles subdirectory.
+ *
+ * @return NULL terminated array of strings containing the absolute path
+ * to the default profile directories. Needs to be freed by the caller.
+ */
+static char**
+get_default_profile_dirs()
+{
+  char **retval = NULL;
+
+  const char *confdirs[] = { MOZILLA_DEFAULTS, NULL };
+
+  for (int i=0; confdirs[i] != NULL; i++)
+    {
+      char * realpath = port_realpath(confdirs[i]);
+      char * profile_dir = NULL;
+      if (realpath == NULL)
+        {
+          DEBUGPRINTF ("Did not find directory: '%s'\n", confdirs[i]);
+          continue;
+        }
+      xasprintf(&profile_dir, "%s/profile", realpath);
+      if (port_isdir(profile_dir))
+        {
+          DEBUGPRINTF("Found default directory: '%s'\n", profile_dir);
+          /* All is well */
+          strv_append (&retval, profile_dir, strlen(profile_dir));
+          xfree(profile_dir);
+          profile_dir = NULL;
+          continue;
+        }
+      else
+        {
+          /* Create the directory */
+          if (port_fileexits(profile_dir))
+            {
+              DEBUGPRINTF ("Path: '%s' is not a directory but it exists. Skipping.\n",
+                           profile_dir);
+              xfree(profile_dir);
+              profile_dir = NULL;
+              continue;
+            }
+          else
+            {
+              /* Lets create it */
+              if (!port_mkdir(profile_dir))
+                {
+                  ERRORPRINTF ("Failed to create directory: '%s'\n", profile_dir);
+                  xfree(profile_dir);
+                  profile_dir = NULL;
+                  continue;
+                }
+              strv_append (&retval, profile_dir, strlen(profile_dir));
+              xfree(profile_dir);
+              profile_dir = NULL;
+            }
+        }
+    }
+  return retval;
+}
+
+/**
  * @brief Collect all mozilla profile directories of current user.
  * @return NULL terminated array of strings containing the absolute
  * path of the profile directories.  The array needs to be freed by the
@@ -304,6 +378,24 @@
 {
   char **mozinis, **pdirs;
   char **alldirs = NULL;
+
+  if (is_elevated())
+    {
+#ifndef _WIN32
+      /* NSS Shared db does not exist under windows. */
+      strv_append(&alldirs, NSSSHARED_GLOBAL, strlen(NSSSHARED_GLOBAL));
+#endif
+      pdirs = get_default_profile_dirs();
+      if (pdirs != NULL)
+        {
+          for (int i=0; pdirs[i] != NULL; i++)
+            {
+              strv_append(&alldirs, pdirs[i], strlen(pdirs[i]));
+            }
+          strv_free(pdirs);
+        }
+      return alldirs;
+    }
   /* Search Mozilla/Firefox/Thunderbird profiles */
   if ((mozinis = get_profile_inis()) != NULL)
     {
diff -r cbd32175c56c -r b3695a3399de cinst/nssstore_linux.c
--- a/cinst/nssstore_linux.c	Fri Aug 29 10:26:10 2014 +0200
+++ b/cinst/nssstore_linux.c	Fri Aug 29 12:59:44 2014 +0200
@@ -201,18 +201,19 @@
 {
   struct passwd *usr_it = NULL;
   uid_t my_uid = geteuid();
+  pid_t childprocess = -1;
+  int status = -1;
 
   if (my_uid != 0)
     {
       /* Running as a user */
       char *homedir = getenv ("HOME");
-      pid_t childprocess = -1; /* Only one child for single user installation */
-      int status = -1;
       if (!homedir)
         {
           ERRORPRINTF ("Failed to find home directory\n");
         }
 
+      /* Only one child for single user installation */
       childprocess = start_procces_for_user (to_install, to_remove,
                                              my_uid, getgid(), homedir);
 
@@ -232,6 +233,23 @@
       return 0;
     }
 
+  /* Start once as root to install in the system default directories. */
+  childprocess = start_procces_for_user (to_install, to_remove,
+                                         my_uid, getgid(), getenv ("HOME"));
+  if (childprocess == -1)
+    {
+      ERRORPRINTF ("Failed to start default profile installation!\n");
+      return -1;
+    }
+
+  /* Wait until the default profile directories are done. */
+  childprocess = waitpid (childprocess, &status, 0);
+  if (childprocess == -1 || !WIFEXITED(status))
+    {
+      ERRORPRINTF ("Child process did not finish.\n");
+      return -1;
+    }
+
   setpwent();
 
   while ((usr_it = getpwent ()) != NULL)
diff -r cbd32175c56c -r b3695a3399de common/portpath.c
--- a/common/portpath.c	Fri Aug 29 10:26:10 2014 +0200
+++ b/common/portpath.c	Fri Aug 29 12:59:44 2014 +0200
@@ -36,8 +36,20 @@
 #endif
 }
 
+bool
+port_mkdir(const char *path)
+{
+#ifndef _WIN32
+  return mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0;
+#else
+  /* TODO */
+  printf("Should make path: %s\n", path);
+  return false;
+#endif
+}
+
 char *
-port_realpath(char *path)
+port_realpath(const char *path)
 {
 #ifndef _WIN32
   return realpath(path, NULL);
diff -r cbd32175c56c -r b3695a3399de common/portpath.h
--- a/common/portpath.h	Fri Aug 29 10:26:10 2014 +0200
+++ b/common/portpath.h	Fri Aug 29 12:59:44 2014 +0200
@@ -35,7 +35,7 @@
  * @param[in] path the original pathname
  * @returns a pointer to the resolved path or NULL on error
  */
-char *port_realpath(char *path);
+char *port_realpath(const char *path);
 
 /**
  * @brief test if a file exists
@@ -55,4 +55,14 @@
  */
 bool port_isdir(char *path);
 
+/**
+ * @brief create a directory
+ * @details uses a platform specific mkdir / access rights setup
+ * to create a directory that is world readable and
+ * writable by the current user / group
+ * @param[in] path the path to the directory
+ * @returns true if the directory was created
+ */
+bool port_mkdir(const char *path);
+
 #endif


More information about the Trustbridge-commits mailing list