Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <inttypes.h>
- #include <iostream>
- #include <sstream>
- #include <string>
- #include <sys/stat.h>
- #include <unistd.h>
- #define __NEW_STARLET 1
- #include <descrip.h>
- #include <efndef.h>
- #include <gen64def.h>
- #include <iledef.h>
- #include <iosbdef.h>
- #include <jpidef.h>
- #include <lib$routines.h>
- #include <lnmdef.h>
- #include <prvdef.h>
- #include <psldef.h>
- #include <ssdef.h>
- #include <starlet.h>
- #include <stsdef.h>
- static const char* kCookieLogicalName = "RECALL_INPUT_COOKIE";
- extern "C" int set_process_level_executive(int16_t* new_process_level)
- {
- static const unsigned long PPD$L_PRC = 0x00000008;
- static const unsigned long PRC_W_PROCLEVEL = 0x00000038;
- typedef struct prcdef {
- char filler[PRC_W_PROCLEVEL];
- int16_t prc_w_proclevel;
- } PRCDEF;
- typedef struct clidata {
- char filler[PPD$L_PRC];
- #pragma pointer_size save
- #pragma pointer_size 32
- PRCDEF *p_prc;
- #pragma pointer_size restore
- } CLIDATA;
- extern void *CTL$AG_CLIDATA;
- CLIDATA *p_clidata;
- p_clidata = (CLIDATA *)&CTL$AG_CLIDATA;
- PRCDEF *p_prc;
- p_prc = p_clidata->p_prc;
- const int16_t old_process_level = p_prc->prc_w_proclevel;
- p_prc->prc_w_proclevel = *new_process_level;
- return old_process_level;
- }
- extern "C" bool set_process_level(int16_t new_process_level
- , int16_t& old_process_level)
- {
- struct {
- uint64_t count;
- int16_t* new_process_level;
- } arguments = {1, &new_process_level};
- const int status = static_cast<unsigned short>(
- sys$cmexec_64(reinterpret_cast<int(*)(__unknown_params)>(&set_process_level_executive)
- , reinterpret_cast<unsigned __int64*>(&arguments))
- );
- if (status == SS$_NOCMEXEC) {
- return false;
- }
- old_process_level = static_cast<unsigned short>(status);
- return true;
- }
- extern "C" void set_process_level_noreturn(int16_t new_process_level)
- {
- int16_t unused = 0;
- (void)set_process_level(new_process_level, unused);
- }
- inline void initialize_descriptor(const char* name
- , struct dsc64$descriptor_s& descriptor)
- {
- descriptor.dsc64$w_mbo = 1;
- descriptor.dsc64$b_dtype = DSC64$K_DTYPE_T;
- descriptor.dsc64$b_class = DSC64$K_CLASS_S;;
- descriptor.dsc64$l_mbmo = -1;
- descriptor.dsc64$q_length = strnlen(name, LNM$C_NAMLENGTH);
- descriptor.dsc64$pq_pointer = const_cast<char*>(name);
- }
- #define ILE3_64_BUF(code,bsize,baddr,ret) {1,(code),-1,bsize,baddr,ret}
- #define ILE3_64_END() {0,0,0,0,0,0}
- bool check_magic_cookie()
- {
- const unsigned int flag = LNM$M_CASE_BLIND;
- struct dsc64$descriptor_s table;
- initialize_descriptor("LNM$PROCESS", table);
- struct dsc64$descriptor_s logical;
- initialize_descriptor(kCookieLogicalName, logical);
- char buffer[LNM$C_NAMLENGTH + 1] = {0};
- size_t buffer_length = sizeof(buffer);
- uint64_t length = 0;
- ILEB_64 items[2] = {
- ILE3_64_BUF(LNM$_STRING, buffer_length - 1, buffer, &length)
- , ILE3_64_END()
- };
- unsigned char exec_mode = PSL$C_EXEC;
- const int status = sys$trnlnm(const_cast<unsigned int*>(&flag), &table
- , &logical, &exec_mode, items);
- return ($VMS_STATUS_SUCCESS(status));
- }
- bool destroy_magic_cookie()
- {
- struct dsc64$descriptor_s table;
- initialize_descriptor("LNM$PROCESS", table);
- struct dsc64$descriptor_s logical;
- initialize_descriptor(kCookieLogicalName, logical);
- unsigned char exec_mode = PSL$C_EXEC;
- return ($VMS_STATUS_SUCCESS(sys$dellnm(&table, &logical, &exec_mode)));
- }
- bool create_magic_cookie()
- {
- struct dsc64$descriptor_s table;
- initialize_descriptor("LNM$PROCESS", table);
- struct dsc64$descriptor_s logical;
- initialize_descriptor(kCookieLogicalName, logical);
- static const char* kLogicalValue = "1";
- unsigned char exec_mode = PSL$C_EXEC;
- ILEB_64 items[2] = {
- ILE3_64_BUF(LNM$_STRING, strlen(kLogicalValue), const_cast<char*>(kLogicalValue), 0)
- , ILE3_64_END()
- };
- return ($VMS_STATUS_SUCCESS(sys$crelnm(NULL, &table, &logical, &exec_mode, items)));
- }
- inline bool file_exists(const std::string& filename)
- {
- struct stat unused;
- return (stat(filename.c_str(), &unused) == 0);
- }
- inline bool is_number(const char* input)
- {
- const size_t input_size = strlen(input);
- for (int i = 0; i < input_size; ++i) {
- if (!isdigit(input[i])) {
- return false;
- }
- }
- return true;
- }
- std::string get_process_name()
- {
- char process_name[FILENAME_MAX + 1] = {0};
- uint64_t length = 0;
- ILEB_64 items[] = {
- ILE3_64_BUF(JPI$_IMAGNAME, sizeof(process_name) - 1, process_name, &length)
- , ILE3_64_END()
- };
- _iosb iosb;
- const int status = sys$getjpiw(EFN$C_ENF, NULL, 0, items, &iosb, 0, 0);
- if ($VMS_STATUS_SUCCESS(status) && $VMS_STATUS_SUCCESS(iosb.iosb$w_status)) {
- return std::string(process_name, length);
- }
- return std::string();
- }
- extern "C" int snprintf(char *__s, __size_t __n, const char *__format, ...);
- void display_error(const char* type, const char* message)
- {
- std::stringstream str;
- str << "%RECALLINPUT-E-" << type << ", " << message;
- std::cerr << str.str() << std::endl;
- }
- void display_fnf_error(const char* filename)
- {
- std::stringstream str;
- str << "error opening " << filename << " as input";
- display_error("FNF", str.str().c_str());
- }
- int main(int argc, char** argv)
- {
- if (argc != 2) {
- display_error("USAGE", "mcr tools:recall_input.exe <filename>");
- return EXIT_FAILURE;
- }
- if (is_number(argv[1])) {
- if (!check_magic_cookie()) {
- display_fnf_error(argv[1]);
- return EXIT_FAILURE;
- }
- set_process_level_noreturn(atoi(argv[1]));
- (void)destroy_magic_cookie();
- return EXIT_SUCCESS;
- }
- const std::string filename = argv[1];
- if (!file_exists(filename)) {
- display_fnf_error(filename.c_str());
- return EXIT_FAILURE;
- }
- const std::string this_process = get_process_name();
- if (this_process.empty()) {
- display_error("JPIERR", "error getting this process' name");
- return EXIT_FAILURE;
- }
- int16_t old_process_level = 0;
- if (!set_process_level(0, old_process_level)) {
- display_error("NOPRIV", "error escalating to CMEXEC privileges");
- return EXIT_FAILURE;
- }
- if (!create_magic_cookie()) {
- display_error("COOKIE", "error creating internal cookie");
- set_process_level_noreturn(old_process_level);
- return EXIT_FAILURE;
- }
- char command[256] = {0};
- const int full_command_size =
- snprintf(command, sizeof(command) - 1
- , "pipe recall/input=%s ; mcr %s %d"
- , filename.c_str(), this_process.c_str(), old_process_level);
- if (full_command_size >= sizeof(command)) {
- display_error("CMDLNGTH", "error constructing internal recall command due"
- " to filename being too long");
- set_process_level_noreturn(old_process_level);
- return EXIT_FAILURE;
- }
- $DESCRIPTOR64(command_descriptor, command);
- lib$do_command(&command_descriptor);
- return EXIT_FAILURE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement