This source file includes following definitions.
- munge_init
- munge_finalize
- create_cred
- validate_cred
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <src/include/pmix_config.h>
14
15 #include <pmix_common.h>
16
17 #include "src/include/pmix_globals.h"
18 #include "src/util/argv.h"
19 #include "src/util/error.h"
20 #include "src/util/output.h"
21
22 #include <unistd.h>
23 #ifdef HAVE_SYS_TYPES_H
24 #include <sys/types.h>
25 #endif
26 #include <munge.h>
27
28 #include "src/threads/threads.h"
29 #include "src/mca/psec/psec.h"
30 #include "psec_munge.h"
31
32 static pmix_status_t munge_init(void);
33 static void munge_finalize(void);
34 static pmix_status_t create_cred(struct pmix_peer_t *peer,
35 const pmix_info_t directives[], size_t ndirs,
36 pmix_info_t **info, size_t *ninfo,
37 pmix_byte_object_t *cred);
38 static pmix_status_t validate_cred(struct pmix_peer_t *peer,
39 const pmix_info_t directives[], size_t ndirs,
40 pmix_info_t **info, size_t *ninfo,
41 const pmix_byte_object_t *cred);
42
43 pmix_psec_module_t pmix_munge_module = {
44 .name = "munge",
45 .init = munge_init,
46 .finalize = munge_finalize,
47 .create_cred = create_cred,
48 .validate_cred = validate_cred
49 };
50
51 static pmix_lock_t lock;
52 static char *mycred = NULL;
53 static bool initialized = false;
54 static bool refresh = false;
55
56 static pmix_status_t munge_init(void)
57 {
58 int rc;
59
60 pmix_output_verbose(2, pmix_globals.debug_output,
61 "psec: munge init");
62
63 PMIX_CONSTRUCT_LOCK(&lock);
64 lock.active = false;
65
66
67
68
69
70 if (EMUNGE_SUCCESS != (rc = munge_encode(&mycred, NULL, NULL, 0))) {
71 pmix_output_verbose(2, pmix_globals.debug_output,
72 "psec: munge failed to create credential: %s",
73 munge_strerror(rc));
74 return PMIX_ERR_SERVER_NOT_AVAIL;
75 }
76
77 initialized = true;
78
79 return PMIX_SUCCESS;
80 }
81
82 static void munge_finalize(void)
83 {
84 PMIX_ACQUIRE_THREAD(&lock);
85
86 pmix_output_verbose(2, pmix_globals.debug_output,
87 "psec: munge finalize");
88 if (initialized) {
89 if (NULL != mycred) {
90 free(mycred);
91 mycred = NULL;
92 }
93 }
94 PMIX_RELEASE_THREAD(&lock);
95 PMIX_DESTRUCT_LOCK(&lock);
96 }
97
98 static pmix_status_t create_cred(struct pmix_peer_t *peer,
99 const pmix_info_t directives[], size_t ndirs,
100 pmix_info_t **info, size_t *ninfo,
101 pmix_byte_object_t *cred)
102 {
103 int rc;
104 bool takeus;
105 char **types;
106 size_t n, m;
107
108 PMIX_ACQUIRE_THREAD(&lock);
109
110 pmix_output_verbose(2, pmix_globals.debug_output,
111 "psec: munge create_cred");
112
113
114 PMIX_BYTE_OBJECT_CONSTRUCT(cred);
115
116
117
118 if (NULL != directives && 0 < ndirs) {
119 for (n=0; n < ndirs; n++) {
120 if (0 == strncmp(directives[n].key, PMIX_CRED_TYPE, PMIX_MAX_KEYLEN)) {
121
122 types = pmix_argv_split(directives[n].value.data.string, ',');
123 takeus = false;
124 for (m=0; NULL != types[m]; m++) {
125 if (0 == strcmp(types[m], "munge")) {
126
127 takeus = true;
128 break;
129 }
130 }
131 pmix_argv_free(types);
132 if (!takeus) {
133 PMIX_RELEASE_THREAD(&lock);
134 return PMIX_ERR_NOT_SUPPORTED;
135 }
136 }
137 }
138 }
139
140 if (initialized) {
141 if (!refresh) {
142 refresh = true;
143 cred->bytes = strdup(mycred);
144 cred->size = strlen(mycred) + 1;
145 } else {
146
147
148 if (NULL != mycred) {
149 free(mycred);
150 }
151 if (EMUNGE_SUCCESS != (rc = munge_encode(&mycred, NULL, NULL, 0))) {
152 pmix_output_verbose(2, pmix_globals.debug_output,
153 "psec: munge failed to create credential: %s",
154 munge_strerror(rc));
155 PMIX_RELEASE_THREAD(&lock);
156 return PMIX_ERR_NOT_SUPPORTED;
157 }
158 cred->bytes = strdup(mycred);
159 cred->size = strlen(mycred) + 1;
160 }
161 }
162 if (NULL != info) {
163
164 PMIX_INFO_CREATE(*info, 1);
165 if (NULL == *info) {
166 PMIX_RELEASE_THREAD(&lock);
167 return PMIX_ERR_NOMEM;
168 }
169 *ninfo = 1;
170 PMIX_INFO_LOAD(info[0], PMIX_CRED_TYPE, "munge", PMIX_STRING);
171 }
172 PMIX_RELEASE_THREAD(&lock);
173 return PMIX_SUCCESS;
174 }
175
176 static pmix_status_t validate_cred(struct pmix_peer_t *peer,
177 const pmix_info_t directives[], size_t ndirs,
178 pmix_info_t **info, size_t *ninfo,
179 const pmix_byte_object_t *cred)
180 {
181 pmix_peer_t *pr = (pmix_peer_t*)peer;
182 uid_t euid;
183 gid_t egid;
184 munge_err_t rc;
185 bool takeus;
186 char **types;
187 size_t n, m;
188 uint32_t u32;
189
190 pmix_output_verbose(2, pmix_globals.debug_output,
191 "psec: munge validate_cred %s",
192 (NULL == cred) ? "NULL" : "NON-NULL");
193
194
195
196 if (NULL != directives && 0 < ndirs) {
197 for (n=0; n < ndirs; n++) {
198 if (0 == strncmp(directives[n].key, PMIX_CRED_TYPE, PMIX_MAX_KEYLEN)) {
199
200 types = pmix_argv_split(directives[n].value.data.string, ',');
201 takeus = false;
202 for (m=0; NULL != types[m]; m++) {
203 if (0 == strcmp(types[m], "munge")) {
204
205 takeus = true;
206 break;
207 }
208 }
209 pmix_argv_free(types);
210 if (!takeus) {
211 return PMIX_ERR_NOT_SUPPORTED;
212 }
213 }
214 }
215 }
216
217
218 if (EMUNGE_SUCCESS != (rc = munge_decode(cred->bytes, NULL, NULL, NULL, &euid, &egid))) {
219 pmix_output_verbose(2, pmix_globals.debug_output,
220 "psec: munge failed to decode credential: %s",
221 munge_strerror(rc));
222 return PMIX_ERR_INVALID_CRED;
223 }
224
225
226 if (euid != pr->info->uid) {
227 return PMIX_ERR_INVALID_CRED;
228 }
229
230
231 if (egid != pr->info->gid) {
232 return PMIX_ERR_INVALID_CRED;
233 }
234
235 pmix_output_verbose(2, pmix_globals.debug_output,
236 "psec: munge credential valid");
237 if (NULL != info) {
238 PMIX_INFO_CREATE(*info, 3);
239 if (NULL == *info) {
240 return PMIX_ERR_NOMEM;
241 }
242 *ninfo = 3;
243
244 PMIX_INFO_LOAD(info[0], PMIX_CRED_TYPE, "munge", PMIX_STRING);
245
246 u32 = euid;
247 PMIX_INFO_LOAD(info[1], PMIX_USERID, &u32, PMIX_UINT32);
248
249 u32 = egid;
250 PMIX_INFO_LOAD(info[2], PMIX_GRPID, &u32, PMIX_UINT32);
251 }
252 return PMIX_SUCCESS;
253 }