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 }