annotate cinst/nssstore_linux.c @ 633:6c090638b2b4

Use static buffer for module file name. According to the msdn examle the return value of getmodulefilename should be used to indicate success and not the size. And according to comments on that function on Windows 8.1 it does not return the needed size. So better be more robust and just use max_path as a limit.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 23 Jun 2014 15:29:48 +0200
parents 214bf504c54f
children e41a2537b84d
rev   line source
404
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 384
diff changeset
1 /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 384
diff changeset
2 * Software engineering by Intevation GmbH
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 384
diff changeset
3 *
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 384
diff changeset
4 * This file is Free Software under the GNU GPL (v>=2)
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 384
diff changeset
5 * and comes with ABSOLUTELY NO WARRANTY!
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 384
diff changeset
6 * See LICENSE.txt for details.
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 384
diff changeset
7 */
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
8 #ifndef WIN32
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
9
321
824ef90a6721 Move is_elevated into common/util.c file for better reuse
Andre Heinecke <aheinecke@intevation.de>
parents: 305
diff changeset
10 /* @file
824ef90a6721 Move is_elevated into common/util.c file for better reuse
Andre Heinecke <aheinecke@intevation.de>
parents: 305
diff changeset
11 @brief Linux implementation of nssstore process control.
824ef90a6721 Move is_elevated into common/util.c file for better reuse
Andre Heinecke <aheinecke@intevation.de>
parents: 305
diff changeset
12 */
824ef90a6721 Move is_elevated into common/util.c file for better reuse
Andre Heinecke <aheinecke@intevation.de>
parents: 305
diff changeset
13
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
14 #include <stdbool.h>
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
15 #include <stdio.h>
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
16 #include <unistd.h>
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
17 #include <sys/types.h>
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
18 #include <sys/wait.h>
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
19 #include <string.h>
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
20 #include <stdlib.h>
383
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
21 #include <limits.h>
439
c88090a15ae4 Fix cinstprocesstest for new arguments. Handle errno on write errors
Andre Heinecke <aheinecke@intevation.de>
parents: 404
diff changeset
22 #include <errno.h>
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
23
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
24 #include "nssstore.h"
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
25 #include "logging.h"
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
26 #include "strhelp.h"
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
27
383
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
28 #define NSS_PROCESS_NAME "mozilla"
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
29
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
30 /**@brief get the current path of the executable
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
31 *
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
32 * Looks up the current executables directory. The caller
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
33 * has to free the return value.
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
34 *
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
35 * The returned value includes the last /
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
36 *
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
37 * @returns the absolute directory of the currently executed executable or NULL
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
38 */
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
39 char *
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
40 get_exe_dir()
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
41 {
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
42 char *retval = NULL,
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
43 *p = NULL,
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
44 buf[PATH_MAX];
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
45 ssize_t ret;
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
46 size_t path_len = 0;
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
47
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
48 ret = readlink ("/proc/self/exe", buf, PATH_MAX);
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
49 if (ret <= 0)
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
50 {
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
51 ERRORPRINTF ("readlink failed\n");
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
52 return NULL;
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
53 }
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
54
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
55 buf[ret] = '\0';
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
56
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
57 /* cut off the filename */
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
58 p = strrchr (buf, '/');
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
59 if (p == NULL)
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
60 {
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
61 ERRORPRINTF ("No filename found.\n");
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
62 return NULL;
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
63 }
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
64 *(p + 1) = '\0';
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
65
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
66 path_len = strlen (buf);
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
67 retval = xmalloc (path_len + 1);
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
68 strncpy (retval, buf, path_len);
476
e8d761c2d2d1 Make sure that retval is terminated
Andre Heinecke <aheinecke@intevation.de>
parents: 439
diff changeset
69 retval[path_len] = '\0';
383
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
70
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
71 return retval;
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
72 }
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
73
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
74 /**@brief Start the process to install / remove
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
75 *
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
76 * This forks the process and executes the NSS installation
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
77 * process. It also writes the Instructions to that process.
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
78 *
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
79 * @param [in] to_install strv of DER encoded certificates to be added.
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
80 * @param [in] to_remove strv of DER encoded certificates to be remvoed.
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
81 * @param [in] uid_t uid of the user to install certificates for.
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
82 * @param [in] gid_t the gid of the user to install certificates for.
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
83 * @param [in] homedir the homedir of the user.
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
84 *
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
85 * @returns childs pid on success. -1 on failure
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
86 */
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
87 static int
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
88 start_procces_for_user (char **to_install, char **to_remove,
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
89 uid_t uid, gid_t gid, char *homedir)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
90 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
91 int pipe_fd[2];
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
92 pid_t pid = 0;
383
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
93 char *argv[2] = {NULL, NULL},
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
94 *envp[2] = {NULL, NULL},
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
95 *inst_dir = NULL;
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
96 size_t homedir_len = 0,
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
97 exe_path_len = 0;
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
98 int ret = -1,
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
99 i = 0;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
100 FILE *stream = NULL;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
101 bool success = false;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
102
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
103 if (homedir == NULL)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
104 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
105 ERRORPRINTF ("Invalid call to start_process_for_user\n");
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
106 return -1;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
107 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
108
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
109 homedir_len = strlen (homedir);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
110
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
111 /* Allocate space for HOME=homedir\0 */
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
112 envp[0] = xmalloc (homedir_len + 6);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
113 envp[1] = NULL;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
114
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
115 ret = snprintf (envp[0], homedir_len + 6, "HOME=%s", homedir);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
116
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
117 if (ret < 0 || (size_t) ret != homedir_len + 5)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
118 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
119 ERRORPRINTF ("Error setting home env variable.\n");
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
120 xfree (envp[0]);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
121 return -1;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
122 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
123
383
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
124 /* Set up the file name of the installer process */
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
125 inst_dir = get_exe_dir();
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
126 if (inst_dir == NULL)
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
127 {
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
128 ERRORPRINTF ("Failed to find installation directory.\n");
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
129 xfree (envp[0]);
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
130 return -1;
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
131 }
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
132
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
133 exe_path_len = strlen(inst_dir) + strlen(NSS_PROCESS_NAME);
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
134 argv[0] = xmalloc (exe_path_len + 1);
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
135
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
136 ret = snprintf(argv[0], exe_path_len + 1, "%s%s", inst_dir, NSS_PROCESS_NAME);
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
137 if (ret < 0 || (size_t) ret != exe_path_len)
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
138 {
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
139 ERRORPRINTF ("Error setting executable variable.\n");
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
140 xfree (argv[0]);
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
141 return -1;
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
142 }
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
143
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
144 if (pipe (pipe_fd))
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
145 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
146 ERRORPRINTF ("Failed to create pipe.\n");
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
147 return -1;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
148 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
149
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
150 pid = fork();
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
151
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
152 if (pid == (pid_t) -1)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
153 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
154 ERRORPRINTF ("Failed to fork child.\n");
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
155 return -1;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
156 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
157
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
158 if (pid == (pid_t) 0)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
159 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
160 /* Drop privileges */
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
161 if (setuid (uid) || setgid (gid))
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
162 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
163 exit(-1);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
164 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
165
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
166 close (pipe_fd[1]);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
167 dup2 (pipe_fd[0], 0);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
168 close (pipe_fd[0]);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
169 /* TODO find path based on current executable */
383
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
170 execve (argv[0], argv, envp);
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
171 exit (127);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
172 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
173
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
174 close (pipe_fd[0]);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
175 stream = fdopen(pipe_fd[1], "w");
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
176 if (stream == NULL)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
177 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
178 ERRORPRINTF ("Failed to open pipe for writing\n");
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
179 goto done;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
180 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
181
384
638db75f0fdf Ignore sigpipe if the child closed the channel or there is an error
Andre Heinecke <andre.heinecke@intevation.de>
parents: 383
diff changeset
182 /* The NSS installer may exit on error before we are done
638db75f0fdf Ignore sigpipe if the child closed the channel or there is an error
Andre Heinecke <andre.heinecke@intevation.de>
parents: 383
diff changeset
183 * telling it what to do. We want to handle that rather
638db75f0fdf Ignore sigpipe if the child closed the channel or there is an error
Andre Heinecke <andre.heinecke@intevation.de>
parents: 383
diff changeset
184 * then die unexpectedly. */
638db75f0fdf Ignore sigpipe if the child closed the channel or there is an error
Andre Heinecke <andre.heinecke@intevation.de>
parents: 383
diff changeset
185 signal(SIGPIPE, SIG_IGN);
638db75f0fdf Ignore sigpipe if the child closed the channel or there is an error
Andre Heinecke <andre.heinecke@intevation.de>
parents: 383
diff changeset
186
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
187 /* Send the instructions */
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
188 for (i = 0; to_install && to_install[i]; i++)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
189 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
190 if (fprintf (stream, "I:%s\n", to_install[i]) <= 3)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
191 {
478
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
192 int err = errno;
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
193 ERRORPRINTF ("Write failed: %s \n", strerror(err));
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
194 if (err == 32)
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
195 {
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
196 /* Broken pipe is expected if there are no NSS stores
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
197 to be found the process just exits. That's ok */
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
198 success = true;
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
199 }
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
200 goto done;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
201 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
202 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
203
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
204 for (i = 0; to_remove && to_remove[i]; i++)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
205 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
206 if (fprintf (stream, "R:%s\n", to_remove[i]) <= 3)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
207 {
478
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
208 int err = errno;
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
209 ERRORPRINTF ("Write failed: %s \n", strerror(err));
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
210 if (err == 32)
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
211 {
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
212 /* Broken pipe is expected if there are no NSS stores
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
213 to be found the process just exits. That's ok */
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
214 success = true;
214bf504c54f Handle broken pipe as it is expected behavior
Andre Heinecke <aheinecke@intevation.de>
parents: 476
diff changeset
215 }
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
216 goto done;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
217 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
218 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
219
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
220 success = true;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
221
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
222 done:
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
223 if (stream) {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
224 fclose (stream);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
225 }
383
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
226 xfree (argv[0]);
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
227 xfree (envp[0]);
383
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
228 close (pipe_fd[0]);
5eb7ee4ee819 Look up executable name based on /proc/self/exe
Andre Heinecke <andre.heinecke@intevation.de>
parents: 321
diff changeset
229 close (pipe_fd[1]);
302
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
230
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
231 if (success)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
232 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
233 return pid;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
234 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
235 return -1;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
236 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
237
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
238 int
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
239 write_stores_nss (char **to_install, char **to_remove)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
240 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
241 uid_t my_uid = getuid();
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
242
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
243 if (my_uid != 0)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
244 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
245 /* Running as a user */
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
246 char *homedir = getenv ("HOME");
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
247 pid_t childprocess = -1; /* Only one child for single user installation */
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
248 int status = -1;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
249 if (!homedir)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
250 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
251 ERRORPRINTF ("Failed to find home directory\n");
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
252 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
253
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
254 childprocess = start_procces_for_user (to_install, to_remove,
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
255 my_uid, getgid(), homedir);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
256
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
257 if (childprocess == -1)
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
258 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
259 ERRORPRINTF ("Failed to start childprocess!\n");
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
260 return -1;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
261 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
262
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
263 childprocess = waitpid (childprocess, &status, 0);
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
264 if (childprocess == -1 || !WIFEXITED(status))
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
265 {
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
266 ERRORPRINTF ("Waitpid failed.\n");
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
267 return -1;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
268 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
269
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
270 return 0;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
271 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
272 printf ("Installation as root is not yet implemented\n");
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
273 /* TODO root parse /etc/passwd for users with a home directory */
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
274 return 0;
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
275 }
fac7e1b0e558 Add nss store calling function and use it in cinst
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
276 #endif

http://wald.intevation.org/projects/trustbridge/