00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00099 static const char* default_lifetime = "12:00";
00100
00101
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
00212
00213
00214
00215 if (*value) {
00216 free(*value);
00217 *value = NULL;
00218 }
00219
00220
00221 if (strcmp(argv[*pos], name)==0) {
00222 lcmaps_log(0, "\tlcmaps_afs: plugin_initialize(): Found argument %s.\n", name);
00223
00224 if (num==1) {
00225
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
00235
00236
00237
00238
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
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
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
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
00371
00372
00373
00374
00375
00376
00377
00378
00379
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
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
00510 lcmaps_log(0, "%s: fork failed: %s\n", logstr, sys_errlist[errno]);
00511 return -1;
00512 } if (pid == 0) {
00513
00514 close(pipe_fd[0]);
00515 dup2(pipe_fd[1], 1);
00516 dup2(pipe_fd[1], 2);
00517 close(pipe_fd[1]);
00518
00519 execvp(cmd, argv);
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
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 }