Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

lcmaps_afs.c

00001 /*
00002  *  Copyright (c) 2001 EU DataGrid.
00003  *  For license conditions see http://www.eu-datagrid.org/license.html
00004  *
00005  *  Copyright (c) 2001, 2002 by 
00006  *      Martijn Steenbakkers <martijn@nikhef.nl>,
00007  *      David Groep <davidg@nikhef.nl>,
00008  *      Gerben Venekamp <venekamp@nikhef.nl>,
00009  *      NIKHEF Amsterdam, the Netherlands
00010  */
00011 
00012 
00086 #include <stdio.h>
00087 #include <stdlib.h>
00088 #include <string.h>
00089 #include <sys/types.h>
00090 #include <sys/wait.h>
00091 #include <unistd.h>
00092 
00093 #include "lcmaps_config.h"
00094 #include "lcmaps_modules.h"
00095 #include "lcmaps_arguments.h"
00096 
00097 
00098 /*  Default values for options.  */
00099 static const char* default_lifetime = "12:00";
00100 
00101 /*  The following option may be set.  */
00102 static char* lifetime = NULL;
00103 static char* port     = NULL;
00104 static char* server   = NULL;
00105 static char* gsiklog  = NULL;
00106 static char* cell     = NULL;
00107 static char* setpag   = NULL;
00108 
00109 static int argv_count = 0;
00110 
00111 int run_cmd(char* cmd, char* argv[]);
00112 int fail_afs(void);
00113 int check_argument(const char* name, char** value, unsigned int num, int argc, char* argv[], int* pos);
00114 int construct_argv(char* cmd, char** argv[]);
00115 void destruct_argv(char** argv[]);
00116 
00117 
00129 int plugin_introspect(int *argc, lcmaps_argument_t **argv)
00130 {
00131   static lcmaps_argument_t argList[] = {
00132     { "job_request", "lcmaps_request_t",  1, NULL},
00133     { "user_cred"  , "gss_cred_id_t"   ,  0, NULL},
00134     { NULL         , NULL              , -1, NULL}
00135   };
00136   
00137   lcmaps_log_debug(1, "\tlcmaps_afs: plugin_introspect(): introspecting\n");
00138   
00139   *argv = argList;
00140   *argc = lcmaps_cntArgs(argList);
00141   lcmaps_log_debug(1, "\tlcmaps_afs: plugin_introspect(): address first argument: 0x%x\n",argList);
00142   
00143   return LCMAPS_MOD_SUCCESS;
00144 }
00145 
00146 
00164 int plugin_initialize(int argc, char **argv)
00165 {
00166   int i;
00167   
00168   lcmaps_log_debug(1, "\tlcmaps_afs: plugin_initialize(): passed arguments:\n");
00169   for (i=1; i<argc; i++) {
00170     if (argv[i][0] != '-') {
00171       lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Could not interpret arg[%d] = '%s'.\n", i, argv[i]);
00172       lcmaps_log(0, "\tlcmaps_afs:                    : Skipping argument...\n");
00173       continue;
00174     }
00175 
00176     lcmaps_log_debug(2, "\tlcmaps_afs: plugin_initialize(): arg %d is %s\n", i, argv[i]);
00177 
00178     if (check_argument("-lifetime", &lifetime, 1, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00179     if (check_argument("-server",   &server,   1, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00180     if (check_argument("-cell",     &cell,     1, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00181     if (check_argument("-port",     &port,     1, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00182     if (check_argument("-setpag",   &setpag,   0, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00183     if (check_argument("-gsiklog",  &gsiklog,  0, argc, argv, &i) == LCMAPS_MOD_FAIL) return LCMAPS_MOD_FAIL; else continue;
00184   }
00185 
00186   return LCMAPS_MOD_SUCCESS;
00187 }
00188 
00189 
00207 int check_argument(const char* name, char** value, unsigned int num,
00208                    int argc, char* argv[], int* pos)
00209 {
00210   /*
00211    *  Value should be a NULL pointer, if not, it should point to
00212    *  allocated memory; in which case memory is freeed and the
00213    *  pointer set to NULL.
00214    */
00215   if (*value) {
00216     free(*value);
00217     *value = NULL;
00218   }
00219 
00220   /*  Check if the argument is recognized.  */
00221   if (strcmp(argv[*pos], name)==0) {
00222     lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Found argument %s.\n", name);
00223     /*  Does the argument need a value?  */
00224     if (num==1) {
00225       /*  Protect ourselves to reading past the argv list.  */
00226       if ((*pos+num)<(argc)) {
00227         if (!(*value = strdup(argv[*pos+1]))) {
00228           lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Could not allocate memory.\n");
00229           return LCMAPS_MOD_FAIL;
00230         }
00231         lcmaps_log(0, "\tlcmaps_afs:                    : With value = '%s'\n", *value);
00232       } else {
00233         /*
00234          *  We have to have a value for the given argument. Since,
00235          *  we have reached the end of the argv list the sysadmin
00236          *  must have forgotten to specify it. We could silently
00237          *  ignor this mistake and supply a default value. However
00238          *  it is best that the sysadmin corrects this problem.
00239          */
00240         lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Could not read additional values.\n");
00241         lcmaps_log(0, "\tlcmaps_afs:                    : Please correct configuration file.\n");
00242         return LCMAPS_MOD_FAIL;
00243       }
00244     } else if (!(*value = strdup(name))) {
00245       lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Could not allocate memory.\n");
00246       return LCMAPS_MOD_FAIL;
00247     }
00248 
00249     *pos += num+1;
00250     argv_count += num+1;
00251   }
00252 
00253   return LCMAPS_MOD_SUCCESS;
00254 }
00255 
00256 
00272 int plugin_run(int argc, lcmaps_argument_t *argv)
00273 {
00274   char*  cmd      = "gssklog";
00275   char** cmd_argv = NULL;
00276   char*  logstr   = "\tlcmaps_afs: plugin_run()";
00277 
00278   gss_cred_id_t *pcred = NULL;
00279   gss_cred_id_t  cred  = GSS_C_NO_CREDENTIAL;
00280 
00281   lcmaps_log_debug(1, "\tlcmaps_afs: plugin_run():\n");
00282 
00283   if (getuid()==0) {
00284     lcmaps_log(0, "%s: Afs plugin is run as root.\n", logstr);
00285     lcmaps_log(0, "%s: Exit afs plugin.\n", logstr);
00286 
00287     return -1;
00288   }
00289 
00290   /* Fetch user gss credential */
00291   if ((pcred = (gss_cred_id_t *)lcmaps_getArgValue("user_cred", "gss_cred_id_t", argc, argv))) {
00292     lcmaps_log_debug(2, "%s: Address user_cred: %p\n", logstr, pcred);
00293     cred = *pcred;
00294 
00295     if (cred == GSS_C_NO_CREDENTIAL) {
00296       lcmaps_log(0, "%s: User gss credential is empty.\n", logstr);
00297       lcmaps_log(0, "%s: Exit afs plugin.\n", logstr);
00298 
00299       return fail_afs();
00300     }
00301   } else {
00302     lcmaps_log(0, "%s: Could not get address of user_cred.\n", logstr);
00303     lcmaps_log(0, "%s: Exit afs plugin.\n", logstr);
00304 
00305     return fail_afs();
00306   }
00307 
00308   if (cred) {
00309     gss_buffer_desc  deleg_proxy_filename;
00310     OM_uint32        major_status = 0;
00311     OM_uint32        minor_status = 0;
00312         
00313     major_status = gss_export_cred(&minor_status,
00314                                    cred,
00315                                    NULL,
00316                                    1,
00317                                    &deleg_proxy_filename);
00318 
00319     if (major_status == GSS_S_COMPLETE) {
00320       char *cp;
00321 
00322       cp = strchr((char *)deleg_proxy_filename.value, '=');
00323       *cp = '\0';
00324       cp++;
00325       setenv((char *)deleg_proxy_filename.value, cp, 1);
00326       free(deleg_proxy_filename.value);
00327     } else {
00328       char *error_str = NULL;
00329       globus_object_t *error_obj;
00330       
00331       error_obj = globus_error_get((globus_result_t)minor_status);
00332       
00333       error_str = globus_error_print_chain(error_obj);
00334       
00335       lcmaps_log(0, "%s: Error, gss_export_cred(): %s\n", logstr, error_str);
00336     }
00337   }
00338 
00339   /* for gssapi_ssleay if we received delegated proxy certificate
00340    * they will be in a file in tmp pointed at by the 
00341    * X509_USER_DELEG_PROXY env variable. 
00342    * This will be owned by the current uid, we need this owned by
00343    * the user.
00344    * for other gss, this is a noop, since X509_USER_DELEG_PROXY 
00345    * should not be defined.
00346    */
00347 
00348   /*
00349    * the proxyfile is probably already owned by the current user,
00350    * so commented out
00351    */
00352 //    {
00353 //        char *proxyfile;
00354 //        if ((proxyfile = getenv("X509_USER_PROXY")) != NULL)
00355 //        {
00356 //            chown(proxyfile,uid[0],priGid[0]);
00357 //        }
00358 //    }
00359   
00360   lcmaps_log_debug(1, "\tlcmaps_afs: plugin_run(): address first argument: 0x%x\n", argv);
00361 
00362   if (construct_argv(cmd, &cmd_argv) && (run_cmd(cmd, cmd_argv) != 0)) {
00363   lcmaps_log(0, "\tlcmaps_afs: construct_argv: cmd_argv = %x.\n", cmd_argv);
00364     destruct_argv(&cmd_argv);
00365     return fail_afs();
00366   }
00367 
00368   destruct_argv(&cmd_argv);
00369 
00370   //  rc = system(cmd);
00371   
00372   //  switch(rc) {
00373   //  case 0:   /*  Everything seems to be okay.  */
00374   //    break;
00375   //  default:
00376   //    lcmaps_log(0, "%s: gssklog returned unknown error: rc = %d", logstr, rc);
00377   //  }
00378 
00379   /*  succes  */
00380   if(getenv("X509_USER_PROXY")) {
00381     remove(getenv("X509_USER_PROXY"));
00382   }
00383 
00384   return LCMAPS_MOD_SUCCESS;
00385 }
00386 
00387 
00400 int construct_argv(char* cmd, char** argv[])
00401 {
00402   int i;
00403 
00404   lcmaps_log_debug(0, "\tlcmaps_afs: construct_argv: Max number of elements of argv = %d.\n", argv_count);
00405 
00406   if (!(*argv = (char**)calloc(argv_count+2, sizeof(char *)))) {
00407     lcmaps_log(0, "\tlcmaps_afs: construct_argv: Could not allocate memory.\n");
00408     return 0;
00409   }
00410 
00411   i = 0;
00412   if (!((*argv)[i++] = strdup(cmd))) {
00413     lcmaps_log(0, "\tlcmaps_afs: construct_argv: Could not allocate memory.\n");
00414     return 0;
00415   }
00416 
00417   if (!((*argv)[i++] = strdup("-lifetime"))) {
00418     lcmaps_log(0, "\tlcmaps_afs: construct_argv: Could not allocate memory.\n");
00419     return 0;
00420   }
00421 
00422   if (lifetime)
00423     (*argv)[i++] = lifetime;
00424   else {
00425     if (!((*argv)[i++] = strdup(default_lifetime))) {
00426       lcmaps_log(0, "\tlcmaps_afs: construct_argv: Could not allocate memory.\n");
00427       return 0;
00428     }
00429   }
00430 
00431   lcmaps_log_debug(0, "\tlcmaps_afs: construct_argv: Constructed argv:\n");
00432   i = 0;
00433   while ((*argv)[i]) {
00434     lcmaps_log_debug(0, "\tlcmaps_afs: construct_argv: arg[%d] = '%s'.\n",i, (*argv)[i]);
00435     i++;
00436   }
00437 
00438   return 1;
00439 }
00440 
00441 
00451 void destruct_argv(char** argv[])
00452 {
00453   int i;
00454 
00455   if (*argv) {
00456     for (i=0; i<argv_count; i++) {
00457       free(argv[i]);
00458     }
00459     free(argv);
00460 
00461     *argv = NULL;
00462   }
00463 }
00464 
00465 
00474 int run_cmd(char* cmd, char* argv[])
00475 {
00476   int i, rc = 0;
00477   int child_status;
00478   pid_t term;
00479   char c;
00480   FILE* fr;
00481   pid_t pid;
00482   int pipe_fd[2];
00483   char *logstr = "\tlcmaps_afs: run_cmd()";
00484 
00485   struct sigaction sa, old_sa;
00486 
00487   sa.sa_handler = SIG_DFL;
00488   sigemptyset(&sa.sa_mask);
00489   sa.sa_flags = 0;
00490 
00491   if (sigaction(SIGCHLD, &sa, &old_sa) == -1) {
00492     lcmaps_log(0, "%s: sigaction failed: %s\n", logstr, sys_errlist[errno]);
00493     return 1;
00494   }
00495 
00496   //  Create the read and write descriptors for the pipe.
00497   if (pipe(pipe_fd) < 0 ) {
00498     lcmaps_log(0, "%s: pipe failed: %s\n", logstr, sys_errlist[errno]);
00499     return 1;
00500   }
00501 
00502   lcmaps_log(0, "%s: executing: '%s'\n", logstr, cmd);
00503   for (i=1; argv[i]!=NULL; ++i)
00504     lcmaps_log(0, "%s:          :  argv[%d]: '%s'\n", logstr, i, argv[i]);
00505   
00506   lcmaps_log(0, "%s: -- begin output of '%s':\n", logstr, cmd);
00507 
00508   if ((pid = fork()) < 0) {
00509     //  Oops, it's an error!
00510     lcmaps_log(0, "%s: fork failed: %s\n", logstr, sys_errlist[errno]);
00511     return -1;
00512   } if (pid == 0) {
00513     //  Child process.
00514     close(pipe_fd[0]);
00515     dup2(pipe_fd[1], 1);   //  Redirect stdin
00516     dup2(pipe_fd[1], 2);   //  Redirect stderr
00517     close(pipe_fd[1]);
00518 
00519     execvp(cmd, argv);  //  Does not return when successful.
00520 
00521     lcmaps_log(0, "%s: execution of %s failed.\n", logstr, cmd);
00522     lcmaps_log(0, "%s:    %s.\n", logstr, sys_errlist[errno]);
00523 
00524     exit(-1);
00525   }
00526 
00527   //  Parent process.
00528   close(pipe_fd[1]);
00529 
00530   fr = fdopen(pipe_fd[0], "r");
00531 
00532   lcmaps_log(0, "\tlcmaps_afs:   gssklog: ");
00533   c = fgetc(fr);
00534   if (c != EOF) {
00535     do {
00536       if (c == '\n') {
00537         fprintf(stderr, "%c", c);
00538         lcmaps_log(0, "\tlcmaps_afs:   gssklog: ");
00539       } else
00540         fprintf(stderr, "%c", c);
00541     } while ((c = fgetc(fr))!=EOF);
00542   }
00543 
00544   fclose(fr);
00545 
00546   fprintf(stderr, "\n");
00547 
00548   lcmaps_log(0, "%s: -- end output of '%s'\n", logstr, cmd);
00549 
00550   if ((term = wait(&child_status)) > 0) {
00551     if (WIFEXITED(child_status))
00552       lcmaps_log_debug(0, "%s: '%s' exit status: rc = %d\n", logstr, cmd, WEXITSTATUS(child_status));
00553     else if (WIFSIGNALED(child_status))
00554       lcmaps_log_debug(0, "%s: '%s' terminated by signal %d\n", logstr, cmd, WTERMSIG(child_status));
00555     else if (WIFSTOPPED(child_status))
00556       lcmaps_log_debug(0, "%s: '%s' stopped by signal %d\n", logstr, cmd, WSTOPSIG(child_status));
00557     else
00558       lcmaps_log(0, "%s: '%s' abnormal exit.\n", logstr, cmd);
00559   } else {
00560     lcmaps_log(0, "%s: waiting for '%s' failed:\n", logstr, cmd);
00561     lcmaps_log(0, "%s: reason: %s\n", logstr, sys_errlist[errno]);
00562     rc = 1;
00563   }
00564 
00565   if (sigaction(SIGCHLD, &old_sa, NULL) == -1) {
00566     lcmaps_log(0, "%s: sigaction failed: %s\n", logstr, sys_errlist[errno]);
00567     lcmaps_log(0, "%s:                 : Old sigaction value has not been restored.\n", logstr);
00568     return 1;
00569   }
00570 
00571   close(pipe_fd[0]);
00572 
00573   return 0;
00574 }
00575 
00576 
00583 int fail_afs(void) {
00584 
00585   if(getenv("X509_USER_PROXY")) {
00586     remove(getenv("X509_USER_PROXY"));
00587   }
00588   
00589   return LCMAPS_MOD_FAIL;
00590 }
00591 
00592 
00602 int plugin_terminate()
00603 {
00604   lcmaps_log_debug(1,"\tlcmaps_afs: plugin_terminate(): terminating\n");
00605   
00606   return LCMAPS_MOD_SUCCESS;
00607 }

Generated at Thu Mar 4 17:39:03 2004 for edg-lcmaps by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001