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

lcmaps_afs.c

Go to the documentation of this file.
00001 /*                                                                                                            
00002  * Copyright (c) Members of the EGEE Collaboration. 2004.
00003  * See http://eu-egee.org/partners/ for details on the copyright holders.
00004  * For license conditions see the license file or
00005  * http://eu-egee.org/license.html
00006  */
00007 
00008 /*
00009  *  Copyright (c) 2001 EU DataGrid.
00010  *  For license conditions see http://www.eu-datagrid.org/license.html
00011  *
00012  *  Copyright (c) 2001, 2002 by 
00013  *      Martijn Steenbakkers <martijn@nikhef.nl>,
00014  *      David Groep <davidg@nikhef.nl>,
00015  *      Gerben Venekamp <venekamp@nikhef.nl>,
00016  *      NIKHEF Amsterdam, the Netherlands
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 /*  Default values for options.  */
00108 static const char* default_lifetime = "12:00";
00109 
00110 /*  The following option may be set.  */
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 Function:   plugin_introspect
00129 Description:
00130     return list of required arguments
00131 Parameters:
00132 
00133 Returns:
00134     LCMAPS_MOD_SUCCESS : succes
00135     LCMAPS_MOD_FAIL    : failure
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 Function:   plugin_initialize
00156 Description:
00157     Initialize plugin
00158     Everything that is needed to initialize the plugin should be put
00159     inside this function.  Arguments as read from the LCMAPS database
00160     (argc, argv) are passed to the plugin.
00161 Parameters:
00162     argc, argv
00163     argv[0]: the name of the plugin
00164 Returns:
00165     LCMAPS_MOD_SUCCESS : succes
00166     LCMAPS_MOD_FAIL    : failure
00167     LCMAPS_MOD_NOFILE  : db file not found (will halt LCMAPS initialization)
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    *  Value should be a NULL pointer, if not, it should point to
00217    *  allocated memory; in which case memory is freeed and the
00218    *  pointer set to NULL.
00219    */
00220   if (*value) {
00221     free(*value);
00222     *value = NULL;
00223   }
00224 
00225   /*  Check if the argument is recognized.  */
00226   if (strcmp(argv[*pos], name)==0) {
00227     lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Found argument %s.\n", name);
00228     /*  Does the argument need a value?  */
00229     if (num==1) {
00230       /*  Protect ourselves to reading past the argv list.  */
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          *  We have to have a value for the given argument. Since,
00240          *  we have reached the end of the argv list the sysadmin
00241          *  must have forgotten to specify it. We could silently
00242          *  ignor this mistake and supply a default value. However
00243          *  it is best that the sysadmin corrects this problem.
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   /* Fetch user gss credential */
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   /* for gssapi_ssleay if we received delegated proxy certificate
00330    * they will be in a file in tmp pointed at by the 
00331    * X509_USER_DELEG_PROXY env variable. 
00332    * This will be owned by the current uid, we need this owned by
00333    * the user.
00334    * for other gss, this is a noop, since X509_USER_DELEG_PROXY 
00335    * should not be defined.
00336    */
00337 
00338   /*
00339    * the proxyfile is probably already owned by the current user,
00340    * so commented out
00341    */
00342 //    {
00343 //        char *proxyfile;
00344 //        if ((proxyfile = getenv("X509_USER_PROXY")) != NULL)
00345 //        {
00346 //            chown(proxyfile,uid[0],priGid[0]);
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   //  rc = system(cmd);
00361   
00362   //  switch(rc) {
00363   //  case 0:   /*  Everything seems to be okay.  */
00364   //    break;
00365   //  default:
00366   //    lcmaps_log(0, "%s: gssklog returned unknown error: rc = %d", logstr, rc);
00367   //  }
00368 
00369   /*  succes  */
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   //  Create the read and write descriptors for the pipe.
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     //  Oops, it's an error!
00500     lcmaps_log(0, "%s: fork failed: %s\n", logstr, sys_errlist[errno]);
00501     return -1;
00502   } if (pid == 0) {
00503     //  Child process.
00504     close(pipe_fd[0]);
00505     dup2(pipe_fd[1], 1);   //  Redirect stdin
00506     dup2(pipe_fd[1], 2);   //  Redirect stderr
00507     close(pipe_fd[1]);
00508 
00509     execvp(cmd, argv);  //  Does not return when successful.
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   //  Parent process.
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 }

Generated on Sun May 29 21:22:10 2005 for lcmaps by doxygen 1.3.5