/** * @brief * main - the initialization and main loop of pbs_daemon */ int main(int argc, char *argv[]) { char jobfile[MAXPATHLEN+1]; char jobfile_full[MAXPATHLEN+1]; pbs_net_t hostaddr = 0; int port = -1; int move_type = -1; pbs_list_head attrl; enum conn_type cntype = ToServerDIS; int con = -1; char *destin; int encode_type; int i; job *jobp; char job_id[PBS_MAXSVRJOBID+1]; attribute *pattr; struct attropl *pqjatr; /* list (single) of attropl for quejob */ char script_name[MAXPATHLEN+1]; int in_server = -1; char *param_name, *param_val; char buf[4096]; struct hostent *hp; struct in_addr addr; char *credbuf = NULL; size_t credlen = 0; int prot = PROT_TCP; /*the real deal or output version and exit?*/ execution_mode(argc, argv); /* If we are not run with real and effective uid of 0, forget it */ pbs_loadconf(0); if (!isAdminPrivilege(getlogin())) { fprintf(stderr, "%s: Must be run by root\n", argv[0]); exit(SEND_JOB_FATAL); } /* initialize the pointers in the resource_def array */ for (i = 0; i < (svr_resc_size - 1); ++i) svr_resc_def[i].rs_next = &svr_resc_def[i+1]; /* last entry is left with null pointer */ /* set single threaded mode */ pbs_client_thread_set_single_threaded_mode(); /* disable attribute verification */ set_no_attribute_verification(); /* initialize the thread context */ if (pbs_client_thread_init_thread_context() != 0) { fprintf(stderr, "%s: Unable to initialize thread context\n", argv[0]); exit(SEND_JOB_FATAL); } if(set_msgdaemonname("PBS_send_job")) { fprintf(stderr, "Out of memory\n"); return 1; } winsock_init(); connection_init(); while (fgets(buf, sizeof(buf), stdin) != NULL) { buf[strlen(buf)-1] = '\0'; /* gets rid of newline */ param_name = buf; param_val = strchr(buf, '='); if (param_val) { *param_val = '\0'; param_val++; } else { /* bad param_val -- skipping */ break; } if (strcmp(param_name, "jobfile") == 0) { jobfile[0] = '\0'; strncpy(jobfile, param_val, MAXPATHLEN); } else if (strcmp(param_name, "destaddr") == 0) { hostaddr = atol(param_val); } else if (strcmp(param_name, "destport") == 0) { port = atoi(param_val); } else if (strcmp(param_name, "move_type") == 0) { move_type = atoi(param_val); } else if (strcmp(param_name, "in_server") == 0) { in_server = atoi(param_val); } else if (strcmp(param_name, "server_name") == 0) { server_name[0] = '\0'; strncpy(server_name, param_val, PBS_MAXSERVERNAME); } else if (strcmp(param_name, "server_host") == 0) { server_host[0] = '\0'; strncpy(server_host, param_val, (sizeof(server_host) - 1)); } else if (strcmp(param_name, "server_addr") == 0) { pbs_server_addr = atol(param_val); } else if (strcmp(param_name, "server_port") == 0) { pbs_server_port_dis = atoi(param_val); } else if (strcmp(param_name, "log_file") == 0) { log_file = strdup(param_val); } else if (strcmp(param_name, "path_log") == 0) { path_log[0] = '\0'; strncpy(path_log, param_val, MAXPATHLEN); } else if (strcmp(param_name, "path_jobs") == 0) { path_jobs = strdup(param_val); } else if (strcmp(param_name, "path_spool") == 0) { path_spool = strdup(param_val); } else if (strcmp(param_name, "path_rescdef") == 0) { path_rescdef = strdup(param_val); } else if (strcmp(param_name, "path_users") == 0) { path_users = strdup(param_val); } else if (strcmp(param_name, "path_hooks_workdir") == 0) { path_hooks_workdir = strdup(param_val); if (path_hooks_workdir == NULL) exit(SEND_JOB_FATAL); } else if (strcmp(param_name, "svr_history_enable") == 0) { svr_history_enable = atol(param_val); } else if (strcmp(param_name, "svr_history_duration") == 0) { svr_history_duration = atol(param_val); } else if (strcmp(param_name, "single_signon_password_enable") == 0) { if (decode_b(&server.sv_attr[(int)SRV_ATR_ssignon_enable], NULL, NULL, param_val) != 0) { fprintf(stderr, "%s: failed to set ssignon_password_enable\n", argv[0]); exit(SEND_JOB_FATAL); } } else if (strcmp(param_name, "script_name") == 0) { strncpy(script_name, param_val, MAXPATHLEN + 1); } else break; } time(&time_now); (void)log_open_main(log_file, path_log, 1); /* silent open */ if (setup_resc(1) == -1) { /* log_buffer set in setup_resc */ log_err(-1, "pbsd_send_job(setup_resc)", log_buffer); return (-1); } if( strlen(jobfile) == 0 || hostaddr == 0 || port == 0 || move_type == -1 || \ in_server == -1 || strlen(server_name) == 0 || strlen(server_host) == 0 || \ pbs_server_addr == 0 || pbs_server_port_dis == 0 || \ strlen(path_log) == 0 || path_jobs == NULL || \ path_spool == NULL || path_users == NULL ) { log_err(-1, "pbs_send_job", "error on one of the parameters"); log_close(0); /* silent close */ exit(SEND_JOB_FATAL); } CLEAR_HEAD(task_list_immed); CLEAR_HEAD(task_list_timed); CLEAR_HEAD(task_list_event); CLEAR_HEAD(svr_queues); CLEAR_HEAD(svr_alljobs); CLEAR_HEAD(svr_newjobs); CLEAR_HEAD(svr_allresvs); CLEAR_HEAD(svr_newresvs); CLEAR_HEAD(svr_deferred_req); CLEAR_HEAD(svr_unlicensedjobs); strcpy(jobfile_full, path_jobs); strcat(jobfile_full, jobfile); if (chk_save_file(jobfile_full) != 0) { sprintf(log_buffer, "Error opening jobfile=%s", jobfile); log_err(-1, __func__, log_buffer); goto fatal_exit; } if ((jobp=job_recov_fs(jobfile, RECOV_SUBJOB)) == NULL) { sprintf(log_buffer, "Failed to recreate job in jobfile=%s", jobfile); log_err(-1, __func__, log_buffer); goto fatal_exit; } /* now delete the temp job file that was created by job_save_fs in server code * jobs are in database now, no need to keep in filesystem */ unlink(jobfile_full); if (in_server) append_link(&svr_alljobs, &jobp->ji_alljobs, jobp); /* select attributes/resources to send based on move type */ if (move_type == MOVE_TYPE_Exec) { resc_access_perm = ATR_DFLAG_MOM; encode_type = ATR_ENCODE_MOM; cntype = ToServerDIS; } else { resc_access_perm = ATR_DFLAG_USWR | ATR_DFLAG_OPWR | ATR_DFLAG_MGWR | ATR_DFLAG_SvRD; encode_type = ATR_ENCODE_SVR; svr_dequejob(jobp); } CLEAR_HEAD(attrl); pattr = jobp->ji_wattr; for (i=0; i < (int)JOB_ATR_LAST; i++) { if ((job_attr_def+i)->at_flags & resc_access_perm) { (void)(job_attr_def+i)->at_encode(pattr+i, &attrl, (job_attr_def+i)->at_name, NULL, encode_type, NULL); } } attrl_fixlink(&attrl); /* script name is passed from parent */ /* get host name */ pbs_loadconf(0); addr.s_addr = htonl(hostaddr); hp = gethostbyaddr((void *)&addr, sizeof(struct in_addr), AF_INET); if (hp == NULL) { sprintf(log_buffer, "%s: h_errno=%d", inet_ntoa(addr), h_errno); log_err(-1, __func__, log_buffer); } else { /* read any credential file */ (void)get_credential(hp->h_name, jobp, PBS_GC_BATREQ, &credbuf, &credlen); } /* save the job id for when after we purge the job */ (void)strcpy(job_id, jobp->ji_qs.ji_jobid); con = -1; DIS_tcparray_init(); for (i=0; i<RETRY; i++) { pbs_errno = 0; /* connect to receiving server with retries */ if (i > 0) { /* recycle after an error */ if (con >= 0) svr_disconnect(con); if (should_retry_route(pbs_errno) == -1) { goto fatal_exit; /* fatal error, don't retry */ } sleep(1<<i); } if ((con = svr_connect(hostaddr, port, 0, cntype, prot)) == PBS_NET_RC_FATAL) { (void)sprintf(log_buffer, "send_job failed to %lx port %d", hostaddr, port); log_err(pbs_errno, __func__, log_buffer); goto fatal_exit; } else if (con == PBS_NET_RC_RETRY) { pbs_errno = WSAECONNREFUSED; /* should retry */ continue; } /* * if the job is substate JOB_SUBSTATE_TRNOUTCM which means * we are recovering after being down or a late failure, we * just want to send the "read-to-commit/commit" */ if (jobp->ji_qs.ji_substate != JOB_SUBSTATE_TRNOUTCM) { if (jobp->ji_qs.ji_substate != JOB_SUBSTATE_TRNOUT) { jobp->ji_qs.ji_substate = JOB_SUBSTATE_TRNOUT; } pqjatr = &((svrattrl *)GET_NEXT(attrl))->al_atopl; destin = jobp->ji_qs.ji_destin; if (PBSD_queuejob(con, jobp->ji_qs.ji_jobid, destin, pqjatr, NULL, prot, NULL)== 0) { if (pbs_errno == PBSE_JOBEXIST && move_type == MOVE_TYPE_Exec) { /* already running, mark it so */ log_event(PBSEVENT_ERROR, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, "Mom reports job already running"); goto ok_exit; } else if ((pbs_errno == PBSE_HOOKERROR) || (pbs_errno == PBSE_HOOK_REJECT) || (pbs_errno == PBSE_HOOK_REJECT_RERUNJOB) || (pbs_errno == PBSE_HOOK_REJECT_DELETEJOB)) { char name_buf[MAXPATHLEN+1]; int rfd; int len; char *reject_msg; int err; err = pbs_errno; reject_msg = pbs_geterrmsg(con); (void)snprintf(log_buffer, sizeof(log_buffer), "send of job to %s failed error = %d reject_msg=%s", destin, err, reject_msg?reject_msg:""); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, log_buffer); (void)strcpy(name_buf, path_hooks_workdir); (void)strcat(name_buf, jobp->ji_qs.ji_jobid); (void)strcat(name_buf, HOOK_REJECT_SUFFIX); if ((reject_msg != NULL) && (reject_msg[0] != '\0')) { if ((rfd = open(name_buf, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1) { snprintf(log_buffer, sizeof(log_buffer), "open of reject file %s failed: errno %d", name_buf, errno); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, log_buffer); } else { secure_file(name_buf, "Administrators", READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED); setmode(rfd, O_BINARY); len = strlen(reject_msg)+1; /* write also trailing null char */ if (write(rfd, reject_msg, len) != len) { snprintf(log_buffer, sizeof(log_buffer), "write to file %s incomplete: errno %d", name_buf, errno); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, log_buffer); } close(rfd); } } if (err == PBSE_HOOKERROR) exit(SEND_JOB_HOOKERR); if (err == PBSE_HOOK_REJECT) exit(SEND_JOB_HOOK_REJECT); if (err == PBSE_HOOK_REJECT_RERUNJOB) exit(SEND_JOB_HOOK_REJECT_RERUNJOB); if (err == PBSE_HOOK_REJECT_DELETEJOB) exit(SEND_JOB_HOOK_REJECT_DELETEJOB); } else { (void)sprintf(log_buffer, "send of job to %s failed error = %d", destin, pbs_errno); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobp->ji_qs.ji_jobid, log_buffer); continue; } } if (jobp->ji_qs.ji_svrflags & JOB_SVFLG_SCRIPT) { if (PBSD_jscript(con, script_name, prot, NULL) != 0) continue; } if (credlen > 0) { int ret; ret = PBSD_jcred(con, jobp->ji_extended.ji_ext.ji_credtype, credbuf, credlen, prot, NULL); if ((ret == 0) || (i == (RETRY - 1))) free(credbuf); /* free credbuf if credbuf is sent successfully OR */ /* at the end of all retry attempts */ if (ret != 0) continue; } if ((move_type == MOVE_TYPE_Exec) && (jobp->ji_qs.ji_svrflags & JOB_SVFLG_HASRUN) && (hostaddr != pbs_server_addr)) { /* send files created on prior run */ if ((move_job_file(con, jobp, StdOut, prot) != 0) || (move_job_file(con, jobp, StdErr, prot) != 0) || (move_job_file(con, jobp, Chkpt, prot) != 0)) continue; } jobp->ji_qs.ji_substate = JOB_SUBSTATE_TRNOUTCM; } if (PBSD_rdytocmt(con, job_id, prot, NULL) != 0) continue; if (PBSD_commit(con, job_id, prot, NULL) != 0) goto fatal_exit; goto ok_exit; /* This child process is all done */ } if (con >= 0) svr_disconnect(con); /* * If connection is actively refused by the execution node(or mother superior) OR * the execution node(or mother superior) is rejecting request with error * PBSE_BADHOST(failing to authorize server host), the node should be marked down. */ if ((move_type == MOVE_TYPE_Exec) && (pbs_errno == WSAECONNREFUSED || pbs_errno == PBSE_BADHOST)) { i = SEND_JOB_NODEDW; } else if (should_retry_route(pbs_errno) == -1) { i = SEND_JOB_FATAL; } else { i = SEND_JOB_RETRY; } (void)sprintf(log_buffer, "send_job failed with error %d", pbs_errno); log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_NOTICE, jobp->ji_qs.ji_jobid, log_buffer); log_close(0); net_close(-1); unlink(script_name); exit(i); fatal_exit: if (con >= 0) svr_disconnect(con); log_close(0); net_close(-1); unlink(script_name); exit(SEND_JOB_FATAL); ok_exit: if (con >= 0) svr_disconnect(con); log_close(0); net_close(-1); unlink(script_name); exit(SEND_JOB_OK); }
/** * @brief * main - the initialization and main loop of pbs_daemon */ int main(int argc, char *argv[]) { char buf[4096]; char *param_name, *param_val; int rc; execution_mode(argc, argv); if(set_msgdaemonname("PBS_send_hooks")) { fprintf(stderr, "Out of memory\n"); return 1; } pbs_loadconf(0); /* If we are not run with real and effective uid of 0, forget it */ if (!isAdminPrivilege(getlogin())) { fprintf(stderr, "%s: Must be run by root\n", argv[0]); exit(-1); } pbs_client_thread_set_single_threaded_mode(); /* disable attribute verification */ set_no_attribute_verification(); /* initialize the thread context */ if (pbs_client_thread_init_thread_context() != 0) { fprintf(stderr, "%s: Unable to initialize thread context\n", argv[0]); exit(-1); } winsock_init(); connection_init(); while (fgets(buf, sizeof(buf), stdin) != NULL) { buf[strlen(buf)-1] = '\0'; /* gets rid of newline */ param_name = buf; param_val = strchr(buf, '='); if (param_val) { *param_val = '\0'; param_val++; } else { /* bad param_val -- skipping */ break; } if (strcmp(param_name, "path_log") == 0) { path_log[0] = '\0'; strncpy(path_log, param_val, MAXPATHLEN); } else if (strcmp(param_name, "path_hooks") == 0) { path_hooks = strdup(param_val); if (path_hooks == NULL) exit(-1); } else if (strcmp(param_name, "log_file") == 0) { log_file = strdup(param_val); if (log_file == NULL) exit(-1); } else if (strcmp(param_name, "path_hooks_tracking") == 0) { path_hooks_tracking = strdup(param_val); if (path_hooks_tracking == NULL) exit(-1); } else if (strcmp(param_name, "hook_action_tid") == 0) { #ifdef WIN32 hook_action_tid_set(_atoi64(param_val)); #else hook_action_tid_set(atoll(param_val)); #endif } else if (strcmp(param_name, "pbs_server_port_dis") == 0) { pbs_server_port_dis = atoi(param_val); } else if (strcmp(param_name, "pbs_server_addr") == 0) { pbs_server_addr = atol(param_val); } else break; } (void)log_open_main(log_file, path_log, 1); /* silent open */ hook_track_recov(); rc = sync_mom_hookfiles(NULL); log_close(0); /* silent close */ net_close(-1); if (log_file != NULL) free(log_file); if (path_hooks != NULL) free(path_hooks); if (path_hooks_tracking != NULL) free(path_hooks_tracking); exit(rc); }
int svr_get_privilege(char *user, char *host) { int is_root = 0; int priv = (ATR_DFLAG_USRD | ATR_DFLAG_USWR); char uh[PBS_MAXUSER + PBS_MAXHOSTNAME + 2]; #ifdef WIN32 char server_host_netbios[MAX_COMPUTERNAME_LENGTH+1]; DWORD hsize = MAX_COMPUTERNAME_LENGTH; char current_domain[PBS_MAXHOSTNAME+1]; char server_host_domain[PBS_MAXHOSTNAME+1]; char user_s[PBS_MAXHOSTNAME+ UNLEN+2]; char *p = NULL; char *p0 = NULL; int ch = '\\'; #endif (void)strcpy(uh, user); (void)strcat(uh, "@"); (void)strcat(uh, host); #ifdef WIN32 /* Try to match requesting host against: */ /* localhost */ /* <server_host> */ /* <server_host_netbios_name> */ /* <server_host_netbios_name>.<windows_domain> */ if ( isAdminPrivilege(user) && \ ( (strcasecmp(host, server_host) == 0) || \ (strcasecmp(host, LOCALHOST_SHORTNAME) == 0) || \ (GetComputerName(server_host_netbios, &hsize) && \ (strcasecmp(host, server_host_netbios) == 0)) || \ (GetComputerDomainName(current_domain) && \ sprintf(server_host_domain, "%s.%s", server_host_netbios, current_domain) && \ (strcasecmp(host, server_host_domain) == 0)) ) ) { is_root = 1; } #else if (strcmp(user, PBS_DEFAULT_ADMIN) == 0) { char myhostname[PBS_MAXHOSTNAME+1]; /* First try without DNS lookup. */ if (strcasecmp(host, server_host) == 0) { is_root = 1; } else if (strcasecmp(host, LOCALHOST_SHORTNAME) == 0) { is_root = 1; } else if (strcasecmp(host, LOCALHOST_FULLNAME) == 0) { is_root = 1; } else { if (gethostname(myhostname, (sizeof(myhostname) - 1)) == -1) { myhostname[0] = '\0'; } if (strcasecmp(host, myhostname) == 0) { is_root = 1; } } if (is_root == 0) { /* Now try with DNS lookup. */ if (is_same_host(host, server_host)) { is_root = 1; } else if (is_same_host(host, myhostname)) { is_root = 1; } } } #endif /* WIN32 */ #ifdef PBS_ROOT_ALWAYS_ADMIN if (is_root) return (priv | ATR_DFLAG_MGRD | ATR_DFLAG_MGWR | ATR_DFLAG_OPRD | ATR_DFLAG_OPWR); #endif /* PBS_ROOT_ALWAYS_ADMIN */ if (!(server.sv_attr[(int)SRV_ATR_managers].at_flags & ATR_VFLAG_SET)) { if (is_root) priv |= (ATR_DFLAG_MGRD | ATR_DFLAG_MGWR); } else if (acl_check(&server.sv_attr[SRV_ATR_managers], uh, ACL_User)) priv |= (ATR_DFLAG_MGRD | ATR_DFLAG_MGWR); if (!(server.sv_attr[(int)SRV_ATR_operators].at_flags&ATR_VFLAG_SET)) { if (is_root) priv |= (ATR_DFLAG_OPRD | ATR_DFLAG_OPWR); } else if (acl_check(&server.sv_attr[SRV_ATR_operators], uh, ACL_User)) priv |= (ATR_DFLAG_OPRD | ATR_DFLAG_OPWR); return (priv); }
/** * @brief * main - the entry point in pbs_account_win.c * * @param[in] argc - argument count * @param[in] argv - argument variables. * @param[in] env - environment values. * * @return int * @retval 0 : success * @retval !=0 : error code */ main(int argc, char *argv[]) { SID *sa_sid = NULL; /* service account SID */ char sa_name[PBS_MAXHOSTNAME+UNLEN+2] = {'\0'}; /* service account name */ /* domain\user\0 */ int ret_val = 0; int c_opt = 0; int s_opt = 0; int a_opt = 0; int p_opt = 0; int R_opt = 0; int U_opt = 0; int instid_opt = 0; char service_bin_path[MAXPATHLEN+1] = {'\0'}; char service_name[MAXPATHLEN+1] = {'\0'}; int i = 0; char outputfile[MAXPATHLEN+1] = {'\0'}; char instanceName[MAXPATHLEN+1] = {'\0'}; int output_fd = -1; struct passwd *pw = NULL; char *p = NULL; winsock_init(); /*test for real deal or just version and exit*/ execution_mode(argc, argv); strcpy(exec_unamef, getlogin_full()); strcpy(exec_dname, "."); if ((p=strchr(exec_unamef, '\\'))) { *p = '\0'; strcpy(exec_dname, exec_unamef); *p = '\\'; } strcpy(sa_password, ""); strcpy(outputfile, ""); /* with no option, check only if service account exists */ if (argc == 1) { int in_domain_environment = 0; char dname[PBS_MAXHOSTNAME+1] = {'\0'}; char dctrl[PBS_MAXHOSTNAME+1] = {'\0'}; wchar_t unamew[UNLEN+1] = {'\0'}; wchar_t dctrlw[PBS_MAXHOSTNAME+1] = {'\0'}; USER_INFO_0 *ui1_ptr = NULL; NET_API_STATUS netst = 0; /* figure out the domain controller hostname (dctrl) */ /* in domain environment, */ /* domain name (dname) != domain controller hostname */ /* in standalone environment, */ /* domain name (dname) == domain controller hostname */ in_domain_environment = GetComputerDomainName(dname); strcpy(dctrl, dname); if (in_domain_environment) { char dname_a[PBS_MAXHOSTNAME+1]; get_dcinfo(dname, dname_a, dctrl); } /* convert strings to "wide" format */ mbstowcs(unamew, service_accountname, UNLEN+1); mbstowcs(dctrlw, dctrl, PBS_MAXHOSTNAME+1); netst = wrap_NetUserGetInfo(dctrlw, unamew, 1, (LPBYTE *)&ui1_ptr); if (strlen(winlog_buffer) > 0) { fprintf(stderr, "%s\n", winlog_buffer); } if (netst == NERR_UserNotFound) { fprintf(stderr, "%s not found!\n", service_accountname); if (in_domain_environment && stricmp(exec_dname, dname) != 0) { fprintf(stderr, "But no privilege to create service account %s\\%s!\n", dname, service_accountname); ret_val=2; } else { ret_val=1; } } else if ((netst == ERROR_ACCESS_DENIED) || (netst == ERROR_LOGON_FAILURE)) { fprintf(stderr, "no privilege to obtain info for service account %s\\%s!\n", dname, service_accountname); ret_val= 2; } else { fprintf(stderr, "service account is %s\\%s!\n", dname, service_accountname); ret_val = 0; } if (ui1_ptr != NULL) NetApiBufferFree(ui1_ptr); goto end_pbs_account; } i = 1; while (i < argc) { if (strcmp(argv[i], "-c") == 0) { c_opt = 1; i++; } else if (strcmp(argv[i], "--ci") == 0) { c_opt = 1; for_info_only = 1; i++; } else if (strcmp(argv[i], "-s") == 0) { s_opt = 1; i++; } else if (strcmp(argv[i], "-a") == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No service account name argument supplied!\n"); usage(argv[0]); exit(1); } a_opt = 1; strcpy(service_accountname, argv[i+1]); i+=2; } else if (strcmp(argv[i], "-p") == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No password argument supplied!\n"); usage(argv[0]); exit(1); } p_opt = 1; strcpy(sa_password, argv[i+1]); cache_usertoken_and_homedir(service_accountname, NULL, 0, read_sa_password, (char*)service_accountname, decrypt_sa_password, 1); i+=2; } else if (strcmp(argv[i], "--reg") == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No service binary path given\n"); usage(argv[0]); exit(1); } R_opt = 1; strcpy(service_bin_path, argv[i+1]); i+=2; } else if (strcmp(argv[i], "--unreg") == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No service binary path given\n"); usage(argv[0]); exit(1); } U_opt = 1; strcpy(service_bin_path, argv[i+1]); i+=2; } else if (strcmp(argv[i], "-o") == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No output path argument supplied!\n"); usage(argv[0]); exit(1); } p_opt = 1; strcpy(outputfile, argv[i+1]); i+=2; } else if (strncmp(argv[i], "--instid", strlen("--instid")) == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No instance id supplied!\n"); usage(argv[0]); exit(1); } instid_opt = 1; strncpy(instanceName, argv[i+1], MAXPATHLEN); i+=2; } else { fprintf(stderr, "Unknown option %s\n", argv[i]); usage(argv[0]); exit(1); } } if (strlen(outputfile) > 0) { if ((output_fd=open(outputfile, O_RDWR|O_CREAT, 0600)) != -1) { _dup2(output_fd, 1); /* put stdout in file */ _dup2(output_fd, 2); /* put stderr in file */ } } /* prompt for password if not supplied with -p */ if ((c_opt || R_opt) && (strcmp(sa_password, "") == 0)) { prompt_to_get_password(sa_password); cache_usertoken_and_homedir(service_accountname, NULL, 0, read_sa_password, (char *)service_accountname, decrypt_sa_password, 1); } /* Need to get service_name */ if (R_opt || U_opt) { char *p = NULL; int k = 0; strcpy(service_name, service_bin_path); if ((p=strrchr(service_bin_path, '\\'))) { strcpy(service_name, p+1); } if ((p=strrchr(service_name, '.'))) {/*remove .exe portion*/ *p = '\0'; } /* translate from lower-case to upper-case */ for (k=0; k < strlen(service_name); k++) { service_name[k] = toupper(service_name[k]); } if (instid_opt) { strcat_s(service_name, MAXPATHLEN, "_"); strcat_s(service_name, MAXPATHLEN, instanceName); } } if (c_opt) { if (add_service_account(sa_password) == 0) { ret_val = 3; goto end_pbs_account; } } if (s_opt || R_opt) { /* need service account name */ sa_sid = getusersid2(service_accountname, sa_name); if (sa_sid == NULL) { fprintf(stderr, "%s not found!\n", service_accountname); ret_val= 1; goto end_pbs_account; } if (!isAdminPrivilege(service_accountname)) { fprintf(stderr, "%s is not ADMIN! - %s\n", service_accountname, winlog_buffer); ret_val = 2; goto end_pbs_account; } } if (s_opt) { int r1, r2, r3, r4; printf("Setting the following privileges to %s:\n", sa_name); r1 = add_privilege(sa_sid, SE_CREATE_TOKEN_NAME); r2 = add_privilege(sa_sid, SE_ASSIGNPRIMARYTOKEN_NAME); r3 = add_privilege(sa_sid, SE_SERVICE_LOGON_NAME); r4 = add_privilege(sa_sid, SE_TCB_NAME); if ((r1 != 0) || (r2 != 0) || (r3 != 0) || (r4 != 0)) { ret_val = 4; goto end_pbs_account; } } if (R_opt) { ret_val = register_scm(__TEXT(service_name), service_bin_path, sa_name, sa_password); } if (U_opt) { ret_val = unregister_scm(__TEXT(service_name)); } end_pbs_account: if (sa_sid != NULL) LocalFree(sa_sid); if (strlen(sa_password) > 0) memset((char *)sa_password, 0, strlen(sa_password)); if (output_fd != -1) (void)close(output_fd); exit(ret_val); }
void req_holdjob(struct batch_request *preq) { long *hold_val; int jt; /* job type */ int newstate; int newsub; long old_hold; job *pjob; char *pset; int rc; char date[32]; time_t now; pjob = chk_job_request(preq->rq_ind.rq_hold.rq_orig.rq_objname, preq, &jt); if (pjob == (job *)0) return; if ((jt != IS_ARRAY_NO) && (jt != IS_ARRAY_ArrayJob)) { req_reject(PBSE_IVALREQ, 0, preq); return; } if ((pjob->ji_qs.ji_state == JOB_STATE_RUNNING) && (pjob->ji_qs.ji_substate == JOB_SUBSTATE_PROVISION)) { req_reject(PBSE_BADSTATE, 0, preq); return; } /* cannot do anything until we decode the holds to be set */ if ((rc=get_hold(&preq->rq_ind.rq_hold.rq_orig.rq_attr, &pset)) != 0) { req_reject(rc, 0, preq); return; } /* if other than HOLD_u is being set, must have privil */ if ((rc = chk_hold_priv(temphold.at_val.at_long, preq->rq_perm)) != 0) { req_reject(rc, 0, preq); return; } /* HOLD_bad_password can only be done by root or admin */ #ifdef WIN32 if ( (temphold.at_val.at_long & HOLD_bad_password) && \ !isAdminPrivilege(preq->rq_user) ) #else if ( (temphold.at_val.at_long & HOLD_bad_password) && \ strcasecmp(preq->rq_user, PBS_DEFAULT_ADMIN) != 0 ) #endif { req_reject(PBSE_PERM, 0, preq); return; } hold_val = &pjob->ji_wattr[(int)JOB_ATR_hold].at_val.at_long; old_hold = *hold_val; *hold_val |= temphold.at_val.at_long; pjob->ji_wattr[(int)JOB_ATR_hold].at_flags |= ATR_VFLAG_SET | ATR_VFLAG_MODCACHE; /* Note the hold time in the job comment. */ now = time(NULL); (void)strncpy(date, (const char *)ctime(&now), 24); date[24] = '\0'; (void)sprintf(log_buffer, "Job held by %s on %s", preq->rq_user, date); job_attr_def[(int)JOB_ATR_Comment].at_decode(&pjob->ji_wattr[(int)JOB_ATR_Comment], (char *)0, (char *)0, log_buffer); (void)sprintf(log_buffer, msg_jobholdset, pset, preq->rq_user, preq->rq_host); if ((pjob->ji_qs.ji_state == JOB_STATE_RUNNING) && (pjob->ji_qs.ji_substate != JOB_SUBSTATE_PRERUN) && (pjob->ji_wattr[(int)JOB_ATR_chkpnt].at_val.at_str) && (*pjob->ji_wattr[(int)JOB_ATR_chkpnt].at_val.at_str != 'n')) { /* have MOM attempt checkpointing */ if ((rc = relay_to_mom(pjob, preq, post_hold)) != 0) { *hold_val = old_hold; /* reset to the old value */ req_reject(rc, 0, preq); } else { pjob->ji_qs.ji_substate = JOB_SUBSTATE_RERUN; pjob->ji_qs.ji_svrflags |= JOB_SVFLG_HASRUN | JOB_SVFLG_CHKPT; (void)job_save(pjob, SAVEJOB_QUICK); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, pjob->ji_qs.ji_jobid, log_buffer); } } else { /* every thing went well, may need to update the job state */ log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, pjob->ji_qs.ji_jobid, log_buffer); if (old_hold != *hold_val) { /* indicate attributes changed */ pjob->ji_modified = 1; svr_evaljobstate(pjob, &newstate, &newsub, 0); (void)svr_setjobstate(pjob, newstate, newsub); } reply_ack(preq); } }
int site_check_user_map(void *pobj, int objtype, char *luser) { char *orighost; char owner[PBS_MAXUSER+1]; char *p1; char *objid; int event_type, event_class; int rc; /* set pointer variables etc based on object's type */ if (objtype == JOB_OBJECT) { p1 = ((job *)pobj)->ji_wattr[JOB_ATR_job_owner].at_val.at_str; objid = ((job *)pobj)->ji_qs.ji_jobid; event_type = PBSEVENT_JOB; event_class = PBS_EVENTCLASS_JOB; } else { p1 = ((resc_resv *)pobj)->ri_wattr[RESV_ATR_resv_owner].at_val.at_str; objid = ((resc_resv *)pobj)->ri_qs.ri_resvID; event_type = PBSEVENT_JOB; event_class = PBS_EVENTCLASS_JOB; } /* the owner name, without the "@host" */ cvrt_fqn_to_name(p1, owner); orighost = strchr(p1, '@'); if ((orighost == (char *)0) || (*++orighost == '\0')) { log_event(event_type, event_class, LOG_INFO, objid, msg_orighost); return (-1); } if (!strcasecmp(orighost, server_host) && !strcmp(owner, luser)) return (0); #ifdef WIN32 rc = ruserok(orighost, isAdminPrivilege(luser), owner, luser); if (rc == -2) { sprintf(log_buffer, "User %s does not exist!", luser); log_err(0, "site_check_user_map", log_buffer); rc = -1; } else if (rc == -3) { sprintf(log_buffer, "User %s's [HOMEDIR]/.rhosts is unreadable! Needs SYSTEM or Everyone access", luser); log_err(0, "site_check_user_map", log_buffer); rc = -1; } #else rc = ruserok(orighost, 0, owner, luser); #endif #ifdef sun /* broken Sun ruserok() sets process so it appears to be owned */ /* by the luser, change it back for cosmetic reasons */ if (setuid(0) == -1) { log_err(errno, "site_check_user_map", "cannot go back to root"); exit(1); } #endif /* sun */ return (rc); }
int set_objexid(void *pobj, int objtype, attribute *attrry) { int addflags = 0; int isowner; attribute *pattr; char *puser; char *pgrpn; char *owner; int idx_ul, idx_gl; int idx_owner, idx_euser, idx_egroup; int idx_acct; int bad_euser, bad_egrp; attribute *objattrs; attribute_def *obj_attr_def; attribute *paclRoot; /*future: aclRoot resv != aclRoot job*/ #ifdef WIN32 char user_s[PBS_MAXHOSTNAME+ MAXNAMLEN+3]; char *p = NULL; char *p0 = NULL; int ch = '\\'; SID *sid; char *defgrp = NULL; #else char **pmem; struct group *gpent; struct passwd *pwent; char gname[PBS_MAXGRPN+1]; #endif /* determine index values and pointers based on object type */ if (objtype == JOB_OBJECT) { idx_ul = (int)JOB_ATR_userlst; idx_gl = (int)JOB_ATR_grouplst; idx_owner = (int)JOB_ATR_job_owner; idx_euser = (int)JOB_ATR_euser; idx_egroup = (int)JOB_ATR_egroup; idx_acct = (int)JOB_ATR_account; obj_attr_def = job_attr_def; objattrs = ((job *)pobj)->ji_wattr; owner = ((job *)pobj)->ji_wattr[idx_owner].at_val.at_str; paclRoot = &server.sv_attr[(int)SRV_ATR_AclRoot]; bad_euser = PBSE_BADUSER; bad_egrp = PBSE_BADGRP; } else { idx_ul = (int)RESV_ATR_userlst; idx_gl = (int)RESV_ATR_grouplst; idx_owner = (int)RESV_ATR_resv_owner; idx_euser = (int)RESV_ATR_euser; idx_egroup = (int)RESV_ATR_egroup; idx_acct = (int)RESV_ATR_account; obj_attr_def = resv_attr_def; objattrs = ((resc_resv *)pobj)->ri_wattr; owner = ((resc_resv *)pobj)->ri_wattr[idx_owner].at_val.at_str; paclRoot = &server.sv_attr[(int)SRV_ATR_AclRoot]; bad_euser = PBSE_R_UID; bad_egrp = PBSE_R_GID; } /* if passed in "User_List" attribute is set use it - this may * be a newly modified one. * if not set, fall back to the object's User_List, which may * actually be the same as what is passed into this function */ if ((attrry + idx_ul)->at_flags & ATR_VFLAG_SET) pattr = attrry + idx_ul; else pattr = &objattrs[idx_ul]; if ((puser = determine_euser(pobj, objtype, pattr, &isowner)) == NULL) return (bad_euser); #ifdef WIN32 if (isAdminPrivilege(puser)) { /* equivalent of root */ if ((paclRoot->at_flags & ATR_VFLAG_SET) == 0) return (bad_euser); /* root not allowed */ if (acl_check(paclRoot, owner, ACL_User) == 0) return (bad_euser); /* root not allowed */ } #else pwent = getpwnam(puser); if (pwent == NULL) { if (!server.sv_attr[(int)SRV_ATR_FlatUID].at_val.at_long) return (bad_euser); } else if (pwent->pw_uid == 0) { if ((paclRoot->at_flags & ATR_VFLAG_SET) == 0) return (bad_euser); /* root not allowed */ if (acl_check(paclRoot, owner, ACL_User) == 0) return (bad_euser); /* root not allowed */ } #endif if (!isowner || !server.sv_attr[(int)SRV_ATR_FlatUID].at_val.at_long) { #ifdef WIN32 if ( (server.sv_attr[SRV_ATR_ssignon_enable].at_flags & \ ATR_VFLAG_SET) && \ (server.sv_attr[SRV_ATR_ssignon_enable].at_val.at_long \ == 1) ) { /* read/cache user password */ cache_usertoken_and_homedir(puser, NULL, 0, user_read_password, (char *)puser, pbs_decrypt_pwd, 0); } else { /* read/cache job password */ cache_usertoken_and_homedir(puser, NULL, 0, read_cred, (job *)pobj, pbs_decrypt_pwd, 0); } #endif if (site_check_user_map(pobj, objtype, puser) == -1) return (bad_euser); } pattr = &objattrs[idx_euser]; obj_attr_def[idx_euser].at_free(pattr); obj_attr_def[idx_euser].at_decode(pattr, NULL, NULL, puser); #ifndef WIN32 if (pwent != NULL) { #endif /* if account (qsub -A) is not specified, set to empty string */ pattr = &objattrs[idx_acct]; if ((pattr->at_flags & ATR_VFLAG_SET) == 0) { (void)obj_attr_def[idx_acct].at_decode(pattr, NULL, NULL, "\0"); } /* * now figure out (for this host) the effective/execute "group name" * for the object. * PBS requires that each group have an entry in the group file, * see the admin guide for the reason why... * * use the passed group_list if set, may be a newly modified one. * if it isn't set, use the object's group_list, which may in fact * be same as what was passed */ if ((attrry + idx_gl)->at_flags & ATR_VFLAG_SET) pattr = attrry + idx_gl; else pattr = &objattrs[idx_gl]; if ((pgrpn = determine_egroup(pobj, objtype, pattr)) != NULL) { /* user specified a group, group must exists and either */ /* must be user's primary group or the user must be in it */ #ifdef WIN32 if ((sid=getgrpsid(pgrpn)) == NULL) return (bad_egrp); /* no such group */ (void)LocalFree(sid); #else gpent = getgrnam(pgrpn); if (gpent == NULL) { if (pwent != NULL) /* no such group is allowed */ return (bad_egrp); /* only when no user (flatuid)*/ } else if (gpent->gr_gid != pwent->pw_gid) { /* not primary */ pmem = gpent->gr_mem; while (*pmem) { if (!strcmp(puser, *pmem)) break; ++pmem; } if (*pmem == 0) return (bad_egrp); /* user not in group */ } #endif addflags = ATR_VFLAG_SET; } else { /* Use user login group */ #ifdef WIN32 if ((defgrp=getdefgrpname(puser)) == NULL) return (bad_egrp); /* set to a group that ALL users belong to as default */ pgrpn = defgrp; #else gpent = getgrgid(pwent->pw_gid); if (gpent != NULL) { pgrpn = gpent->gr_name; /* use group name */ } else { (void)sprintf(gname, "%d", pwent->pw_gid); pgrpn = gname; /* turn gid into string */ } #endif /* * setting the DEFAULT flag is a "kludy" way to keep MOM from * having to do an unneeded look up of the group file. * We needed to have JOB_ATR_egroup set for the server but * MOM only wants it if it is not the login group, so there! */ addflags = ATR_VFLAG_SET | ATR_VFLAG_DEFLT; } #ifndef WIN32 } else { /* * null password entry, * set group to "default" and set default for Mom to use login group */ pgrpn = "-default-"; addflags = ATR_VFLAG_SET | ATR_VFLAG_DEFLT; } #endif pattr = attrry + idx_egroup; obj_attr_def[idx_egroup].at_free(pattr); if (addflags != 0) { obj_attr_def[idx_egroup].at_decode(pattr, NULL, NULL, pgrpn); pattr->at_flags |= addflags; } #ifdef WIN32 if (defgrp) (void)free(defgrp); #endif return (0); }
int main(int argc, char **argv) #endif /* WIN32 */ { #ifdef WIN32 struct arg_param *p = (struct arg_param *)pv; int argc; char **argv; SERVICE_STATUS ss; #endif /* WIN32 */ char *name = NULL; struct tpp_config conf; int rpp_fd; char *pc; int numthreads; char lockfile[MAXPATHLEN + 1]; char path_log[MAXPATHLEN + 1]; char svr_home[MAXPATHLEN + 1]; char *log_file = 0; char *host; int port; char *routers = NULL; int c, i, rc; extern char *optarg; int are_primary; int num_var_env; #ifndef WIN32 struct sigaction act; struct sigaction oact; #endif #ifndef WIN32 /*the real deal or just pbs_version and exit*/ execution_mode(argc, argv); #endif /* As a security measure and to make sure all file descriptors */ /* are available to us, close all above stderr */ #ifdef WIN32 _fcloseall(); #else i = sysconf(_SC_OPEN_MAX); while (--i > 2) (void)close(i); /* close any file desc left open by parent */ #endif /* If we are not run with real and effective uid of 0, forget it */ #ifdef WIN32 argc = p->argc; argv = p->argv; ZeroMemory(&ss, sizeof(ss)); ss.dwCheckPoint = 0; ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ss.dwCurrentState = g_dwCurrentState; ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; ss.dwWaitHint = 6000; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); if (!isAdminPrivilege(getlogin())) { fprintf(stderr, "%s: Must be run by root\n", argv[0]); return (2); } #else if ((getuid() != 0) || (geteuid() != 0)) { fprintf(stderr, "%s: Must be run by root\n", argv[0]); return (2); } #endif /* WIN32 */ /* set standard umask */ #ifndef WIN32 umask(022); #endif /* load the pbs conf file */ if (pbs_loadconf(0) == 0) { fprintf(stderr, "%s: Configuration error\n", argv[0]); return (1); } umask(022); #ifdef WIN32 save_env(); #endif /* The following is code to reduce security risks */ /* start out with standard umask, system resource limit infinite */ if ((num_var_env = setup_env(pbs_conf.pbs_environment)) == -1) { #ifdef WIN32 g_dwCurrentState = SERVICE_STOPPED; ss.dwCurrentState = g_dwCurrentState; ss.dwWin32ExitCode = ERROR_INVALID_ENVIRONMENT; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); return (1); #else exit(1); #endif /* WIN32 */ } #ifndef WIN32 i = getgid(); (void)setgroups(1, (gid_t *)&i); /* secure suppl. groups */ #endif log_event_mask = &pbs_conf.pbs_comm_log_events; tpp_set_logmask(*log_event_mask); #ifdef WIN32 winsock_init(); #endif routers = pbs_conf.pbs_comm_routers; numthreads = pbs_conf.pbs_comm_threads; server_host[0] = '\0'; if (pbs_conf.pbs_comm_name) { name = pbs_conf.pbs_comm_name; host = tpp_parse_hostname(name, &port); if (host) snprintf(server_host, sizeof(server_host), "%s", host); free(host); host = NULL; } else if (pbs_conf.pbs_leaf_name) { char *endp; snprintf(server_host, sizeof(server_host), "%s", pbs_conf.pbs_leaf_name); endp = strchr(server_host, ','); /* find the first name */ if (endp) *endp = '\0'; endp = strchr(server_host, ':'); /* cut out the port */ if (endp) *endp = '\0'; name = server_host; } else { if (gethostname(server_host, (sizeof(server_host) - 1)) == -1) { #ifndef WIN32 sprintf(log_buffer, "Could not determine my hostname, errno=%d", errno); #else sprintf(log_buffer, "Could not determine my hostname, errno=%d", WSAGetLastError()); #endif fprintf(stderr, "%s\n", log_buffer); return (1); } if ((get_fullhostname(server_host, server_host, (sizeof(server_host) - 1)) == -1)) { sprintf(log_buffer, "Could not determine my hostname"); fprintf(stderr, "%s\n", log_buffer); return (1); } name = server_host; } if (server_host[0] == '\0') { sprintf(log_buffer, "Could not determine server host"); fprintf(stderr, "%s\n", log_buffer); return (1); } while ((c = getopt(argc, argv, "r:t:e:N")) != -1) { switch (c) { case 'e': *log_event_mask = strtol(optarg, NULL, 0); break; case 'r': routers = optarg; break; case 't': numthreads = atol(optarg); if (numthreads == -1) { usage(argv[0]); return (1); } break; case 'N': stalone = 1; break; default: usage(argv[0]); return (1); } } (void)strcpy(daemonname, "Comm@"); (void)strcat(daemonname, name); if ((pc = strchr(daemonname, (int)'.')) != NULL) *pc = '\0'; if(set_msgdaemonname(daemonname)) { fprintf(stderr, "Out of memory\n"); return 1; } (void) snprintf(path_log, sizeof(path_log), "%s/%s", pbs_conf.pbs_home_path, PBS_COMM_LOGDIR); #ifdef WIN32 /* * let SCM wait 10 seconds for log_open() to complete * as it does network interface query which can take time */ ss.dwCheckPoint++; ss.dwWaitHint = 60000; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); #endif (void) log_open(log_file, path_log); /* set pbs_comm's process limits */ set_limits(); /* set_limits can call log_record, so call only after opening log file */ /* set tcp function pointers */ set_tpp_funcs(log_tppmsg); (void) snprintf(svr_home, sizeof(svr_home), "%s/%s", pbs_conf.pbs_home_path, PBS_SVR_PRIVATE); if (chdir(svr_home) != 0) { (void) sprintf(log_buffer, msg_init_chdir, svr_home); log_err(-1, __func__, log_buffer); return (1); } (void) sprintf(lockfile, "%s/%s/comm.lock", pbs_conf.pbs_home_path, PBS_SVR_PRIVATE); if ((are_primary = are_we_primary()) == FAILOVER_SECONDARY) { strcat(lockfile, ".secondary"); } else if (are_primary == FAILOVER_CONFIG_ERROR) { sprintf(log_buffer, "Failover configuration error"); log_err(-1, __func__, log_buffer); #ifdef WIN32 g_dwCurrentState = SERVICE_STOPPED; ss.dwCurrentState = g_dwCurrentState; ss.dwWin32ExitCode = ERROR_SERVICE_NOT_ACTIVE; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); #endif return (3); } if ((lockfds = open(lockfile, O_CREAT | O_WRONLY, 0600)) < 0) { (void) sprintf(log_buffer, "pbs_comm: unable to open lock file"); log_err(errno, __func__, log_buffer); return (1); } if ((host = tpp_parse_hostname(name, &port)) == NULL) { sprintf(log_buffer, "Out of memory parsing leaf name"); log_err(errno, __func__, log_buffer); return (1); } rc = 0; if (pbs_conf.auth_method == AUTH_RESV_PORT) { rc = set_tpp_config(&pbs_conf, &conf, host, port, routers, pbs_conf.pbs_use_compression, TPP_AUTH_RESV_PORT, NULL, NULL); } else { /* for all non-resv-port based authentication use a callback from TPP */ rc = set_tpp_config(&pbs_conf, &conf, host, port, routers, pbs_conf.pbs_use_compression, TPP_AUTH_EXTERNAL, get_ext_auth_data, validate_ext_auth_data); } if (rc == -1) { (void) sprintf(log_buffer, "Error setting TPP config"); log_err(-1, __func__, log_buffer); return (1); } free(host); i = 0; if (conf.routers) { while (conf.routers[i]) { sprintf(log_buffer, "Router[%d]:%s", i, conf.routers[i]); fprintf(stdout, "%s\n", log_buffer); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_INFO, msg_daemonname, log_buffer); i++; } } #ifndef DEBUG #ifndef WIN32 if (stalone != 1) go_to_background(); #endif #endif #ifdef WIN32 ss.dwCheckPoint = 0; g_dwCurrentState = SERVICE_RUNNING; ss.dwCurrentState = g_dwCurrentState; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); #endif if (already_forked == 0) lock_out(lockfds, F_WRLCK); /* go_to_backgroud call creates a forked process, * thus print/log pid only after go_to_background() * has been called */ sprintf(log_buffer, "%s ready (pid=%d), Proxy Name:%s, Threads:%d", argv[0], getpid(), conf.node_name, numthreads); fprintf(stdout, "%s\n", log_buffer); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_INFO, msg_daemonname, log_buffer); #ifndef DEBUG pbs_close_stdfiles(); #endif #ifdef WIN32 signal(SIGINT, stop_me); signal(SIGTERM, stop_me); #else sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = hup_me; if (sigaction(SIGHUP, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for HUP"); return (2); } act.sa_handler = stop_me; if (sigaction(SIGINT, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for INT"); return (2); } if (sigaction(SIGTERM, &act, &oact) != 0) { log_err(errno, __func__, "sigactin for TERM"); return (2); } if (sigaction(SIGQUIT, &act, &oact) != 0) { log_err(errno, __func__, "sigactin for QUIT"); return (2); } #ifdef SIGSHUTDN if (sigaction(SIGSHUTDN, &act, &oact) != 0) { log_err(errno, __func__, "sigactin for SHUTDN"); return (2); } #endif /* SIGSHUTDN */ act.sa_handler = SIG_IGN; if (sigaction(SIGPIPE, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for PIPE"); return (2); } if (sigaction(SIGUSR1, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for USR1"); return (2); } if (sigaction(SIGUSR2, &act, &oact) != 0) { log_err(errno, __func__, "sigaction for USR2"); return (2); } #endif /* WIN32 */ conf.node_type = TPP_ROUTER_NODE; conf.numthreads = numthreads; if ((rpp_fd = tpp_init_router(&conf)) == -1) { log_err(-1, __func__, "tpp init failed\n"); return 1; } /* Protect from being killed by kernel */ daemon_protect(0, PBS_DAEMON_PROTECT_ON); /* go in a while loop */ while (get_out == 0) { if (hupped == 1) { struct pbs_config pbs_conf_bak; int new_logevent; hupped = 0; /* reset back */ memcpy(&pbs_conf_bak, &pbs_conf, sizeof(struct pbs_config)); if (pbs_loadconf(1) == 0) { log_tppmsg(LOG_CRIT, NULL, "Configuration error, ignoring"); memcpy(&pbs_conf, &pbs_conf_bak, sizeof(struct pbs_config)); } else { /* restore old pbs.conf */ new_logevent = pbs_conf.pbs_comm_log_events; memcpy(&pbs_conf, &pbs_conf_bak, sizeof(struct pbs_config)); pbs_conf.pbs_comm_log_events = new_logevent; log_tppmsg(LOG_INFO, NULL, "Processed SIGHUP"); log_event_mask = &pbs_conf.pbs_comm_log_events; tpp_set_logmask(*log_event_mask); } } sleep(3); } tpp_router_shutdown(); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_NOTICE, msg_daemonname, "Exiting"); log_close(1); lock_out(lockfds, F_UNLCK); /* unlock */ (void)close(lockfds); (void)unlink(lockfile); return 0; }
/** * @brief * The main function in C - entry point * * @param[in] argc - argument count * @param[in] argv - pointer to argument array * * @return int * @retval 0 - success * @retval !0 - error */ int main(int argc, char *argv[]) { int i, rc; char passwd[MAX_PASSWORD_LEN + 1] = {'\0'}; char passwd2[MAX_PASSWORD_LEN + 1]; char *pquoted; char pwd_file[MAXPATHLEN + 1]; char userid[LOGIN_NAME_MAX + 1]; int fd, errflg = 0; int gen_pwd = 0; char sqlbuff[1024]; int db_conn_error=0; char *db_errmsg = NULL; int pmode; int change_user = 0; char *olduser; int update_db = 0; char getopt_format[5]; char prog[]="pbs_ds_password"; char errmsg[PBS_MAX_DB_CONN_INIT_ERR + 1]; conn = NULL; pwd_file_new[0]=0; /*test for real deal or just version and exit*/ PRINT_VERSION_AND_EXIT(argc, argv); /* read configuration file */ if (pbs_loadconf(0) == 0) { fprintf(stderr, "%s: Could not load pbs configuration\n", prog); return (-1); } /* backup old user name */ if ((olduser = pbs_get_dataservice_usr(errmsg, PBS_MAX_DB_CONN_INIT_ERR)) == NULL) { fprintf(stderr, "%s: Could not retrieve current data service user\n", prog); if (strlen(errmsg) > 0) fprintf(stderr, "%s\n", errmsg); return (-1); } if (pbs_conf.pbs_data_service_host == NULL) update_db = 1; userid[0]=0; /* empty user id */ strcpy(getopt_format, "rC:"); while ((i = getopt(argc, argv, getopt_format)) != EOF) { switch (i) { case 'r': gen_pwd = 1; break; case 'C': strcpy(userid, optarg); break; case '?': default: errflg++; } } if (errflg) { fprintf(stderr, "\nusage:\t%s [-r] [-C username]\n", prog); fprintf(stderr, " \t%s --version\n", prog); return (-1); } /* NOTE : This functionality is added just for the automation testing purpose. * Usage: pbs_ds_password <password> */ if (argv[optind] != NULL) { gen_pwd = 0; strncpy(passwd, argv[optind], sizeof(passwd)); passwd[sizeof(passwd) - 1] = '\0'; } /* check admin privileges */ #ifdef WIN32 if (!isAdminPrivilege(getlogin())) { fprintf(stderr, "pbs_ds_password: Must be run by Admin\n"); return (1); } #else if ((getuid() != 0) || (geteuid() != 0)) { fprintf(stderr, "%s: Must be run by root\n", prog); return (1); } #endif /* WIN32 */ change_user = 0; /* if the -C option was specified read the user from pbs.conf */ if (userid[0] != 0) { if (strcmp(olduser, userid) != 0) { change_user = 1; } } if (change_user == 1) { /* check that the supplied user-id exists (and is non-root on unix) */ if (check_user(userid) != 0) { #ifdef WIN32 fprintf(stderr, "\n%s: User-id %s does not exist\n", prog, userid); #else fprintf(stderr, "\n%s: User-id %s does not exist/is root user/home dir is not accessible\n", prog, userid); #endif return (-1); } } atexit(cleanup); if (update_db == 1) { /* then connect to database */ conn = pbs_db_init_connection(NULL, PBS_DB_CNT_TIMEOUT_NORMAL, 1, &db_conn_error, errmsg, PBS_MAX_DB_CONN_INIT_ERR); if (!conn) { get_db_errmsg(db_conn_error, &db_errmsg); fprintf(stderr, "%s: %s\n", prog, db_errmsg); if (strlen(errmsg) > 0) fprintf(stderr, "%s\n", errmsg); return -1; } db_conn_error = pbs_db_connect(conn); if (db_conn_error == PBS_DB_SUCCESS && change_user == 1) { /* able to connect ? Thats bad, PBS or dataservice is running */ fprintf(stderr, "%s: PBS Services and/or PBS Data Service is running\n", prog); fprintf(stderr, " Stop PBS and Data Services before changing Data Service user\n"); return (-1); } if (db_conn_error != PBS_DB_SUCCESS) { if (db_conn_error == PBS_DB_CONNREFUSED) { /* start db only if it was not already running */ if (pbs_startup_db(&db_errmsg) != 0) { if (db_errmsg) fprintf(stderr, "%s: Failed to start PBS dataservice:[%s]\n", prog, db_errmsg); else fprintf(stderr, "%s: Failed to start PBS dataservice\n", prog); return (-1); } started_db = 1; } db_conn_error = pbs_db_connect(conn); if (db_conn_error != PBS_DB_SUCCESS) { get_db_errmsg(db_conn_error, &db_errmsg); if (conn->conn_db_err) fprintf(stderr, "%s: Could not connect to PBS data service:%s:[%s]\n", prog, db_errmsg, (char*)conn->conn_db_err); else fprintf(stderr, "%s: Could not connect to PBS data service:%s\n", prog, db_errmsg); return (-1); } } } if (gen_pwd == 0 && passwd[0] == '\0') { /* ask user to enter password twice */ printf("Enter the password:"******"\nRe-enter the password:"******"\n\n"); if (strcmp(passwd, passwd2) != 0) { fprintf(stderr, "Entered passwords do not match\n"); return (-2); } if (strlen(passwd) == 0) { fprintf(stderr, "Blank password is not allowed\n"); return (-2); } } else if (gen_pwd == 1) { gen_password(passwd, 16); } rc = pbs_encrypt_pwd(passwd, &cred_type, &cred_buf, &cred_len); if (rc != 0) { fprintf(stderr, "%s: Failed to encrypt password\n", prog); return (-1); } /* escape password to use in sql strings later */ if ((pquoted = pbs_db_escape_str(conn, passwd)) == NULL) { fprintf(stderr, "%s: Out of memory\n", prog); return -1; } #ifdef WIN32 sprintf(pwd_file_new, "%s\\server_priv\\db_password.new", pbs_conf.pbs_home_path); sprintf(pwd_file, "%s\\server_priv\\db_password", pbs_conf.pbs_home_path); #else sprintf(pwd_file_new, "%s/server_priv/db_password.new", pbs_conf.pbs_home_path); sprintf(pwd_file, "%s/server_priv/db_password", pbs_conf.pbs_home_path); #endif /* write encrypted password to the password file */ #ifdef WIN32 pmode = _S_IWRITE | _S_IREAD; fix_perms2(pwd_file_new, pwd_file); if ((fd = open(pwd_file_new, O_WRONLY | O_TRUNC | O_CREAT | O_Sync | O_BINARY, pmode)) == -1) #else pmode = 0600; if ((fd = open(pwd_file_new, O_WRONLY | O_TRUNC | O_CREAT | O_Sync, pmode)) == -1) #endif { perror("open/create failed"); fprintf(stderr, "%s: Unable to create file %s\n", prog, pwd_file_new); return (-1); } #ifdef WIN32 secure_file(pwd_file_new, "Administrators", READS_MASK|WRITES_MASK|STANDARD_RIGHTS_REQUIRED); setmode(fd, O_BINARY); #endif if (update_db == 1) { /* change password only if this config option is not set */ if (pbs_db_begin_trx(conn, 0, 0) != 0) { fprintf(stderr, "%s: Could not start transaction\n", prog); unlink(pwd_file_new); return -1; } if (change_user == 1) { /* check whether user exists */ snprintf(sqlbuff, sizeof(sqlbuff), "select usename from pg_user where usename = '%s'", userid); if (pbs_db_execute_str(conn, sqlbuff) == 1) { /* now attempt to create new user & set the database passwd to the un-encrypted password */ snprintf(sqlbuff, sizeof(sqlbuff), "create user \"%s\" SUPERUSER ENCRYPTED PASSWORD '%s'", userid, pquoted); } else { /* attempt to alter new user & set the database passwd to the un-encrypted password */ snprintf(sqlbuff, sizeof(sqlbuff), "alter user \"%s\" SUPERUSER ENCRYPTED PASSWORD '%s'", userid, pquoted); } memset(passwd, 0, sizeof(passwd)); memset(passwd2, 0, sizeof(passwd2)); memset(pquoted, 0, (sizeof(char) * strlen(pquoted))); if (pbs_db_execute_str(conn, sqlbuff) == -1) { fprintf(stderr, "%s: Failed to create/alter user id %s\n", prog, userid); (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); return -1; } } else { /* now attempt to set the database passwd to the un-encrypted password */ /* alter user ${user} SUPERUSER ENCRYPTED PASSWORD '${passwd}' */ sprintf(sqlbuff, "alter user \"%s\" SUPERUSER ENCRYPTED PASSWORD '%s'", olduser, pquoted); memset(passwd, 0, sizeof(passwd)); memset(passwd2, 0, sizeof(passwd2)); memset(pquoted, 0, (sizeof(char) * strlen(pquoted))); if (pbs_db_execute_str(conn, sqlbuff) == -1) { fprintf(stderr, "%s: Failed to create/alter user id %s\n", prog, userid); (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); return -1; } } } if (write(fd, cred_buf, cred_len) != cred_len) { perror("write failed"); fprintf(stderr, "%s: Unable to write to file %s\n", prog, pwd_file_new); if (update_db == 1) { (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); } return -1; } close(fd); free(cred_buf); #ifdef WIN32 if (MoveFileEx(pwd_file_new, pwd_file, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) == 0) { errno = GetLastError(); fprintf(stderr, "MoveFileEx(%s, %s) failed!", pwd_file_new, pwd_file); if (update_db == 1) { (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); } return (-1); } #else if (rename(pwd_file_new, pwd_file) != 0) { if (update_db == 1) { (void) pbs_db_end_trx(conn, PBS_DB_ROLLBACK); } return (-1); } #endif if (update_db == 1) { /* commit to database */ (void) pbs_db_end_trx(conn, PBS_DB_COMMIT); cleanup(); /* cleanup will disconnect and delete tmp file too */ } printf("---> Updated user password\n"); if (update_db == 1 && change_user == 1) { printf("---> Updated user in datastore\n"); printf("---> Stored user password in datastore\n"); } if (change_user == 1) { char usr_file[MAXPATHLEN + 1]; #ifdef WIN32 sprintf(usr_file, "%s\\server_priv\\db_user", pbs_conf.pbs_home_path); #else sprintf(usr_file, "%s/server_priv/db_user", pbs_conf.pbs_home_path); #endif /* update PBS_HOME/server_priv/db_user file with the new user name */ if (update_db_usr(usr_file, userid) != 0) { fprintf(stderr, "Unable to update file %s\n", usr_file); return -1; } printf("---> Updated new user\n"); } if (update_db == 1 && change_user == 1) { char datastore[MAXPATHLEN + 1]; #ifndef WIN32 /* ownership is changed only for Unix users * On windows, these files are allways owned by the user who installed the database * and writable by administrators anyway */ sprintf(datastore, "%s/datastore", pbs_conf.pbs_home_path); /* change ownership of the datastore directories to the new user, so that db can be started again */ if (change_ownership(datastore, userid) != 0) { fprintf(stderr, "%s: Failed to change ownership on path %s\n", prog, datastore); return -1; } printf("---> Changed ownership of %s to user %s\n", datastore, userid); #endif /* reload configuration file */ if (pbs_loadconf(1) == 0) { fprintf(stderr, "%s: Could not load pbs configuration\n", prog); return (-1); } if (pbs_startup_db(&db_errmsg) != 0) { if (db_errmsg) fprintf(stderr, "%s: Failed to start PBS dataservice as new user:[%s]\n", prog, db_errmsg); else fprintf(stderr, "%s: Failed to start PBS dataservice as new user\n", prog); return (-1); } started_db = 1; /* connect again to drop the old user */ conn = pbs_db_init_connection(NULL, PBS_DB_CNT_TIMEOUT_NORMAL, 1, &db_conn_error, errmsg, PBS_MAX_DB_CONN_INIT_ERR); if (!conn) { get_db_errmsg(db_conn_error, &db_errmsg); fprintf(stderr, "%s: %s\n", prog, db_errmsg); if (strlen(errmsg) > 0) fprintf(stderr, "%s\n", errmsg); return -1; } db_conn_error = pbs_db_connect(conn); if (db_conn_error != PBS_DB_SUCCESS) { get_db_errmsg(db_conn_error, &db_errmsg); if (conn->conn_db_err) fprintf(stderr, "%s: Could not connect to PBS data service as new user:%s[%s]\n", prog, db_errmsg, (char*)conn->conn_db_err); else fprintf(stderr, "%s: Could not connect to PBS data service as new user:%s\n", prog, db_errmsg); return (-1); } /* delete the old user from the database */ sprintf(sqlbuff, "drop user \"%s\"", olduser); pbs_db_execute_str(conn, sqlbuff); } printf("---> Success\n"); return (0); }