00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00093 #include <stdio.h>
00094 #include <stdlib.h>
00095 #include <string.h>
00096 #include <sys/types.h>
00097 #include <sys/wait.h>
00098 #include <unistd.h>
00099 #include <errno.h>
00100 #include <gssapi.h>
00101 
00102 #include "lcmaps_config.h"
00103 #include "lcmaps_modules.h"
00104 #include "lcmaps_arguments.h"
00105 
00106 
00107 
00108 static const char* default_lifetime = "12:00";
00109 
00110 
00111 static char* lifetime = NULL;
00112 static char* port     = NULL;
00113 static char* server   = NULL;
00114 static char* gsiklog  = NULL;
00115 static char* cell     = NULL;
00116 static char* setpag   = NULL;
00117 
00118 static int argv_count = 0;
00119 
00120 int run_cmd(char* cmd, char* argv[]);
00121 int fail_afs(void);
00122 int check_argument(const char* name, char** value, unsigned int num, int argc, char* argv[], int* pos);
00123 int construct_argv(char* cmd, char** argv[]);
00124 void destruct_argv(char** argv[]);
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 int plugin_introspect(int *argc, lcmaps_argument_t **argv)
00138 {
00139   static lcmaps_argument_t argList[] = {
00140     { "job_request", "lcmaps_request_t",  1, NULL},
00141     { "user_cred"  , "gss_cred_id_t"   ,  0, NULL},
00142     { NULL         , NULL              , -1, NULL}
00143   };
00144   
00145   lcmaps_log_debug(1, "\tlcmaps_afs: plugin_introspect(): introspecting\n");
00146   
00147   *argv = argList;
00148   *argc = lcmaps_cntArgs(argList);
00149   lcmaps_log_debug(1, "\tlcmaps_afs: plugin_introspect(): address first argument: 0x%x\n",argList);
00150   
00151   return LCMAPS_MOD_SUCCESS;
00152 }
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 int plugin_initialize(int argc, char **argv)
00170 {
00171   int i;
00172   
00173   lcmaps_log_debug(1, "\tlcmaps_afs: plugin_initialize(): passed arguments:\n");
00174   for (i=1; i<argc; i++) {
00175     if (argv[i][0] != '-') {
00176       lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Could not interpret arg[%d] = '%s'.\n", i, argv[i]);
00177       lcmaps_log(0, "\tlcmaps_afs:                    : Skipping argument...\n");
00178       continue;
00179     }
00180 
00181     lcmaps_log_debug(2, "\tlcmaps_afs: plugin_initialize(): arg %d is %s\n", i, argv[i]);
00182 
00183     if (check_argument("-lifetime", &lifetime, 1, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00184     if (check_argument("-server",   &server,   1, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00185     if (check_argument("-cell",     &cell,     1, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00186     if (check_argument("-port",     &port,     1, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00187     if (check_argument("-setpag",   &setpag,   0, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00188     if (check_argument("-gsiklog",  &gsiklog,  0, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00189   }
00190 
00191   return LCMAPS_MOD_SUCCESS;
00192 }
00193 
00194 
00212 int check_argument(const char* name, char** value, unsigned int num,
00213                    int argc, char* argv[], int* pos)
00214 {
00215   
00216 
00217 
00218 
00219 
00220   if (*value) {
00221     free(*value);
00222     *value = NULL;
00223   }
00224 
00225   
00226   if (strcmp(argv[*pos], name)==0) {
00227     lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Found argument %s.\n", name);
00228     
00229     if (num==1) {
00230       
00231       if ((*pos+num)<(argc)) {
00232         if (!(*value = strdup(argv[*pos+1]))) {
00233           lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Could not allocate memory.\n");
00234           return LCMAPS_MOD_FAIL;
00235         }
00236         lcmaps_log(0, "\tlcmaps_afs:                    : With value = '%s'\n", *value);
00237       } else {
00238         
00239 
00240 
00241 
00242 
00243 
00244 
00245         lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Could not read additional values.\n");
00246         lcmaps_log(0, "\tlcmaps_afs:                    : Please correct configuration file.\n");
00247         return LCMAPS_MOD_FAIL;
00248       }
00249     } else if (!(*value = strdup(name))) {
00250       lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Could not allocate memory.\n");
00251       return LCMAPS_MOD_FAIL;
00252     }
00253 
00254     *pos += num+1;
00255     argv_count += num+1;
00256   }
00257 
00258   return LCMAPS_MOD_SUCCESS;
00259 }
00260 
00261 
00262 int plugin_run(int argc, lcmaps_argument_t *argv)
00263 {
00264   char*  cmd      = "gssklog";
00265   char** cmd_argv = NULL;
00266   char*  logstr   = "\tlcmaps_afs: plugin_run()";
00267 
00268   gss_cred_id_t *pcred = NULL;
00269   gss_cred_id_t  cred  = GSS_C_NO_CREDENTIAL;
00270 
00271   lcmaps_log_debug(1, "\tlcmaps_afs: plugin_run():\n");
00272 
00273   if (getuid()==0) {
00274     lcmaps_log(0, "%s: Afs plugin is run as root.\n", logstr);
00275     lcmaps_log(0, "%s: Exit afs plugin.\n", logstr);
00276 
00277     return -1;
00278   }
00279 
00280   
00281   if ((pcred = (gss_cred_id_t *)lcmaps_getArgValue("user_cred", "gss_cred_id_t", argc, argv))) {
00282     lcmaps_log_debug(2, "%s: Address user_cred: %p\n", logstr, pcred);
00283     cred = *pcred;
00284 
00285     if (cred == GSS_C_NO_CREDENTIAL) {
00286       lcmaps_log(0, "%s: User gss credential is empty.\n", logstr);
00287       lcmaps_log(0, "%s: Exit afs plugin.\n", logstr);
00288 
00289       return fail_afs();
00290     }
00291   } else {
00292     lcmaps_log(0, "%s: Could not get address of user_cred.\n", logstr);
00293     lcmaps_log(0, "%s: Exit afs plugin.\n", logstr);
00294 
00295     return fail_afs();
00296   }
00297 
00298   if (cred) {
00299     gss_buffer_desc  deleg_proxy_filename;
00300     OM_uint32        major_status = 0;
00301     OM_uint32        minor_status = 0;
00302         
00303     major_status = gss_export_cred(&minor_status,
00304                                    cred,
00305                                    NULL,
00306                                    1,
00307                                    &deleg_proxy_filename);
00308 
00309     if (major_status == GSS_S_COMPLETE) {
00310       char *cp;
00311 
00312       cp = strchr((char *)deleg_proxy_filename.value, '=');
00313       *cp = '\0';
00314       cp++;
00315       setenv((char *)deleg_proxy_filename.value, cp, 1);
00316       free(deleg_proxy_filename.value);
00317     } else {
00318       char *error_str = NULL;
00319       globus_object_t *error_obj;
00320       
00321       error_obj = globus_error_get((globus_result_t)minor_status);
00322       
00323       error_str = globus_error_print_chain(error_obj);
00324       
00325       lcmaps_log(0, "%s: Error, gss_export_cred(): %s\n", logstr, error_str);
00326     }
00327   }
00328 
00329   
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338   
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349   
00350   lcmaps_log_debug(1, "\tlcmaps_afs: plugin_run(): address first argument: 0x%x\n", argv);
00351 
00352   if (construct_argv(cmd, &cmd_argv) && (run_cmd(cmd, cmd_argv) != 0)) {
00353   lcmaps_log(0, "\tlcmaps_afs: construct_argv: cmd_argv = %x.\n", cmd_argv);
00354     destruct_argv(&cmd_argv);
00355     return fail_afs();
00356   }
00357 
00358   destruct_argv(&cmd_argv);
00359 
00360   
00361   
00362   
00363   
00364   
00365   
00366   
00367   
00368 
00369   
00370   if(getenv("X509_USER_PROXY")) {
00371     remove(getenv("X509_USER_PROXY"));
00372   }
00373 
00374   return LCMAPS_MOD_SUCCESS;
00375 }
00376 
00377 
00390 int construct_argv(char* cmd, char** argv[])
00391 {
00392   int i;
00393 
00394   lcmaps_log_debug(0, "\tlcmaps_afs: construct_argv: Max number of elements of argv = %d.\n", argv_count);
00395 
00396   if (!(*argv = (char**)calloc(argv_count+2, sizeof(char *)))) {
00397     lcmaps_log(0, "\tlcmaps_afs: construct_argv: Could not allocate memory.\n");
00398     return 0;
00399   }
00400 
00401   i = 0;
00402   if (!((*argv)[i++] = strdup(cmd))) {
00403     lcmaps_log(0, "\tlcmaps_afs: construct_argv: Could not allocate memory.\n");
00404     return 0;
00405   }
00406 
00407   if (!((*argv)[i++] = strdup("-lifetime"))) {
00408     lcmaps_log(0, "\tlcmaps_afs: construct_argv: Could not allocate memory.\n");
00409     return 0;
00410   }
00411 
00412   if (lifetime)
00413     (*argv)[i++] = lifetime;
00414   else {
00415     if (!((*argv)[i++] = strdup(default_lifetime))) {
00416       lcmaps_log(0, "\tlcmaps_afs: construct_argv: Could not allocate memory.\n");
00417       return 0;
00418     }
00419   }
00420 
00421   lcmaps_log_debug(0, "\tlcmaps_afs: construct_argv: Constructed argv:\n");
00422   i = 0;
00423   while ((*argv)[i]) {
00424     lcmaps_log_debug(0, "\tlcmaps_afs: construct_argv: arg[%d] = '%s'.\n",i, (*argv)[i]);
00425     i++;
00426   }
00427 
00428   return 1;
00429 }
00430 
00431 
00441 void destruct_argv(char** argv[])
00442 {
00443   int i;
00444 
00445   if (*argv) {
00446     for (i=0; i<argv_count; i++) {
00447       free(argv[i]);
00448     }
00449     free(argv);
00450 
00451     *argv = NULL;
00452   }
00453 }
00454 
00455 
00464 int run_cmd(char* cmd, char* argv[])
00465 {
00466   int i, rc = 0;
00467   int child_status;
00468   pid_t term;
00469   char c;
00470   FILE* fr;
00471   pid_t pid;
00472   int pipe_fd[2];
00473   char *logstr = "\tlcmaps_afs: run_cmd()";
00474 
00475   struct sigaction sa, old_sa;
00476 
00477   sa.sa_handler = SIG_DFL;
00478   sigemptyset(&sa.sa_mask);
00479   sa.sa_flags = 0;
00480 
00481   if (sigaction(SIGCHLD, &sa, &old_sa) == -1) {
00482     lcmaps_log(0, "%s: sigaction failed: %s\n", logstr, sys_errlist[errno]);
00483     return 1;
00484   }
00485 
00486   
00487   if (pipe(pipe_fd) < 0 ) {
00488     lcmaps_log(0, "%s: pipe failed: %s\n", logstr, sys_errlist[errno]);
00489     return 1;
00490   }
00491 
00492   lcmaps_log(0, "%s: executing: '%s'\n", logstr, cmd);
00493   for (i=1; argv[i]!=NULL; ++i)
00494     lcmaps_log(0, "%s:          :  argv[%d]: '%s'\n", logstr, i, argv[i]);
00495   
00496   lcmaps_log(0, "%s: -- begin output of '%s':\n", logstr, cmd);
00497 
00498   if ((pid = fork()) < 0) {
00499     
00500     lcmaps_log(0, "%s: fork failed: %s\n", logstr, sys_errlist[errno]);
00501     return -1;
00502   } if (pid == 0) {
00503     
00504     close(pipe_fd[0]);
00505     dup2(pipe_fd[1], 1);   
00506     dup2(pipe_fd[1], 2);   
00507     close(pipe_fd[1]);
00508 
00509     execvp(cmd, argv);  
00510 
00511     lcmaps_log(0, "%s: execution of %s failed.\n", logstr, cmd);
00512     lcmaps_log(0, "%s:    %s.\n", logstr, sys_errlist[errno]);
00513 
00514     exit(-1);
00515   }
00516 
00517   
00518   close(pipe_fd[1]);
00519 
00520   fr = fdopen(pipe_fd[0], "r");
00521 
00522   lcmaps_log(0, "\tlcmaps_afs:   gssklog: ");
00523   c = fgetc(fr);
00524   if (c != EOF) {
00525     do {
00526       if (c == '\n') {
00527         fprintf(stderr, "%c", c);
00528         lcmaps_log(0, "\tlcmaps_afs:   gssklog: ");
00529       } else
00530         fprintf(stderr, "%c", c);
00531     } while ((c = fgetc(fr))!=EOF);
00532   }
00533 
00534   fclose(fr);
00535 
00536   fprintf(stderr, "\n");
00537 
00538   lcmaps_log(0, "%s: -- end output of '%s'\n", logstr, cmd);
00539 
00540   if ((term = wait(&child_status)) > 0) {
00541     if (WIFEXITED(child_status))
00542       lcmaps_log_debug(0, "%s: '%s' exit status: rc = %d\n", logstr, cmd, WEXITSTATUS(child_status));
00543     else if (WIFSIGNALED(child_status))
00544       lcmaps_log_debug(0, "%s: '%s' terminated by signal %d\n", logstr, cmd, WTERMSIG(child_status));
00545     else if (WIFSTOPPED(child_status))
00546       lcmaps_log_debug(0, "%s: '%s' stopped by signal %d\n", logstr, cmd, WSTOPSIG(child_status));
00547     else
00548       lcmaps_log(0, "%s: '%s' abnormal exit.\n", logstr, cmd);
00549   } else {
00550     lcmaps_log(0, "%s: waiting for '%s' failed:\n", logstr, cmd);
00551     lcmaps_log(0, "%s: reason: %s\n", logstr, sys_errlist[errno]);
00552     rc = 1;
00553   }
00554 
00555   if (sigaction(SIGCHLD, &old_sa, NULL) == -1) {
00556     lcmaps_log(0, "%s: sigaction failed: %s\n", logstr, sys_errlist[errno]);
00557     lcmaps_log(0, "%s:                 : Old sigaction value has not been restored.\n", logstr);
00558     return 1;
00559   }
00560 
00561   close(pipe_fd[0]);
00562 
00563   return 0;
00564 }
00565 
00566 
00573 int fail_afs(void) {
00574 
00575   if(getenv("X509_USER_PROXY")) {
00576     remove(getenv("X509_USER_PROXY"));
00577   }
00578   
00579   return LCMAPS_MOD_FAIL;
00580 }
00581 
00582 
00583 int plugin_terminate()
00584 {
00585   lcmaps_log_debug(1,"\tlcmaps_afs: plugin_terminate(): terminating\n");
00586   
00587   return LCMAPS_MOD_SUCCESS;
00588 }