/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ mafdcmd() $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/ int main(int argc, char *argv[]) { int errors = 0, i, position, user_offset; char fake_user[MAX_FULL_USER_ID_LENGTH], *perm_buffer, *ptr, user[MAX_FULL_USER_ID_LENGTH], work_dir[MAX_PATH_LENGTH]; CHECK_FOR_VERSION(argc, argv); if ((argc > 1) && (argv[1][0] == '-') && (argv[1][1] == 'v') && (argv[1][2] == '\0')) { (void)fprintf(stdout, "%s\n", PACKAGE_VERSION); exit(SUCCESS); } if (get_mon_path(&argc, argv, work_dir) < 0) { exit(INCORRECT); } p_work_dir = work_dir; if (get_arg(&argc, argv, "-p", user, MAX_PROFILE_NAME_LENGTH) == INCORRECT) { user_offset = 0; } else { user_offset = strlen(user); } #ifdef WITH_SETUID_PROGS set_afd_euid(work_dir); #endif if (argc < 2) { usage(argv[0]); exit(INCORRECT); } check_fake_user(&argc, argv, MON_CONFIG_FILE, fake_user); eval_input(argc, argv); get_user(user, fake_user, user_offset); /* * Ensure that the user may use this program. */ switch (get_permissions(&perm_buffer, fake_user)) { case NO_ACCESS : /* Cannot access afd.users file. */ { char afd_user_file[MAX_PATH_LENGTH]; (void)strcpy(afd_user_file, p_work_dir); (void)strcat(afd_user_file, ETC_DIR); (void)strcat(afd_user_file, AFD_USER_FILE); (void)fprintf(stderr, "Failed to access `%s', unable to determine users permissions.\n", afd_user_file); } exit(INCORRECT); case NONE : (void)fprintf(stderr, "%s\n", PERMISSION_DENIED_STR); exit(INCORRECT); case SUCCESS : /* Lets evaluate the permissions and see what */ /* the user may do. */ { int permission = NO; if ((perm_buffer[0] == 'a') && (perm_buffer[1] == 'l') && (perm_buffer[2] == 'l') && ((perm_buffer[3] == '\0') || (perm_buffer[3] == ' ') || (perm_buffer[3] == '\t'))) { permission = YES; } else { if (lposi(perm_buffer, MAFD_CMD_PERM, MAFD_CMD_PERM_LENGTH) != NULL) { permission = YES; /* * Check if the user may do everything * he has requested. If not remove it * from the option list. */ if ((options & ENABLE_AFD_OPTION) || (options & DISABLE_AFD_OPTION)) { if (lposi(perm_buffer, DISABLE_AFD_PERM, DISABLE_AFD_PERM_LENGTH) == NULL) { if (options & ENABLE_AFD_OPTION) { options ^= ENABLE_AFD_OPTION; } if (options & DISABLE_AFD_OPTION) { options ^= DISABLE_AFD_OPTION; } if (options & TOGGLE_AFD_OPTION) { options ^= TOGGLE_AFD_OPTION; } (void)fprintf(stderr, "User %s not permitted to enable/disable a AFD.\n", user); } } if (options & RETRY_OPTION) { if (lposi(perm_buffer, RETRY_PERM, RETRY_PERM_LENGTH) == NULL) { options ^= RETRY_OPTION; (void)fprintf(stderr, "User %s not permitted to retry.\n", user); } } if (options & SWITCH_AFD_OPTION) { if (lposi(perm_buffer, SWITCH_HOST_PERM, SWITCH_HOST_PERM_LENGTH) == NULL) { options ^= SWITCH_AFD_OPTION; (void)fprintf(stderr, "User %s not permitted to retry.\n", user); } } } } free(perm_buffer); if (permission != YES) { (void)fprintf(stderr, "%s\n", PERMISSION_DENIED_STR); exit(INCORRECT); } } break; case INCORRECT: /* Hmm. Something did go wrong. Since we want to */ /* be able to disable permission checking let */ /* the user have all permissions. */ break; default : (void)fprintf(stderr, "Impossible!! Remove the programmer!\n"); exit(INCORRECT); } if (msa_attach() < 0) { (void)fprintf(stderr, "ERROR : Failed to attach to MSA. (%s %d)\n", __FILE__, __LINE__); exit(INCORRECT); } for (i = 0; i < no_of_afd_names; i++) { position = -1; ptr = afds[i]; while ((*ptr != '\0') && (isdigit((int)(*ptr)))) { ptr++; } if ((*ptr == '\0') && (ptr != afds[i])) { position = atoi(afds[i]); if ((position < 0) || (position > (no_of_afds - 1))) { (void)fprintf(stderr, "WARNING : Position %d out of range. Ignoring. (%s %d)\n", position, __FILE__, __LINE__); errors++; continue; } } if (position < 0) { if ((position = get_afd_position(msa, afds[i], no_of_afds)) < 0) { (void)fprintf(stderr, "WARNING : Could not find AFD %s in MSA. (%s %d)\n", afds[i], __FILE__, __LINE__); errors++; continue; } } /* * ENABLE AFD */ if (options & ENABLE_AFD_OPTION) { if (msa[position].connect_status == DISABLED) { int fd; #ifdef WITHOUT_FIFO_RW_SUPPORT int readfd; #endif char mon_cmd_fifo[MAX_PATH_LENGTH]; (void)sprintf(mon_cmd_fifo, "%s%s%s", p_work_dir, FIFO_DIR, MON_CMD_FIFO); #ifdef WITHOUT_FIFO_RW_SUPPORT if (open_fifo_rw(mon_cmd_fifo, &readfd, &fd) == -1) #else if ((fd = open(mon_cmd_fifo, O_RDWR)) == -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to open() %s : %s", mon_cmd_fifo, strerror(errno)); errors++; } else { char cmd[1 + SIZEOF_INT]; cmd[0] = ENABLE_MON; (void)memcpy(&cmd[1], &position, SIZEOF_INT); if (write(fd, cmd, (1 + SIZEOF_INT)) != (1 + SIZEOF_INT)) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to write() to %s : %s", mon_cmd_fifo, strerror(errno)); errors++; } else { system_log(DEBUG_SIGN, NULL, 0, "%-*s: ENABLED (%s) [mafdcmd].", MAX_AFD_NAME_LENGTH, msa[position].afd_alias, user); } #ifdef WITHOUT_FIFO_RW_SUPPORT if (close(readfd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Failed to close() FIFO %s : %s", mon_cmd_fifo, strerror(errno)); } #endif if (close(fd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Failed to close() FIFO %s : %s", mon_cmd_fifo, strerror(errno)); } } } else { (void)fprintf(stderr, "INFO : AFD %s is already enabled.\n", msa[position].afd_alias); } } /* * DISABLE AFD */ if (options & DISABLE_AFD_OPTION) { if (msa[position].connect_status == DISABLED) { (void)fprintf(stderr, "INFO : AFD %s is already disabled.\n", msa[position].afd_alias); } else { int fd; #ifdef WITHOUT_FIFO_RW_SUPPORT int readfd; #endif char mon_cmd_fifo[MAX_PATH_LENGTH]; (void)sprintf(mon_cmd_fifo, "%s%s%s", p_work_dir, FIFO_DIR, MON_CMD_FIFO); #ifdef WITHOUT_FIFO_RW_SUPPORT if (open_fifo_rw(mon_cmd_fifo, &readfd, &fd) == -1) #else if ((fd = open(mon_cmd_fifo, O_RDWR)) == -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to open() %s : %s", mon_cmd_fifo, strerror(errno)); errors++; } else { char cmd[1 + SIZEOF_INT]; cmd[0] = DISABLE_MON; (void)memcpy(&cmd[1], &position, SIZEOF_INT); if (write(fd, cmd, (1 + SIZEOF_INT)) != (1 + SIZEOF_INT)) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to write() to %s : %s", mon_cmd_fifo, strerror(errno)); errors++; } else { system_log(DEBUG_SIGN, NULL, 0, "%-*s: DISABLED (%s) [mafdcmd].", MAX_AFD_NAME_LENGTH, msa[position].afd_alias, user); } #ifdef WITHOUT_FIFO_RW_SUPPORT if (close(readfd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Failed to close() FIFO %s : %s", mon_cmd_fifo, strerror(errno)); } #endif if (close(fd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Failed to close() FIFO %s : %s", mon_cmd_fifo, strerror(errno)); } } } } /* * ENABLE or DISABLE a AFD. */ if (options & TOGGLE_AFD_OPTION) { int fd; #ifdef WITHOUT_FIFO_RW_SUPPORT int readfd; #endif char mon_cmd_fifo[MAX_PATH_LENGTH]; (void)sprintf(mon_cmd_fifo, "%s%s%s", p_work_dir, FIFO_DIR, MON_CMD_FIFO); #ifdef WITHOUT_FIFO_RW_SUPPORT if (open_fifo_rw(mon_cmd_fifo, &readfd, &fd) == -1) #else if ((fd = open(mon_cmd_fifo, O_RDWR)) == -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to open() %s : %s", mon_cmd_fifo, strerror(errno)); errors++; } else { char cmd[1 + SIZEOF_INT]; if (msa[position].connect_status == DISABLED) { cmd[0] = ENABLE_MON; } else /* DISABLE AFD */ { cmd[0] = DISABLE_MON; } (void)memcpy(&cmd[1], &position, SIZEOF_INT); if (write(fd, cmd, (1 + SIZEOF_INT)) != (1 + SIZEOF_INT)) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Failed to write() to %s : %s", mon_cmd_fifo, strerror(errno)); errors++; } else { system_log(DEBUG_SIGN, NULL, 0, "%-*s: %s (%s) [mafdcmd].", MAX_AFD_NAME_LENGTH, msa[position].afd_alias, (cmd[0] == DISABLE_MON) ? "DISABLE" : "ENABLE", user); } #ifdef WITHOUT_FIFO_RW_SUPPORT if (close(readfd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Failed to close() FIFO %s : %s", mon_cmd_fifo, strerror(errno)); } #endif if (close(fd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Failed to close() FIFO %s : %s", mon_cmd_fifo, strerror(errno)); } } } if (options & RETRY_OPTION) { int fd; #ifdef WITHOUT_FIFO_RW_SUPPORT int readfd; #endif char retry_fifo[MAX_PATH_LENGTH]; (void)sprintf(retry_fifo, "%s%s%s%d", p_work_dir, FIFO_DIR, RETRY_MON_FIFO, position); #ifdef WITHOUT_FIFO_RW_SUPPORT if (open_fifo_rw(retry_fifo, &readfd, &fd) == -1) #else if ((fd = open(retry_fifo, O_RDWR)) == -1) #endif { (void)fprintf(stderr, "WARNING : Failed to open() %s : %s (%s %d)\n", retry_fifo, strerror(errno), __FILE__, __LINE__); errors++; } else { if (write(fd, &position, sizeof(int)) != sizeof(int)) { (void)fprintf(stderr, "WARNING : Failed to write() to %s : %s (%s %d)\n", retry_fifo, strerror(errno), __FILE__, __LINE__); errors++; } #ifdef WITHOUT_FIFO_RW_SUPPORT if (close(readfd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Failed to close() FIFO %s : %s" RETRY_FD_FIFO, strerror(errno)); } #endif if (close(fd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Failed to close() FIFO %s : %s" RETRY_FD_FIFO, strerror(errno)); } } } /* * Switch AFD */ if (options & SWITCH_AFD_OPTION) { if (msa[position].afd_switching == NO_SWITCHING) { (void)fprintf(stderr, "INFO : AFD %s cannot be switched.\n", msa[position].afd_alias); errors++; } else { if (msa[position].afd_toggle == (HOST_ONE - 1)) { msa[position].afd_toggle = (HOST_TWO - 1); } else { msa[position].afd_toggle = (HOST_ONE - 1); } system_log(DEBUG_SIGN, NULL, 0, "%-*s: SWITCHED (%s) [mafdcmd].", MAX_AFD_NAME_LENGTH, msa[position].afd_alias, user); } } } /* for (i = 0; i < no_of_afd_names; i++) */ (void)msa_detach(); exit(errors); }
/*######################### check_fake_user() ###########################*/ void check_fake_user(int *argc, char *argv[], char *config_file, char *fake_user) { register int i; char wanted_user[MAX_FULL_USER_ID_LENGTH]; wanted_user[0] = 1; for (i = 1; i < *argc; i++) { if (CHECK_STRCMP(argv[i], "-u") == 0) { if (((i + 1) < *argc) && (argv[i + 1][0] != '-')) { /* Check if the buffer is long enough! */ if (MAX_FULL_USER_ID_LENGTH < strlen(argv[i + 1])) { (void)fprintf(stderr, _("Buffer for storing fake user to short. (%s %d)\n"), __FILE__, __LINE__); fake_user[0] = '\0'; return; } (void)strcpy(wanted_user, argv[i + 1]); if ((i + 2) < *argc) { register int j; for (j = i; j < *argc; j++) { argv[j] = argv[j + 2]; } argv[j] = NULL; } else { argv[i] = NULL; } *argc -= 2; i = *argc; } else { /* No fake user supplied, so lets take it from */ /* config file. */ wanted_user[0] = '\0'; if ((i + 1) < *argc) { register int j; for (j = i; j < *argc; j++) { argv[j] = argv[j + 1]; } argv[j] = NULL; } else { argv[i] = NULL; } *argc -= 1; i = *argc; } break; } } if (wanted_user[0] != 1) { struct passwd *pwd; if ((pwd = getpwuid(getuid())) != NULL) { char *buffer = NULL, full_config_name[MAX_PATH_LENGTH]; (void)snprintf(full_config_name, MAX_PATH_LENGTH, "%s%s%s", p_work_dir, ETC_DIR, config_file); if ((eaccess(full_config_name, F_OK) == 0) && (read_file_no_cr(full_config_name, &buffer, YES, __FILE__, __LINE__) != INCORRECT)) { char fake_user_list[MAX_PATH_LENGTH]; if (get_definition(buffer, FAKE_USER_DEF, fake_user_list, MAX_PATH_LENGTH) != NULL) { size_t length; length = strlen(pwd->pw_name); if (length > 0) { int change_char; char real_user[MAX_FULL_USER_ID_LENGTH + 2], *ptr, *tmp_ptr; if ((length + 1) < MAX_FULL_USER_ID_LENGTH) { (void)memcpy(real_user, pwd->pw_name, length); } else { (void)memcpy(real_user, pwd->pw_name, MAX_FULL_USER_ID_LENGTH - 1); length = MAX_FULL_USER_ID_LENGTH - 1; } real_user[length] = '-'; real_user[length + 1] = '>'; real_user[length + 2] = '\0'; ptr = fake_user_list; while ((ptr = lposi(ptr, real_user, length + 2)) != NULL) { ptr--; tmp_ptr = ptr; while ((*tmp_ptr != ',') && (*tmp_ptr != '\0')) { tmp_ptr++; } if (*tmp_ptr == ',') { change_char = YES; *tmp_ptr = '\0'; } else { change_char = NO; } if ((wanted_user[0] == '\0') || (CHECK_STRCMP(ptr, wanted_user) == 0)) { i = 0; while ((*(ptr + i) != ' ') && (*(ptr + i) != '\0') && (*(ptr + i) != '\t') && (i < MAX_FULL_USER_ID_LENGTH)) { fake_user[i] = *(ptr + i); i++; } fake_user[i] = '\0'; free(buffer); return; } if (change_char == YES) { *tmp_ptr = ','; } ptr = tmp_ptr; } } } } free(buffer); (void)fprintf(stderr, "%s (%s %d)\n", PERMISSION_DENIED_STR, __FILE__, __LINE__); exit(INCORRECT); } } fake_user[0] = '\0'; return; }