comparison cinst/nssstore_linux.c @ 302:fac7e1b0e558

Add nss store calling function and use it in cinst
author Andre Heinecke <andre.heinecke@intevation.de>
date Thu, 03 Apr 2014 14:28:23 +0200
parents
children 4a3febc6d806
comparison
equal deleted inserted replaced
301:aec9008c3b30 302:fac7e1b0e558
1 #ifndef WIN32
2
3 #include <stdbool.h>
4 #include <stdio.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 #include <string.h>
9 #include <stdlib.h>
10
11 #include "nssstore.h"
12 #include "logging.h"
13 #include "strhelp.h"
14
15 /**@brief Start the process to install / remove
16 *
17 * This forks the process and executes the NSS installation
18 * process. It also writes the Instructions to that process.
19 *
20 * @param [in] to_install strv of DER encoded certificates to be added.
21 * @param [in] to_remove strv of DER encoded certificates to be remvoed.
22 * @param [in] uid_t uid of the user to install certificates for.
23 * @param [in] gid_t the gid of the user to install certificates for.
24 * @param [in] homedir the homedir of the user.
25 *
26 * @returns childs pid on success. -1 on failure
27 */
28 static int
29 start_procces_for_user (char **to_install, char **to_remove,
30 uid_t uid, gid_t gid, char *homedir)
31 {
32 int pipe_fd[2];
33 pid_t pid = 0;
34 char *argv[] = {"mozilla", NULL},
35 *envp[2];
36 size_t homedir_len = 0;
37 int ret = -1,
38 i = 0;
39 FILE *stream = NULL;
40 bool success = false;
41
42 if (homedir == NULL)
43 {
44 ERRORPRINTF ("Invalid call to start_process_for_user\n");
45 return -1;
46 }
47
48 homedir_len = strlen (homedir);
49
50 /* Allocate space for HOME=homedir\0 */
51 envp[0] = xmalloc (homedir_len + 6);
52 envp[1] = NULL;
53
54 ret = snprintf (envp[0], homedir_len + 6, "HOME=%s", homedir);
55
56 if (ret < 0 || (size_t) ret != homedir_len + 5)
57 {
58 ERRORPRINTF ("Error setting home env variable.\n");
59 xfree (envp[0]);
60 return -1;
61 }
62
63 DEBUGPRINTF ("Home: %s \n", envp[0]);
64
65 if (pipe (pipe_fd))
66 {
67 ERRORPRINTF ("Failed to create pipe.\n");
68 return -1;
69 }
70
71 pid = fork();
72
73 if (pid == (pid_t) -1)
74 {
75 ERRORPRINTF ("Failed to fork child.\n");
76 return -1;
77 }
78
79 if (pid == (pid_t) 0)
80 {
81 /* Drop privileges */
82 if (setuid (uid) || setgid (gid))
83 {
84 exit(-1);
85 }
86
87 close (pipe_fd[1]);
88 dup2 (pipe_fd[0], 0);
89 close (pipe_fd[0]);
90 /* TODO find path based on current executable */
91 execve ("mozilla", argv, envp);
92 exit (127);
93 }
94
95 close (pipe_fd[0]);
96 stream = fdopen(pipe_fd[1], "w");
97 if (stream == NULL)
98 {
99 ERRORPRINTF ("Failed to open pipe for writing\n");
100 goto done;
101 }
102
103 /* Send the instructions */
104 for (i = 0; to_install && to_install[i]; i++)
105 {
106 if (fprintf (stream, "I:%s\n", to_install[i]) <= 3)
107 {
108 ERRORPRINTF ("Write failed \n");
109 goto done;
110 }
111 }
112
113 for (i = 0; to_remove && to_remove[i]; i++)
114 {
115 if (fprintf (stream, "R:%s\n", to_remove[i]) <= 3)
116 {
117 ERRORPRINTF ("Write failed \n");
118 goto done;
119 }
120 }
121
122 success = true;
123
124 done:
125 if (stream) {
126 fclose (stream);
127 }
128 xfree (envp[0]);
129 close(pipe_fd[0]);
130 close(pipe_fd[1]);
131
132 if (success)
133 {
134 return pid;
135 }
136 return -1;
137 }
138
139 int
140 write_stores_nss (char **to_install, char **to_remove)
141 {
142 uid_t my_uid = getuid();
143
144 if (my_uid != 0)
145 {
146 /* Running as a user */
147 char *homedir = getenv ("HOME");
148 pid_t childprocess = -1; /* Only one child for single user installation */
149 int status = -1;
150 if (!homedir)
151 {
152 ERRORPRINTF ("Failed to find home directory\n");
153 }
154
155 childprocess = start_procces_for_user (to_install, to_remove,
156 my_uid, getgid(), homedir);
157
158 if (childprocess == -1)
159 {
160 ERRORPRINTF ("Failed to start childprocess!\n");
161 return -1;
162 }
163
164 childprocess = waitpid (childprocess, &status, 0);
165 if (childprocess == -1 || !WIFEXITED(status))
166 {
167 ERRORPRINTF ("Waitpid failed.\n");
168 return -1;
169 }
170 DEBUGPRINTF ("Child returned status: %i", WEXITSTATUS(status));
171
172 return 0;
173 }
174 printf ("Installation as root is not yet implemented\n");
175 /* TODO root parse /etc/passwd for users with a home directory */
176 return 0;
177 }
178 #endif

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