Exemplo n.º 1
0
/*
** Name: PCexec_suid - Execute a command as the ingres user.
**
** Description:
**	This procedure works with the Ingres service to run the given
**	command as the ingres user. It mimicks the "setuid" bit in UNIX.
**
** Inputs:
**	cmdbuf - command to execute as the ingres user
**
** Outputs:
**	none
**
** Returns:
**	OK
**	FAIL
**
** Side Effects:
**	none
**
** History:
**	08-jan-1998 (somsa01)
**	    Created.
**	19-feb-1998 (somsa01)
**	    We need to pass to the service the current working directory
**	    as well.  (Bug #89006)
**	25-feb-1998 (somsa01)
**	    We now have an input file for the process' stdin which
**	    runs through the OpenIngres service.
**	19-jun-1998 (somsa01)
**	    Use SYSTEM_PRODUCT_NAME for the name of the service.
**	10-jul-1998 (kitch01)
**		Bug 91362. If user is 'system' run through OpenIngres service
**		despite having access to server shared memory 'system' does not
**		have required privilege to access semaphores/mutexes.
**	11-jun-1999 (somsa01)
**	    If the command is a startup command, then it is always run through
**	    the Ingres service.
**	03-nov-1999 (somsa01)
**	    A failure from ControlService() should be treated as a severe
**	    error which should not let us continue.
** 	22-jan-2000 (somsa01)
**	    Return the exit code of the spawned process. Also, if the
**	    files exist, truncate them. The service name is now keyed off
**	    of II_INSTALLATION.
**	05-jun-2000 (somsa01)
**	    The Ingres installation may be started as the SYSTEM account,
**	    in which the 'ingres' user will not automatically have access
**	    to the shared memory segments. Therefore, even if the real
**	    user is 'ingres', check to see if he has access.
**	24-oct-2000 (somsa01)
**	    Removed the check on shared memory access. Access to the shared
**	    memory segment does not necessarily mean that the user running
**	    the process does not need to run the specified process as the
**	    Ingres owner. Also, generalized the check of the user with
**	    IDname_service().
**	18-dec-2000 (somsa01)
**	    Modified the cases to run the command "as is" without the Ingres
**	    service.
**	20-mar-2002 (somsa01)
**	    If all is well, return the exit code of the child process that
**	    was executed.
**	29-mar-2002 (somsa01)
**	    Properly return the child process exit code.
**	11-apr-2003 (somsa01)
**	    While waiting for "pending" to not be set, give some CPU back
**	    to the OS.
**      29-Jul-2005 (drivi01)
**	    Allow user to run the command if he/she owns a shared
**	    segment and ingres is not running as a service.
**	06-Dec-2006 (drivi01)
**	    Adding support for Vista, Vista requires "Global\" prefix for
**	    shared objects as well.  Replacing calls to GVosvers with 
**	    GVshobj which returns the prefix to shared objects.
**	    Added PCadjust_SeDebugPrivilege to allow quering of 
**	    System processes.
**	25-Jul-2007 (drivi01)
**		On Vista, PCexec_suid is unable to use SE_DEBUG Privilege
**	    to query process status and retireve its exit code.
**		The routine for monitoring a process and retrieving 
**	    its exit code has been moved to Ingres Service.
**	05-Nov-2009 (wanfr01) b122847
**	    Don't do a PCsleep unless you are waiting for more input
*/
STATUS
PCexec_suid(char *cmdbuf)
{
    EX_CONTEXT		context;
    SERVICE_STATUS	ssServiceStatus;
    LPSERVICE_STATUS	lpssServiceStatus = &ssServiceStatus;
    struct SETUID	setuid;
    DWORD		ProcID;
    HANDLE		SaveStdout;
    SECURITY_ATTRIBUTES	sa;
    CHAR		szRealUserID[25] = "";
    CHAR		*pszRealUserID = szRealUserID;
    CHAR		szServiceUserID[25] = "";
    CHAR		*pszServiceUserID = szServiceUserID;
    DWORD		BytesWritten, BytesRead = 0;
    CHAR		*inst_id;
    CHAR		SetuidShmName[64];
    CHAR		*temp_loc;
    CHAR		InBuf[256], OutBuf[256];
    static CHAR		SetuidPipeName[32];
    CL_ERR_DESC		err_code;
    CHAR		ServiceName[255];
    DWORD		ExitCode = 0;
    CHAR		tchII_INSTALLATION[3];
    BOOL		SetuidDbCmd = FALSE, ServiceCommand = FALSE;
    int			i, cmdlen;
    char		*ObjectPrefix;
	u_i4		drType;
    SC_HANDLE		schSCManager, OpIngSvcHandle;
    BOOL		bServiceStarted = FALSE;

    if (EXdeclare(ex_handler, &context) != OK)
    {
	EXdelete();
	PCexit(FAIL);
    }
    NMgtAt("II_INSTALLATION", &inst_id);
    STcopy(inst_id, tchII_INSTALLATION);

    /*
    ** See if this is a command that MUST be run through the Ingres
    ** service.
    */
    cmdlen = (i4)STlength(cmdbuf);
    for (i = 0; ServiceCommands[i] ; i++)
    {
	if (STbcompare( cmdbuf, cmdlen, ServiceCommands[i],
			(i4)STlength(ServiceCommands[i]), FALSE ) == 0)
	{
	    ServiceCommand = TRUE;
	    break;
	}
    }

    /*
    ** If the user is the same as the user who started the Ingres
    ** service, just spawn the command.
    */
    if (!ServiceCommand)
    {
	IDname(&pszRealUserID);
	if (!IDname_service(&pszServiceUserID) &&
	    STcompare(pszServiceUserID, pszRealUserID) == 0 && 
		PCisAdmin())
	{
	    /*
	    ** Attempt to just execute the command.
	    */
	    return( PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT,
		    (LOCATION *) NULL, &err_code) );
	}
	else
	{
	    /*
	    ** If current user is not the same as service user and ingres is not
	    ** running as a service, check if shared memory segment is owned
	    ** by current user, if user has access to shared segment allow him
	    ** to run the command.
	    */
	    PTR	shmem;
	    SIZE_TYPE	allocated_pages=0;
	    STATUS status;

	    if((status = MEget_pages(ME_MSHARED_MASK, 1, "lglkdata.mem",
	                 &shmem, &allocated_pages, &err_code)) == OK)
	    {
	        STprintf(ServiceName, "%s_Database_%s", SYSTEM_SERVICE_NAME, 
		tchII_INSTALLATION);
	        if ((schSCManager = OpenSCManager(NULL, NULL, 
					SC_MANAGER_CONNECT)) != NULL)
	        {
		    if ((OpIngSvcHandle = OpenService(schSCManager, ServiceName,
					SERVICE_QUERY_STATUS)) != NULL)
		    {
		       if (QueryServiceStatus(OpIngSvcHandle,lpssServiceStatus))
		       {
		    	if (ssServiceStatus.dwCurrentState != SERVICE_STOPPED)
			     bServiceStarted = TRUE;
		        }
		    }
	        }	
	        if (!bServiceStarted)
		    return(PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT,
			(LOCATION *) NULL, &err_code) );
	    }

	}

	/*
	** See if this command is an Ingres command which needs to interact
	** with at least one database.
	*/
	for (i = 0; validSetuidDbCmds[i] ; i++)
	{
	    if (STbcompare( cmdbuf, cmdlen, validSetuidDbCmds[i],
			    (i4)STlength(validSetuidDbCmds[i]), FALSE ) == 0)
	    {
		SetuidDbCmd = TRUE;
		break;
	    }
	}

	/*
	** If the user has access to the Ingres shared memory segment,
	** just spawn the command provided that it is not in the
	** validSetuidDbCmds list.
	*/
	if (!SetuidDbCmd)
	{
	    PTR	shmem;
	    SIZE_TYPE	allocated_pages=0;
	    STATUS	status;

	    if (((status = MEget_pages(ME_MSHARED_MASK, 1, "lglkdata.mem",
		&shmem,
		&allocated_pages, &err_code)) == OK) ||
		(status == ME_NO_SUCH_SEGMENT))
	    {
		if (status != ME_NO_SUCH_SEGMENT)
		    MEfree_pages(shmem, allocated_pages, &err_code);
		
		return( PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT,
			(LOCATION *) NULL, &err_code) );
	    }
	}
    }

    /*
    ** We must run the command through the Ingres service.
    */

    if ( STstrindex(cmdbuf, "-silent", 0, FALSE ) )
	SilentMode = TRUE;

    iimksec(&sa);


	GVshobj(&ObjectPrefix);
	STprintf(SetuidShmName, "%s%sSetuidShm", ObjectPrefix, tchII_INSTALLATION);

    if ( (SetuidShmHandle = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE,
					    FALSE,
					    SetuidShmName)) == NULL )
    {
	error_exit(GetLastError());
	return(FAIL);
    }
    if ( (SetuidShmPtr = MapViewOfFile(SetuidShmHandle,
				       FILE_MAP_WRITE | FILE_MAP_READ,
				       0,
				       0,
				       sizeof(struct SETUID_SHM))) == NULL )
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    /* Set up the information to send to the service. */
    STcopy(cmdbuf, setuid.cmdline);
    GetCurrentDirectory(sizeof(setuid.WorkingDirectory),
			setuid.WorkingDirectory);
	NMgtAt("II_TEMPORARY", &temp_loc);
	drType = GetDriveType(NULL);
	if (drType == DRIVE_REMOTE)
	{
		STcopy(temp_loc, setuid.WorkingDirectory);
	}
    SaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    CVla(GetCurrentProcessId(), setuid.ClientProcID);
    STprintf(SetuidPipeName, "\\\\.\\PIPE\\INGRES\\%s\\SETUID", inst_id);

    /* Set up the stdout file for the command. */
    STprintf(OutfileName, "%s\\%sstdout.tmp", temp_loc, setuid.ClientProcID);
    if ( (OutFile = CreateFile(OutfileName,
			       GENERIC_READ | GENERIC_WRITE,
			       FILE_SHARE_READ | FILE_SHARE_WRITE,
			       &sa,
			       CREATE_ALWAYS,
			       FILE_ATTRIBUTE_NORMAL,
			       NULL)) == INVALID_HANDLE_VALUE )
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    /* Set up the stdin file for the command. */
    STprintf(InfileName, "%s\\%sstdin.tmp", temp_loc, setuid.ClientProcID);
    if ( (InFile = CreateFile(InfileName,
			      GENERIC_READ | GENERIC_WRITE,
			      FILE_SHARE_READ | FILE_SHARE_WRITE,
			      &sa,
			      CREATE_ALWAYS,
			      FILE_FLAG_WRITE_THROUGH,
			      NULL)) == INVALID_HANDLE_VALUE )
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    /* Wait until the service is ready to process our request. */
    while (SetuidShmPtr->pending == TRUE)
	PCsleep(100);
    SetuidShmPtr->pending = TRUE;

    /* Trigger the "setuid" event of the service. */
    if ( (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)) == NULL)
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    STprintf(ServiceName, "%s_Database_%s", SYSTEM_SERVICE_NAME,
	     tchII_INSTALLATION );
	OpIngSvcHandle = OpenService(schSCManager, ServiceName,
						SERVICE_USER_DEFINED_CONTROL);
	if (OpIngSvcHandle == NULL)
	{
		STprintf(ServiceName, "%s_DBATools_%s", SYSTEM_SERVICE_NAME,
	     tchII_INSTALLATION );
		OpIngSvcHandle = OpenService(schSCManager, ServiceName,
						SERVICE_USER_DEFINED_CONTROL);
	}
    if ( OpIngSvcHandle == NULL)
    {
	error_exit(GetLastError());
	return(FAIL);
    }
    if (!ControlService(OpIngSvcHandle, RUN_COMMAND_AS_INGRES,
			lpssServiceStatus))
    {
	error_exit(GetLastError());
	CloseServiceHandle(schSCManager);
	return(FAIL);
    }

    WaitNamedPipe(SetuidPipeName, NMPWAIT_WAIT_FOREVER);

    /* Send the information to the service. */
    if ( (Setuid_Handle = CreateFile(SetuidPipeName,
				     GENERIC_READ|GENERIC_WRITE,
				     FILE_SHARE_READ|FILE_SHARE_WRITE,
				     &sa,
				     OPEN_EXISTING,
				     FILE_ATTRIBUTE_NORMAL,
				     NULL)) == INVALID_HANDLE_VALUE )
    {
	error_exit(GetLastError());
	return(FAIL);
    }
    if (!WriteFile(Setuid_Handle, &setuid, sizeof(struct SETUID),
		   &BytesWritten, NULL))
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    /*
    ** Retrieve information back from the service, and then
    ** disconnect from the pipe.
    */
    if (!ReadFile(Setuid_Handle, &setuid, sizeof(struct SETUID),
		  &BytesRead, NULL))
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    ProcID = setuid.CreatedProcID;
    SetuidShmPtr->pending = FALSE;

    UnmapViewOfFile(SetuidShmPtr);
    SetuidShmPtr = NULL;
    CloseHandle(SetuidShmHandle);

    if ( (ProcID != -1) && (ProcID != -2) )
    {
	/*
	** Wait for the "spawned" process to exit, reading its output
	** from the stdout file.
	*/
	for (;;)
	{
	    if ( ((!ReadFile(OutFile, OutBuf, sizeof(OutBuf), &BytesRead, NULL)
		  || (BytesRead == 0)) && setuid.ExitCode != STILL_ACTIVE ))
		break;

	    if ( BytesRead &&
		 (!WriteFile(SaveStdout, OutBuf, BytesRead, &BytesWritten,
		  NULL)) && setuid.ExitCode != STILL_ACTIVE)
		break;
	    else if (BytesRead < sizeof(OutBuf))
		PCsleep(200);

	    /*
	    ** Currently, the only DBA program which can require
	    ** user input is verifydb. Therefore, when it spits out
	    ** the appropriate messages asking for user input, get
	    ** it from the end user and pass it along to the spawned
	    ** process.
	    */
	    if ( (STrstrindex(OutBuf, "S_DU04FF_CONTINUE_PROMPT", 0, FALSE)
			!= NULL) ||
		 (STrstrindex(OutBuf, "S_DU0300_PROMPT", 0, FALSE) != NULL) )
	    {
		SIflush(stdout);
		MEfill(sizeof(OutBuf), ' ', &OutBuf);
		MEfill(sizeof(InBuf), ' ', &InBuf);
		SIgetrec(InBuf, 255, 0);
		WriteFile(InFile, InBuf, sizeof(OutBuf), &BytesWritten, NULL);
	    }
	}

	ExitCode = setuid.ExitCode;
	CloseHandle(Setuid_Handle);
	CloseHandle(InFile);
	DeleteFile(InfileName);
	CloseHandle(OutFile);
	DeleteFile(OutfileName);
	CloseServiceHandle(OpIngSvcHandle);
	CloseServiceHandle(schSCManager);
        return(ExitCode);
    }
    else
    {
	error_exit(GetLastError());
	return(FAIL);
    }
}
Exemplo n.º 2
0
main(int argc, char **argv)
{
	char 			*value = NULL; 
	char			*host, *server_type, *command_line; 
	char 			*server_location, *env, *arguments;
	u_i4 			command_line_length;
	char 			config_string[256];
	char 			iidbms[256];
	STARTUPINFO 		si;
	PROCESS_INFORMATION 	ProcessInfo;
	BOOL 			Status;
	SECURITY_ATTRIBUTES     sa;
	HANDLE			hRead, hWrite;
	HANDLE			hStdout;
	char			buffer[512];
	DWORD			bufferl = sizeof(buffer);
	DWORD			pipe_size = 0;	/* Use default buffer size */
	DWORD			datal = 0;
	bool			havequote, failed = FALSE;


	MEadvise( ME_INGRES_ALLOC );

	switch (argc)
	{

	case 1:
		server_type = ERx("dbms");
		server_location = ERx("*");
		break;

	case 2:
		server_type = argv[1];
		server_location = ERx("*");
		break;

	default:
		server_type = argv[1];
    		if (STcompare(server_type, "recovery") == 0)
			server_location = ERx("*");
		else
			server_location = argv[2];
		break;

	}
	
	get_sys_dependencies();

	/*
	**	Get the host name, formally used iipmhost.
	*/
	host = PMhost();

	/*
	**	Build the string we will search for in the config.dat file.
	*/
	STprintf( config_string,
		  ERx("%s.%s.%s.%s.image_name"),
		  SystemCfgPrefix, host, server_type, server_location );

	/*
	**	Get set up for the PMget call.
	*/
	PMinit();
	if( PMload( NULL, (PM_ERR_FUNC *)NULL ) != OK )
		PCexit( FAIL );

	/*
	**	Go search config.dat for a match on the string we just built.
	*/
	PMget( config_string, &value );

	if ( value == NULL )
	{
		NMgtAt( SystemLocationVariable, &env );
		if (STcompare(server_type, "recovery") == 0)
		{
		    STprintf(iidbms, ERx("%s\\%s\\bin\\%sdbms"),
			     env, SystemLocationSubdirectory, SystemCfgPrefix);
		}
		else
		{
		    STprintf(iidbms, ERx("%s\\%s\\bin\\%s%s"),
			     env, SystemLocationSubdirectory, SystemCfgPrefix,
			     server_type);
		}
	}
	else if ( *value == '/' || 
		  *value == '\\' ||
		  (*(value+1) == ':' && *(value+2) == '\\') )
	{
		/* Must be a qualified path name */
		STcopy( value, iidbms );
	}
	else 
	{
		NMgtAt( SystemLocationVariable, &env );
		STprintf( iidbms, ERx("%s\\%s\\bin\\%s"),
			  env, SystemLocationSubdirectory, value );
	}
	
	/*
 	** 	Initialize the startinfo structure.	
	*/
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);

	/*
	**	Get the original command line.
	*/
	arguments = GetCommandLine();
        havequote = FALSE;
        while (*arguments != '\0' && *arguments != '\n')
        {
            if ( *arguments == '"' )
                havequote = (havequote) ? FALSE : TRUE;
            if ( CMwhite(arguments) && havequote == FALSE )
                break;
            arguments++;
        }
	/*
	** 	Put together a command line to create a process with.
	**      - 4 blank separators, quotes, null termination 
	*/
	command_line_length = STlength(arguments) + STlength(iidbms) + 
				STlength(iirun) + 6 + 1; 
	if((command_line = (char *)
		MEreqmem(0, command_line_length, TRUE, NULL)) == NULL)
	{
		error(ERx("Request for memory failed"),NULL);
	}

	STprintf( command_line, "%s \"%s\" %s", iirun, iidbms, arguments );

	/*
	**	Save standard out's handle, to be restored later.
	*/
	hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

 	/*
	**      Initialize the security attributes structure that will
	**      be used to make the pipe handles inheritable.
	*/
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;       /* Make object inheritable */

	/*
	**	Define a anonymous pipe to catch the server's startup message.
	*/
	if((Status = CreatePipe(&hRead,&hWrite,&sa,pipe_size)) != TRUE)
	{
		error(ERx("CreatePipe failed"),ERx("error code = "));
	}

	SetStdHandle(STD_OUTPUT_HANDLE,hWrite);

 	/*
	**      Initialize the security attributes structure that will
	**      be used to make the pipe handles inheritable.
	*/
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;       /* Make object inheritable */

	/*
	**	Initialize the startup information structure.
	*/
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	/* 
	**	Start it up.
	*/
	/*
	**	Start iirun which will start the server.
	*/
	if ((Status = CreateProcess(NULL,command_line,&sa,NULL,TRUE,
		HIGH_PRIORITY_CLASS, NULL,
	     NULL,&si,&ProcessInfo)) != TRUE)
	{
		DWORD dwError = GetLastError();
		switch(dwError)
		{
		     case ERROR_ACCESS_DENIED:
			error(ERROR_REQ_PRIVILEGE, ERx(""));
			break;
		     case ERROR_ELEVATION_REQUIRED:
			error(ERROR_DENIED_PRIVILEGE, ERROR_REQ_ELEVATION);
			break;
		     default:				
			error(ERx("CreateProcess failed"),ERx("error code = "));
			break;
		}
	}

	SetStdHandle(STD_OUTPUT_HANDLE,hStdout);

	for (;;)
	{
	    char	*tmpptr;

	    if((Status = ReadFile(hRead,&buffer,bufferl,&datal,NULL)) != TRUE)
	    {
		error(ERx("ReadFile failed"),ERx("error code = "));
	    }

	    buffer[datal] = '\0';	 		
	    if ((tmpptr = STstrindex(buffer, "PASS\n", 0, FALSE)))
	    {
		*tmpptr = '\0';
		if (STlength(buffer))
		    SIfprintf(stdout, "%s", buffer);

		break;
	    }

	    SIfprintf(stdout, "%s", buffer);

	    if ((tmpptr = STstrindex(buffer, bad_msg, 0, FALSE)))
	    {
		*tmpptr = '\0';
		if (STlength(buffer))
		    SIfprintf(stdout, "%s", buffer);

		failed = TRUE;
		break;
	    }
	}

	/*
	**	Close handles since we don't need them anymore.
	*/
	CloseHandle(ProcessInfo.hThread);
	CloseHandle(ProcessInfo.hProcess);
	CloseHandle(hRead);
	CloseHandle(hWrite);

	if (failed &&
	    STscompare(server_type, STlength(server_type), "gcb", 3) != 0 &&
	    STscompare(server_type, STlength(server_type), "gcc", 3) != 0 &&
	    STscompare(server_type, STlength(server_type), "jdbc", 4) != 0)
	{
		SIfprintf( stderr,"\n%s: server would not start.\n",
			   iirundbms );

		SIfprintf(stderr,
		" %s must be set in your environment.\n", 
		    SystemLocationVariable );

		SIfprintf(stderr,
		" Has the csinstall program been run?\n");

		SIfprintf(stderr,
		" %s_DATABASE, %s_CHECKPOINT, %s_JOURNAL and %s_DUMP\n",
		    SystemVarPrefix,
		    SystemVarPrefix,
		    SystemVarPrefix,
		    SystemVarPrefix );

		SIfprintf(stderr,
		" must also be set. See %s_CONFIG\\symbol.tbl.\n",
		    SystemVarPrefix );

		SIfprintf(stderr,
		" Check the file '%%%s%%\\%s\\files\\errlog.log'\n",
		    SystemLocationVariable, SystemLocationSubdirectory );

		SIfprintf(stderr,
		" for more details concerning internal errors.\n");

		SIfprintf(stderr,
		" See your Installation and Operation Guide for more\n");

		SIfprintf(stderr,
		" information concerning server startup.\n");

		PCexit(FAIL);
	}
	else
	{
		PCexit(OK);
	}
}
Exemplo n.º 3
0
STATUS
ERsend(i4 flag, char *message, i4 msg_length, CL_ERR_DESC *err_code)
{
# ifdef NT_GENERIC
    static bool		er_init = FALSE;
    static bool		is_w95 = FALSE;
# else /* !NT_GENERIC */
    static int		er_ifi = -2;
    static int          ar_ifi = -2;
# endif /* !NT_GENERIC */
    STATUS		status;
    char                tmp_buf[ER_MAX_LEN];
    char*               logmsg = message;

    /*	Check for bad paramters. */

    CL_CLEAR_ERR( err_code );

    if ((message == 0 || msg_length == 0) && flag != ER_AUDIT_MSG)
        return (ER_BADPARAM);

    if ((flag != ER_ERROR_MSG) && (flag != ER_AUDIT_MSG) &&
        ( flag != ER_OPER_MSG))
        return (ER_BADPARAM);

# ifndef NT_GENERIC
    if (flag & ER_AUDIT_MSG)
    {
        key_t msg_key;
        char  *ipc_number;
        struct
        {
            long    mtype;
            char    mtext[ER_MAX_LEN];
        }   msg;

        if (ar_ifi == -2)
        {
            NMgtAt("II_AUDIT_IPC", &ipc_number);
            if (ipc_number && ipc_number[0])
            {
                CVal(ipc_number, &msg_key);
                ar_ifi = msgget(msg_key, 0);
                if (ar_ifi == -1)
                {
                    SETCLERR(err_code, 0, ER_open);
                    return(ER_NO_AUDIT);
                }
            }
            else
            {
                SETCLERR(err_code, 0, ER_open);
                return(ER_NO_AUDIT);
            }

        }
 
        /*  Handle special case to connect only but not send message. */
 
        if (msg_length == 0 && message == 0)
                return (OK);

        MEcopy(message, msg_length, msg.mtext);
        msg.mtype = 1;
        if (msgsnd(ar_ifi, &msg, msg_length, 0))
        {
            SETCLERR(err_code, 0, ER_open);
            return(ER_BADSEND);
        }
        return (OK);
    }
    else
# endif /* ! NT_GENERIC */
    if (flag & ER_OPER_MSG)
    {
        char    hostname[GL_MAXNAME];
        STATUS  status;
 
        message[msg_length] = EOS;
        TRdisplay("ER Operator:\"%s\"\n",message);
	if (!ERsysinit)
	    ERinitsyslog();
# ifdef NT_GENERIC
        {
        wchar_t *wmessage = NULL;

        /*
        ** Update the ReportEvent to report information in the event log.
        */
        if ( ReportEvent( EventLog,
                        (WORD) EVENTLOG_INFORMATION_TYPE,
                        (WORD) 0,             /* event category */
                        (DWORD) I_ING_INFO,   /* event identifier */
                        (PSID) NULL,
                        (WORD) 1,             /* number of strings */
                        (DWORD) 0,
                        &message,
                        NULL ) == FALSE)   
                status = GetLastError();
	if ( !er_init )
	{
	    char		VersionString[256];
	    FUNC_EXTERN BOOL	GVosvers(char *OSVersionString);

	    GVosvers(VersionString);
	    is_w95 = ( STstrindex(VersionString, "Microsoft Windows 9",
				  0, FALSE) != NULL ) ? TRUE : FALSE;

	    if ( !is_w95 ) /* netapi32 only on NT */
	    {
		HANDLE hDll;
                if ((hDll = LoadLibrary(TEXT("netapi32.dll"))) != NULL)
                {
                    pNetMessageNameAdd = 
		     (NET_API_STATUS (*)(LPCWSTR,LPCWSTR))
		     GetProcAddress(hDll, TEXT("NetMessageNameAdd"));
                    pNetMessageNameDel = 
		     (NET_API_STATUS (*)(LPCWSTR,LPCWSTR))
		     GetProcAddress(hDll, TEXT("NetMessageNameDel"));
                    pNetMessageBufferSend = 
		      (NET_API_STATUS (*)(LPCWSTR,LPCWSTR,LPCWSTR,LPBYTE,DWORD))
		      GetProcAddress(hDll, TEXT("NetMessageBufferSend"));
		}
		/* if any problem, pretend we don't support it */
		if ( pNetMessageNameAdd == NULL ||
		     pNetMessageNameDel == NULL ||
		     pNetMessageBufferSend == NULL )
		    is_w95 = TRUE;
	    }
	}

	if ( !is_w95 )
	{
	    /*
	    ** Now, send the message to the server console,
	    ** putting up a message box (if the messenger service
	    ** is running.  Everything must be in Unicode.
	    */

	    if ( whostname[0] == 0 )
	    {
		unsigned int len = sizeof(hostname);
                /* 
		** get the hostname in Unicode format for use 
		** by messenger service 
		*/
                GetComputerName( (char *)hostname, &len );
		MultiByteToWideChar( GetACP(), 0,
				     hostname, sizeof(hostname),
				     whostname, sizeof(whostname) );
	    }
            /* initialize the messenger service */
            status = (*pNetMessageNameAdd)( whostname, msgname );
            if ( status != NERR_Success )
	        status = GetLastError();

	    /* Allocate a buffer for the Unicode */
	    wmessage = (wchar_t *) MEreqmem( 0, msg_length * sizeof(wchar_t), 
				             TRUE, &status );
	    if ( wmessage )
	    {
	        /* copy the message to the Unicode buffer */
		MultiByteToWideChar( GetACP(), 0,
				     message, msg_length,
				     wmessage, msg_length * sizeof(wchar_t) );
                status = (*pNetMessageBufferSend)( whostname, 
					       msgname, 
					       NULL, 
				               (LPBYTE) wmessage, 
					       msg_length*sizeof(wchar_t) );
                if ( status != NERR_Success )
	            status = GetLastError();
	        MEfree( (PTR)wmessage );
	    }

            /* re-initialize the messenger service */
            status = (*pNetMessageNameDel)( whostname, msgname );
            if ( status != NERR_Success )
	        status = GetLastError();

	}
	}
# elif defined(OS_THREADS_USED) && defined(any_aix)
	syslog_r( LOG_ALERT|LOG_ERR, message );
# else
	syslog( LOG_ALERT|LOG_ERR, message );
# endif /* NT_GENERIC */
    }

    if (flag & ER_OPER_MSG)
    {
        i4 msglen = 0;
	char* host = PMhost();

        MEfill( ER_MAX_LEN, 0, tmp_buf );

        /*
        ** Format the message string for the event log.  As the source is
        ** not known a fixed string of INGSYSLOG is used.
        */
        TRformat( NULL, 0, tmp_buf, ER_MAX_LEN - 1,
            "%8.8t::[INGSYSLOG         , 00000000]: %@ ", STlength(host),
            host );
        msglen = STlength(tmp_buf);
        STcat( tmp_buf, message );  /* append original message */
        msg_length += msglen;
        logmsg = tmp_buf;
    }
    status = ERlog( logmsg, msg_length, err_code );
    return( status );
}
Exemplo n.º 4
0
STATUS
ip_batch(i4 argc, char *argv[])
{
    i4  argvx;
    PKGBLK *pkg;
    uchar opid;
    uchar option = opNONE;
    LOCATION outloc;
    char line[ MAX_MANIFEST_LINE + 1 ];
    LISTELE *lp;

    /* no command line arguments except mkresponse 
    ** or exresponse allowed for ingbuild in form mode
    */
    if ((argc < 2) || 
	((argc ==2) && ((pmode == TRUE) || 
           		(mkresponse == TRUE) || (exresponse == TRUE))) ||
	((argc ==3) && (((mkresponse == TRUE) || (exresponse == TRUE)) && 
			 (respfilename != NULL)))) 
	/* No command-line args? */
	return OK; /* Fine, must be forms mode; return without setting flag. */

    batchMode = TRUE;   /* We're in command-line mode. */
    batchOutf = stdout; /* For now, we'll direct output to the terminal. */

    /* Top of loop through the non-positional arguments on the command line. */

    for (argvx = 1; argvx < argc; argvx++)
    {
	if (argv[argvx][0] != '-') /* Not a switch?  Time for positional arg. */
	    break;

        /* Get the option code for the current flag and deal with it... */

	switch (opid = lookup(&argv[argvx][1]))  
	{
	    /* instruct ingbuild to skip set up */

	    case opNOSETUP:  

		noSetup = TRUE;
		break;

	    case opEXPRESS:  

		eXpress = TRUE;
		break;

	    case opPATCH:
		continue;

	    /* -install=<list of features> */

	    case opINSTALL:  
		if (option != opNONE || argval == NULL)
			USAGE;
		option = opid;
		featlist = argval;
		if( !STbcompare("ice", 3, featlist, STlength(featlist), TRUE) ||  
		    !STbcompare("ice64", 5, featlist, STlength(featlist), TRUE) )
		    Install_Ice = TRUE; 
		break;

	    /* 
	    ** -version, -products, -all, -describe
	    ** (All the options that don't require values.) 
	    */

	    case opVERSION:
	    case opPACKAGES:
	    case opDESCRIBE:
	    case opALL:

		if (option == opNONE)
		{
		    featlist = argval;
		    option = opid;
		    break;
		}
	    case opIGNORE:
		ignoreChecksum = TRUE;
		break;
	
	    case opEXRESPONSE:
		exresponse = TRUE;
		break;

	    case opRESPFILE:
		break;

/* -acceptlicense is still accepted for forward compatibility */
	    case opACCEPTLIC:
#if LICENSE_PROMPT
		acceptLicense = TRUE;
#endif
		break;

	    /* Fall through */
	    default:
		USAGE;
	}
    }

    /* 
    ** When we break from the flags loop, we must have a maximum of one
    ** remaining argument... 
    */

    if (argvx < (argc - 1))  /* Too many non-flags at the end of the line. */
	USAGE;

    if (exresponse && (option == opNONE))
    {
        char        *def_file="ingrsp.rsp";
        char        *filename;
        FILE        *respfile;

        if (respfilename != NULL)
            filename = respfilename;
        else
            filename = def_file;

        if (OK == ip_open_response (ERx(""), filename, &respfile, ERx( "r" )) )
        {
            bool        found = FALSE;
            char	line[MAX_MANIFEST_LINE + 1];
            char        *pkg_set = ERx("_set=YES");
            char        *setp, *realloc;
            i4          pkglen;
            i4          buflen = MAX_MANIFEST_LINE + 1;
            i4          space = buflen;

            while (SIgetrec((char *)&line, MAX_MANIFEST_LINE, respfile) == OK )
            {
                /* Check for _set=YES */
                setp = STstrindex(line, pkg_set, 0, 1);
                if(setp != NULL) 
                {
                    if(found == FALSE)
                    {
                        featlist = ip_alloc_blk( buflen );
                    }

                    *setp = NULLCHAR;
                    pkglen = STlength(line);
                     
                    if(found == TRUE)
                    {
                        if(space < (pkglen + 1))
                        {
                            buflen += MAX_MANIFEST_LINE;
                            realloc = ip_alloc_blk( buflen );
                            STcopy(featlist, realloc);
                            MEfree(featlist);
                            featlist = realloc;
                        }
                        STcat(featlist, ",");
                        space--;
                    }
                    else
                    {
                        found = TRUE;
                    }
                    STcat(featlist, line); 
                    space = space - pkglen;
                }

            } /* end read loop */

            ip_close_response(respfile);

            if( found == TRUE)
            {
                /* Need to test this does not override any other options that
                ** may be valid
                */
                option = opINSTALL;
            }
        }
        else
        {
            PCexit ( FAIL );
        }
    }    

    /* 
    ** If we have no positionals, no distribution device was provided on
    ** the command line.  That might or might not be ok... 
    */

    if (argvx == argc) 
    {
	switch (option)
	{
	    case opPATCH:
	    case opVERSION:
	    case opPACKAGES:
	    case opDESCRIBE:
		break;       /*  ...yes.  */

	    default:
	        USAGE;    /*  ...no.   */
	}
    }
    else  /* We got a positional, so copy it into the global field. */
    {
	STcopy(argv[argvx], distribDev);
	if( !IPCLsetDevice( distribDev ) )
	    USAGE;
    }

    if (option == opNONE)    /* No option?  Default to "all". */
	option = opALL; 

    if ( option == opALL );
       batch_opALL = TRUE; 

    /*  
    **  First processing pass.  If the option doesn't involve doing actual
    **  installation, just do whatever needs to be done, and return.
    **  If it's an installation option, mark all requested packages
    ** 	as selected, and continue.  
    */

    switch (option)
    {
	case opPACKAGES:
	    SIfprintf(batchOutf,ERget(S_ST0179_pkg_list_header));

            for( lp = distPkgList.head; lp != NULL; lp = lp->cdr )
            {
                pkg = (PKGBLK *) lp->car;

		if( ip_is_visible( pkg ) || ip_is_visiblepkg( pkg ) )
		{
		    SIfprintf( batchOutf, ERx("\t%-16s  %-30s\n"),
			pkg->feature,pkg->name );
		}
	    }

	    return OK;

	case opVERSION:
	    if (instRelID == NULL)
	    {
		IIUGerr(E_ST017B_not_present,0,1,SystemProductName);
		return FAIL;
	    }

	    if (featlist == NULL)
	    {
		SIfprintf(batchOutf, ERx("%s\n"), instRelID);
		return OK;
	    }

	    if (!apply_list(proc_version))
		return FAIL;

	    return OK;

	case opINSTALL:
	    SCAN_LIST(distPkgList, pkg)
	    {
		pkg->selected = NOT_SELECTED;
	    }

	    if (!apply_list(proc_install))
		return FAIL;

	    break;

	case opDESCRIBE:
	    _VOID_ apply_list(proc_describe);
	    return OK;

	default:
	    for( lp = distPkgList.head; lp != NULL; lp = lp->cdr )
	    {
                pkg = (PKGBLK *) lp->car;

		switch (option)
		{
		    case opALL:
			if ( ip_is_visible(pkg) || ip_is_visiblepkg( pkg ) )
			    pkg->selected = SELECTED;
			break;
		}
	    }
    }

    /* 
    ** If we haven't left yet, that must mean we have an install-class
    ** option, i.e. one that's going to cause us to actually install 
    ** something.  First of all, let's make sure that the user has
    ** defined II_AUTH_STRING and has selected something to install... 
    */

#ifndef INGRESII
    if( !authStringEnv )
    {
	IIUGerr( E_ST0117_license_required, 0, 0 );
	return( FAIL );	
    }
#endif /* INGRESII */

    SCAN_LIST(distPkgList, pkg)
    {
	if (pkg->selected == SELECTED)
	    break;
    }

    if (pkg == NULL) /* Got all the way through the list?  Nothing selected! */
	USAGE;

    /* If Ingres is up, no go; otherwise, do the installation... */

    switch (option)
    {
	case opALL:
	case opINSTALL:
	    if (ip_sysstat() == IP_SYSUP) 
	    {
		IIUGerr(E_ST0178_installation_is_up, 0, 2, 
			SystemProductName, installDir);
		return FAIL;
	    }

#if LICENSE_PROMPT
	    if( !acceptLicense )
		license_prompt();
#endif

	    ip_install(NULL);
	    break;
    }
return OK;
}
Exemplo n.º 5
0
/*
** Name:
**
** Decription:
**
** Inputs:
**      load
**      buf
**      len
**
** Outputs:
**      count
**
** Return:
**
** History:
**      23-Oct-98 (fanra01)
**          Created.
**      01-Feb-1999 (fanra01)
**          Add data length parameter to determine incomplete messages.
**      27-Apr-1999 (fanra01)
**          Update the incomplete message handling to account for '--'
**          characters that don't define a boundary.
*/
static i4
getstrevent (PWTS_UPLOAD load, char *buf, i4  len, i4 datalen, i4 * count)
{
    i4      eventnum = 0;
    i4      i;
    i4      j;
    char*   p = buf;
    i4      pos = 0;
    i4      boundlen;

    if ((buf[0]=='-') && (buf[1] == '-'))
    {
        /*
        ** If the remaining string is less than the length of boundary string
        ** there is likely more to follow.  Set the event for a partial
        ** boundary.
        */
        boundlen = STlength(load->end);
        if ((boundlen < datalen) &&
            (STbcompare (load->end, boundlen, p, 0, TRUE) == 0))
        {
            eventnum = UE_EBOUND;
            pos+=STlength(load->end);
        }
        else
        {
            boundlen = STlength(load->start);
            if ((boundlen < datalen) &&
                (STbcompare (load->start, boundlen, p, 0, TRUE) == 0))
            {
                eventnum = UE_SBOUND;
                pos+=STlength(load->start);
            }
            else
            {
                if (datalen < boundlen)
                {
                    eventnum = UE_PBOUND;
                }
            }
        }
    }

    if ((eventnum == 0) && (*p) &&
        (STbcompare (ERx("content-"), 8, p, 0, TRUE) == 0))
    {
        pos+=8;
        p+=pos;
        /*
        ** Scan list of content attributes
        */
        for (i=0; (attribute[i] != NULL) && (eventnum == 0); i++)
        {
            if ((STbcompare (attribute[i], STlength(attribute[i]), p, 0,
                TRUE)) == 0)
            {
                p += STlength(attribute[i]);
                pos+=STlength(attribute[i]);
                /*
                ** Ensure we don't go beyond the line
                */
                while ((pos < len) && CMwhite(p))
                {
                    CMbyteinc(pos, p);
                    CMnext(p);
                }

                switch (i)
                {
                    case A_TYPE:
                        if ((STbcompare (ERx("multipart/mixed"), 15, p, 0,
                            TRUE)) == 0)
                        {
                            pos+=15;
                            p += 15;
                            eventnum = UE_EMBED;
                        }
                        else
                        {
                            eventnum = UE_MIME;
                        }
                        break;

                    case A_DISP:
                        for (j=0; (disptype[j] != NULL) && (eventnum == 0);
                            j++)
                        {
                            if ((STbcompare (disptype[j],
                                STlength(disptype[j]), p, 0, TRUE)) == 0)
                            {
                                pos+=STlength(disptype[j]);
                                p += STlength(disptype[j]);
                                /*
                                ** Ensure we don't go beyond the line
                                */
                                while ((pos < len) && CMwhite(p))
                                {
                                    CMbyteinc(pos, p);
                                    CMnext(p);
                                }
                                switch (j)
                                {
                                    case D_FORM:
                                        if (STstrindex(p, "filename=",
                                            len - pos, TRUE) !=NULL)
                                        {
                                            eventnum = UE_FNAME;
                                        }
                                        else
                                        {
                                            eventnum = UE_FORM;
                                        }
                                        break;
                                    case D_ATTACH:
                                        eventnum = UE_FNAME;
                                        break;
                                }
                            }
                        }
                        if (eventnum == 0) eventnum = UE_EXCEPT;
                        break;

                    case A_ENC:
                        eventnum = UE_FENC;
                        break;
                }
            }
        }
        if (eventnum == 0) eventnum = UE_EXCEPT;
    }
    else
    {
        if (eventnum == 0)
        {
            /*
            ** Unnamed line - determine event on previous state
            */
            switch (load->state)
            {
                case US_VAL:
                    eventnum = UE_VALUE;
                    break;
                case US_FWRITE:
                    eventnum = UE_FVALUE;
                    break;
                default:
                    eventnum = UE_EXCEPT;
                    break;
            }
        }
    }
    *count+=pos;
    return (eventnum);
}