Mercurial > trustbridge
comparison cinst/nssstore_linux.c @ 310:f758460ca437
Merged
author | Sascha Wilde <wilde@intevation.de> |
---|---|
date | Fri, 04 Apr 2014 09:54:19 +0200 |
parents | 4a3febc6d806 |
children | 824ef90a6721 |
comparison
equal
deleted
inserted
replaced
309:fa37384b86b6 | 310:f758460ca437 |
---|---|
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\n", 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 |