Example #1
0
void PreparedStatement::init(thread_db* tdbb, Attachment* attachment, jrd_tra* transaction,
	const Firebird::string& text, bool isInternalRequest)
{
	AutoSetRestore<SSHORT> autoAttCharset(&attachment->att_charset,
		(isInternalRequest ? CS_METADATA : attachment->att_charset));

	request = NULL;
	try
	{
		const Database& dbb = *tdbb->getDatabase();
		const int dialect = isInternalRequest || (dbb.dbb_flags & DBB_DB_SQL_dialect_3) ?
			SQL_DIALECT_V6 : SQL_DIALECT_V5;

		request = DSQL_prepare(tdbb, attachment, transaction, text.length(), text.c_str(), dialect,
			NULL, NULL, isInternalRequest);

		const DsqlCompiledStatement* statement = request->getStatement();

		if (statement->getSendMsg())
			parseDsqlMessage(statement->getSendMsg(), inValues, inMetadata, inMessage);

		if (statement->getReceiveMsg())
			parseDsqlMessage(statement->getReceiveMsg(), outValues, outMetadata, outMessage);
	}
	catch (const Exception&)
	{
		if (request)
		{
			DSQL_free_statement(tdbb, request, DSQL_drop);
		}
		throw;
	}
}
Example #2
0
Firebird::string pagtype(UCHAR type)
{
	// Print pretty name for database page type

	const char* nameArray[pag_max + 1] = {
		"purposely undefined",
		"database header",
		"page inventory",
		"transaction inventory",
		"pointer",
		"data",
		"index root",
		"index B-tree",
		"blob",
		"generators",
		"SCN inventory"
	};

	Firebird::string rc;
	if (type < FB_NELEM(nameArray))
		rc = nameArray[type];
	else
		rc.printf("unknown (%d)", type);

	return rc;
}
Example #3
0
bool readenv(const char* env_name, Firebird::PathName& env_value)
{
	Firebird::string result;
	bool rc = readenv(env_name, result);
	env_value.assign(result.c_str(), result.length());
	return rc;
}
Example #4
0
// create directory for lock files and set appropriate access rights
void createLockDirectory(const char* pathname)
{
	static bool errorLogged = false;

	DWORD attr = GetFileAttributes(pathname);
	DWORD errcode = 0;
	if (attr == INVALID_FILE_ATTRIBUTES)
	{
		errcode = GetLastError();
		if (errcode == ERROR_FILE_NOT_FOUND)
		{
			if (!CreateDirectory(pathname, NULL)) {
				errcode = GetLastError();
			}
			else
			{
				adjustLockDirectoryAccess(pathname);

				attr = GetFileAttributes(pathname);
				if (attr == INVALID_FILE_ATTRIBUTES) {
					errcode = GetLastError();
				}
			}
		}
	}

	Firebird::string err;
	if (attr == INVALID_FILE_ATTRIBUTES)
	{
		err.printf("Can't create directory \"%s\". OS errno is %d", pathname, errcode);
		if (!errorLogged)
		{
			errorLogged = true;
			gds__log(err.c_str());
		}
		Firebird::fatal_exception::raise(err.c_str());
	}

	if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
	{
		err.printf("Can't create directory \"%s\". File with same name already exists", pathname);
		if (!errorLogged)
		{
			errorLogged = true;
			gds__log(err.c_str());
		}
		Firebird::fatal_exception::raise(err.c_str());
	}

	if (attr & FILE_ATTRIBUTE_READONLY)
	{
		err.printf("Can't create directory \"%s\". Readonly directory with same name already exists", pathname);
		if (!errorLogged)
		{
			errorLogged = true;
			gds__log(err.c_str());
		}
		Firebird::fatal_exception::raise(err.c_str());
	}
}
Example #5
0
ModuleLoader::Module* ModuleLoader::loadModule(ISC_STATUS* status, const Firebird::PathName& modPath)
{
	void* module = dlopen(modPath.nullStr(), FB_RTLD_MODE);
	if (module == NULL)
	{
		if (status)
		{
			status[0] = isc_arg_gds;
			status[1] = isc_random;
			status[2] = isc_arg_string;
			status[3] = (ISC_STATUS) dlerror();
			status[4] = isc_arg_end;
		}

		return 0;
	}

#ifdef DEBUG_THREAD_IN_UNLOADED_LIBRARY
	Firebird::string command;
	command.printf("echo +++ %s +++ >>/tmp/fbmaps;date >> /tmp/fbmaps;cat /proc/%d/maps >>/tmp/fbmaps",
		modPath.c_str(), getpid());
	system(command.c_str());
#endif

	return FB_NEW_POOL(*getDefaultMemoryPool()) DlfcnModule(*getDefaultMemoryPool(), modPath, module);
}
Example #6
0
TracePlugin* FB_CARG TraceFactoryImpl::trace_create(Firebird::IStatus* status, TraceInitInfo* initInfo)
{
	Firebird::MasterInterfacePtr master;
	const char* dbname = NULL;
	try
	{
		master->upgradeInterface(initInfo, FB_TRACE_INIT_INFO_VERSION, upInfo);

		dbname = initInfo->getDatabaseName();
		if (!dbname)
			dbname = "";

		TracePluginConfig config;
		TraceCfgReader::readTraceConfiguration(initInfo->getConfigText(), dbname, config);

		TraceDatabaseConnection* connection = initInfo->getConnection();
		if (connection)
			master->upgradeInterface(connection, FB_TRACE_CONNECTION_VERSION, upInfo);

		if (!config.enabled ||
			(config.connection_id && connection &&
				(connection->getConnectionID() != SLONG(config.connection_id))))
		{
			return NULL; // Plugin is not needed, no error happened.
		}

		Firebird::AutoPtr<TraceLogWriter, Firebird::SimpleRelease<TraceLogWriter> >
			logWriter(initInfo->getLogWriter());

		if (logWriter)
			config.log_filename = "";

		return new TracePluginImpl(config, initInfo);	// Everything is ok, we created a plugin

	}
	catch (Firebird::Exception& ex)
	{
		// put error into trace log
		TraceLogWriter* logWriter = initInfo->getLogWriter();
		if (logWriter)
		{
			master->upgradeInterface(logWriter, FB_TRACE_LOG_WRITER_VERSION, upInfo);
			const char* strEx = TracePluginImpl::marshal_exception(ex);
			Firebird::string err;
			if (dbname)
				err.printf("Error creating trace session for database \"%s\":\n%s\n", dbname, strEx);
			else
				err.printf("Error creating trace session for service manager attachment:\n%s\n", strEx);

			logWriter->write(err.c_str(), err.length());
			logWriter->release();
		}
		else
			ex.stuffException(status);
	}

	return NULL;
}
Example #7
0
	void prepareName(Firebird::string& s, char c)
	{
		for (unsigned i = 0; i < s.length(); ++i)
		{
			if (s[i] == c)
			{
				s.insert(i++, 1, c);
			}
		}
	}
Example #8
0
void Stream::format(const char *pattern, ...)
{
	Firebird::string temp;

	va_list		args;
	va_start	(args, pattern);
	temp.vprintf(pattern, args);
	va_end(args);

	putSegment (temp.c_str());
}
void ExecuteStatement::open(thread_db* tdbb, jrd_nod* sql, SSHORT nVars, bool singleton)
{
    SET_TDBB(tdbb);

    Attachment* const attachment = tdbb->getAttachment();
    jrd_tra* transaction = tdbb->getTransaction();

    if (transaction->tra_callback_count >= MAX_CALLBACKS)
    {
        ERR_post(Arg::Gds(isc_exec_sql_max_call_exceeded));
    }

    varCount = nVars;
    singleMode = singleton;

    Firebird::string sqlText;
    getString(tdbb, sqlText, EVL_expr(tdbb, sql), tdbb->getRequest());
    memcpy(startOfSqlOperator, sqlText.c_str(), sizeof(startOfSqlOperator) - 1);
    startOfSqlOperator[sizeof(startOfSqlOperator) - 1] = 0;

    transaction->tra_callback_count++;

    try
    {
        stmt = attachment->prepareStatement(tdbb, *tdbb->getDefaultPool(), transaction, sqlText);

        if (stmt->getResultCount() == 0)
        {
            delete stmt;
            stmt = NULL;

            ERR_post(Arg::Gds(isc_exec_sql_invalid_req) << Arg::Str(startOfSqlOperator));
        }

        if (stmt->getResultCount() != varCount)
        {
            delete stmt;
            stmt = NULL;

            ERR_post(Arg::Gds(isc_wronumarg));
        }

        resultSet = stmt->executeQuery(tdbb, transaction);

        fb_assert(transaction == tdbb->getTransaction());
    }
    catch (const Firebird::Exception&)
    {
        transaction->tra_callback_count--;
        throw;
    }

    transaction->tra_callback_count--;
}
Example #10
0
void* DlfcnModule::findSymbol(const Firebird::string& symName)
{
	void* result = dlsym(module, symName.c_str());
	if (result == NULL)
	{
		Firebird::string newSym ='_' + symName;
		result = dlsym(module, newSym.c_str());
	}
	return result;

}
Example #11
0
void iscDbLogStatus(const TEXT* text, Firebird::IStatus* status)
{
	const TEXT* hdr = NULL;
	Firebird::string buf;
	if (text)
	{
		buf = "Database: ";
		buf += text;
		hdr = buf.c_str();
	}
	iscLogStatus(hdr, status);
}
Example #12
0
Firebird::string Stream::getFBString() const
{
	Firebird::string string;
	char *p = string.getBuffer (totalLength);

	for (const Segment *segment = segments; segment; segment = segment->next)
	{
		memcpy (p, segment->address, segment->length);
		p += segment->length;
	}

	fb_assert(p - string.begin() == totalLength);

	return string;
}
Example #13
0
// converts bytes to BASE64 representation
void base64(Firebird::string& b64, const Firebird::UCharBuffer& bin)
{
	b64.erase();
	const unsigned char* f = bin.begin();
	for (int i = bin.getCount(); i > 0; i -= 3, f += 3)
	{
		if (i >= 3)
		{
			const ULONG l = (ULONG(f[0]) << 16) | (ULONG(f[1]) <<  8) | f[2];
			b64 += conv_bin2ascii(l >> 18);
			b64 += conv_bin2ascii(l >> 12);
			b64 += conv_bin2ascii(l >> 6);
			b64 += conv_bin2ascii(l);
		}
		else
		{
			ULONG l = ULONG(f[0]) << 16;
			if (i == 2)
				l |= (ULONG(f[1]) << 8);
			b64 += conv_bin2ascii(l >> 18);
			b64 += conv_bin2ascii(l >> 12);
			b64 += (i == 1 ? '=' : conv_bin2ascii(l >> 6));
			b64 += '=';
		}
	}
Example #14
0
static void alice_output(bool error, const SCHAR* format, ...)
{

	AliceGlobals* tdgbl = AliceGlobals::getSpecific();

	va_list arglist;
	va_start(arglist, format);
	Firebird::string buf;
	buf.vprintf(format, arglist);
	va_end(arglist);

	if (error)
		tdgbl->uSvc->outputError(buf.c_str());
	else
		tdgbl->uSvc->outputVerbose(buf.c_str());
}
Example #15
0
static void stuff_stack_trace(const jrd_req* request)
{
	Firebird::string sTrace;
	bool isEmpty = true;

	for (const jrd_req* req = request; req; req = req->req_caller)
	{
		const JrdStatement* statement = req->getStatement();
		Firebird::string name;

		if (statement->triggerName.length())
		{
			name = "At trigger '";
			name += statement->triggerName.c_str();
		}
		else if (statement->procedure)
		{
			name = statement->parentStatement ? "At sub procedure '" : "At procedure '";
			name += statement->procedure->getName().toString().c_str();
		}
		else if (statement->function)
		{
			name = statement->parentStatement ? "At sub function '" : "At function '";
			name += statement->function->getName().toString().c_str();
		}

		if (! name.isEmpty())
		{
			name.trim();

			if (sTrace.length() + name.length() + 2 > MAX_STACK_TRACE)
				break;

			if (isEmpty)
			{
				isEmpty = false;
				sTrace += name + "'";
			}
			else {
				sTrace += "\n" + name + "'";
			}

			if (req->req_src_line)
			{
				Firebird::string src_info;
				src_info.printf(" line: %"ULONGFORMAT", col: %"ULONGFORMAT,
								req->req_src_line, req->req_src_column);

				if (sTrace.length() + src_info.length() > MAX_STACK_TRACE)
					break;

				sTrace += src_info;
			}
		}
	}

	if (!isEmpty)
		ERR_post_nothrow(Arg::Gds(isc_stack_trace) << Arg::Str(sTrace));
}
Example #16
0
ISC_STATUS API_ROUTINE isc_delete_user(ISC_STATUS* status, const USER_SEC_DATA* input_user_data)
{
/**************************************
 *
 *      i s c _ d e l e t e _ u s e r
 *
 **************************************
 *
 * Functional description
 *      Deletes a user from the server's security
 *	    database.
 *      Return 0 if the user was deleted
 *
 *	    Return > 0 if any error occurs.
 *
 **************************************/
	Auth::StackUserData userInfo;
	userInfo.op = Auth::DEL_OPER;
	Firebird::LocalStatus s;
	Firebird::CheckStatusWrapper statusWrapper(&s);

	if (input_user_data->user_name)
	{
		Firebird::string work = input_user_data->user_name;
		if (work.length() > USERNAME_LENGTH) {
			return user_error(status, isc_usrname_too_long);
		}

		Firebird::string::size_type l = work.find(' ');
		if (l != Firebird::string::npos) {
			work.resize(l);
		}

		userInfo.user.set(&statusWrapper, work.c_str());
		Firebird::check(&statusWrapper);
		userInfo.user.setEntered(&statusWrapper, 1);
		Firebird::check(&statusWrapper);
	}
	else {
		return user_error(status, isc_usrname_required);
	}

	return executeSecurityCommand(status, input_user_data, userInfo);
}
Example #17
0
// static function
bool Switches::matchSwitch(const Firebird::string& sw, const char* target, size_t n)
{
/**************************************
 *
 *	m a t c h S w i t c h
 *
 **************************************
 *
 * Functional description
 *	Returns true if switch matches target
 *
 **************************************/
	if (n < sw.length())
	{
		return false;
	}
	n = sw.length();
	return memcmp(sw.c_str(), target, n) == 0;
}
Example #18
0
// Lookup and format message.  Return as much of formatted string as fits in caller's buffer.
int fb_msg_format(void* handle, USHORT facility, USHORT number, unsigned int bsize, TEXT* buffer,
	const MsgFormat::SafeArg& arg)
{
	// The field MESSAGES.TEXT is 118 bytes long.
	int total_msg = 0;
	char msg[120] = "";
	const int n = gds__msg_lookup(handle, facility, number, sizeof(msg), msg, NULL);

	if (n > 0 && unsigned(n) < sizeof(msg))
	{
		// Shameful bridge, gds__msg_format emulation for old format messages.
		if (strchr(msg, '%'))
		{
			const TEXT* rep[5];
			arg.dump(rep, 5);
			total_msg = fb_utils::snprintf(buffer, bsize, msg, rep[0], rep[1], rep[2], rep[3], rep[4]);
		}
		else
			total_msg = MsgPrint(buffer, bsize, msg, arg);
	}
	else
	{
		Firebird::string s;
		s.printf("can't format message %d:%d -- ", facility, number);
		if (n == -1)
			s += "message text not found";
		else if (n == -2)
		{
			s += "message file ";
			s += fb_utils::getPrefix(Firebird::DirType::FB_DIR_MSG, MSG_FILE).ToString();
			s += " not found";
		}
		else
		{
			fb_utils::snprintf(buffer, bsize, "message system code %d", n);
			s += buffer;
		}
		total_msg = s.copyTo(buffer, bsize);
	}

	return (n > 0 ? total_msg : -total_msg);
}
Example #19
0
// fetch password from file
FetchPassResult fetchPassword(const Firebird::PathName& name, const char*& password)
{
	InputFile file(name);
	if (!file)
	{
		return FETCH_PASS_FILE_OPEN_ERROR;
	}

	Firebird::string pwd;
	if (! pwd.LoadFromFile(file.getStdioFile()))
	{
		return ferror(file.getStdioFile()) ? FETCH_PASS_FILE_READ_ERROR : FETCH_PASS_FILE_EMPTY;
	}

	// this is planned leak of a few bytes of memory in utilities
	char* pass = FB_NEW_POOL(*getDefaultMemoryPool()) char[pwd.length() + 1];
	pwd.copyTo(pass, pwd.length() + 1);
	password = pass;
	return FETCH_PASS_OK;
}
Example #20
0
ModuleLoader::Module* ModuleLoader::loadModule(const Firebird::PathName& modPath)
{
	void* module = dlopen(modPath.nullStr(), FB_RTLD_MODE);
	if (module == NULL)
	{
#ifdef DEV_BUILD
//		gds__log("loadModule failed loading %s: %s", modPath.c_str(), dlerror());
#endif
		return 0;
	}

#ifdef DEBUG_THREAD_IN_UNLOADED_LIBRARY
	Firebird::string command;
	command.printf("echo +++ %s +++ >>/tmp/fbmaps;date >> /tmp/fbmaps;cat /proc/%d/maps >>/tmp/fbmaps",
		modPath.c_str(), getpid());
	system(command.c_str());
#endif

	return FB_NEW_POOL(*getDefaultMemoryPool()) DlfcnModule(module);
}
size_t PAR_name(CompilerScratch* csb, Firebird::string& name)
{
/**************************************
 *
 *	P A R _ n a m e
 *
 **************************************
 *
 * Functional description
 *	Parse a counted string of virtually unlimited size
 *  (up to 64K, actually <= 255), returning count.
 *
 **************************************/
	size_t l = csb->csb_blr_reader.getByte();
	char* s = name.getBuffer(l);

	while (l--)
		*s++ = csb->csb_blr_reader.getByte();

	return name.length();
}
Example #22
0
void* DlfcnModule::findSymbol(const Firebird::string& symName)
{
	void* result = dlsym(module, symName.c_str());
	if (!result)
	{
		Firebird::string newSym = '_' + symName;

		result = dlsym(module, newSym.c_str());
	}

#ifdef HAVE_DLADDR
	if (!PathUtils::isRelative(fileName))
	{
		Dl_info info;
		if (!dladdr(result, &info))
			return NULL;
		if (fileName != info.dli_fname)
			return NULL;
	}
#endif

	return result;
}
void ExecuteStatement::getString(thread_db* tdbb,
                                 Firebird::string& sql,
                                 const dsc* desc,
                                 const jrd_req* request)
{
    MoveBuffer buffer;

    UCHAR* ptr = NULL;

    const SSHORT len = (desc && !(request->req_flags & req_null)) ?
                       MOV_make_string2(tdbb, desc, desc->getTextType(), &ptr, buffer) : 0; // !!! How call Msgs ?

    if (!ptr)
    {
        ERR_post(Arg::Gds(isc_exec_sql_invalid_arg));
    }

    sql.assign((const char*) ptr, len);
}
Example #24
0
//***************
// r e a d e n v
//***************
// Goes to read directly the environment variables from the operating system on Windows
// and provides a stub for UNIX.
bool readenv(const char* env_name, Firebird::string& env_value)
{
#ifdef WIN_NT
	const DWORD rc = GetEnvironmentVariable(env_name, NULL, 0);
	if (rc)
	{
		env_value.reserve(rc - 1);
		DWORD rc2 = GetEnvironmentVariable(env_name, env_value.begin(), rc);
		if (rc2 < rc && rc2 != 0)
		{
			env_value.recalculate_length();
			return true;
		}
	}
#else
	const char* p = getenv(env_name);
	if (p)
		return env_value.assign(p).length() != 0;
#endif
	// Not found, clear the output var.
	env_value.begin()[0] = 0;
	env_value.recalculate_length();
	return false;
}
Example #25
0
void exactNumericToStr(SINT64 value, int scale, Firebird::string& target, bool append)
{
	if (value == 0)
	{
		if (append)
			target.append("0", 1);
		else
			target.assign("0", 1);
		return;
	}

	const int MAX_SCALE = 25;
	const int MAX_BUFFER = 50;

	if (scale < -MAX_SCALE || scale > MAX_SCALE)
	{
		fb_assert(false);
		return; // throw exception here?
	}

	const bool neg = value < 0;
	const bool dot = scale < 0; // Need the decimal separator or not?
	char buffer[MAX_BUFFER];
	int iter = MAX_BUFFER;

	buffer[--iter] = '\0';

	if (scale > 0)
	{
		while (scale-- > 0)
			buffer[--iter] = '0';
	}

	bool dot_used = false;
	FB_UINT64 uval = neg ? FB_UINT64(-(value + 1)) + 1 : value; // avoid problems with MIN_SINT64

	while (uval != 0)
	{
		buffer[--iter] = static_cast<char>(uval % 10) + '0';
		uval /= 10;

		if (dot && !++scale)
		{
			buffer[--iter] = '.';
			dot_used = true;
		}
	}

	if (dot)
	{
		// if scale > 0 we have N.M
		// if scale == 0 we have .M and we need 0.M
		// if scale < 0 we have pending zeroes and need 0.{0+}M
		if (!dot_used)
		{
			while (scale++ < 0)
				buffer[--iter] = '0';

			buffer[--iter] = '.';
			buffer[--iter] = '0';
		}
		else if (!scale)
			buffer[--iter] = '0';
	}

	if (neg)
		buffer[--iter] = '-';

	const FB_SIZE_T len = MAX_BUFFER - iter - 1;

	if (append)
		target.append(buffer + iter, len);
	else
		target.assign(buffer + iter, len);
}
Example #26
0
int CLIB_ROUTINE main( int argc, char **argv)
{
    /**************************************
     *
     *	m a i n
     *
     **************************************
     *
     * Functional description
     *	If there is no command line, prompt for one, read it
     *	and make an artificial argc/argv.   Otherwise, pass
     *	the specified argc/argv to IBMGR_exec_line (see below).
     *
     **************************************/

    fprintf(stderr, "*** fbmgr is deprecated, will be removed soon ***\n");
    gds__log("*** fbmgr is deprecated, will be removed soon ***");

    // Let's see if we have something in environment variables
    Firebird::string user, password;
    fb_utils::readenv(ISC_USER, user);
    fb_utils::readenv(ISC_PASSWORD, password);

    Firebird::string host;
    // MMM - do not allow to change host now
    //fb_utils::readenv("ISC_HOST", host);

    TEXT msg[MSG_LEN];

    // Let's get a real user name. This info is used by
    // START server command. Because server is not running
    // we can not check the password, thus we require a
    // real user to be root or FIREBIRD_USER_NAME or
    // INTERBASE_USER_NAME or INTERBASE_USER_SHORT

    const struct passwd* pw = getpwuid(getuid());
    if (pw == NULL)
    {
        perror("getpwuid");
        SRVRMGR_msg_get(MSG_GETPWFAIL, msg);
        fprintf(OUTFILE, "%s\n", msg);
        exit(FINI_ERROR);
    }

    strcpy(ibmgr_data.real_user, pw->pw_name);

    if (!strcmp(pw->pw_name, "root") ||
            !strcmp(pw->pw_name, FIREBIRD_USER_NAME) ||
            !strcmp(pw->pw_name, INTERBASE_USER_NAME) ||
            !strcmp(pw->pw_name, INTERBASE_USER_SHORT))
    {
        strcpy(ibmgr_data.user, SYSDBA_USER_NAME);
    }
    else
        copy_str_upper(ibmgr_data.user, pw->pw_name);


    if (user.length())
        copy_str_upper(ibmgr_data.user, user.c_str());

    if (password.length())
        strcpy(ibmgr_data.password, password.c_str());
    else
        ibmgr_data.password[0] = '\0';

    if (host.length())
        strcpy(ibmgr_data.host, host.c_str());
    else
        strcpy(ibmgr_data.host, "localhost");


    // Shutdown is not in progress and we are not attached to service yet.
    // But obviously we will need attachment.

    ibmgr_data.shutdown = false;
    ibmgr_data.attached = 0;
    ibmgr_data.reattach |= (REA_HOST | REA_USER | REA_PASSWORD);

    // No pidfile by default
    ibmgr_data.pidfile[0] = 0;



    // Special case a solitary -z switch.
    // Print the version and then drop into prompt mode.

    if (argc == 2 && *argv[1] == '-' && (argv[1][1] == 'Z' || argv[1][1] == 'z'))
    {
        parse_cmd_line(argc, argv, false);
        argc--;
    }

    SSHORT ret;
    if (argc > 1)
    {
        ret = parse_cmd_line(argc, argv, true);
        if (ret == FB_SUCCESS)
        {
            ret = SRVRMGR_exec_line(&ibmgr_data);
            if (ret)
            {
                SRVRMGR_msg_get(ret, msg);
                fprintf(OUTFILE, "%s\n", msg);
            }
            // We also need to check the shutdown flag here (if operation was
            // -shut -[noat|notr]) and, depending on what we want to do, either
            // wait here on some sort of a shutdown event, or go to the prompt mode
            SRVRMGR_cleanup(&ibmgr_data);
            exit(FINI_OK);
        }
        else if (ret != ACT_PROMPT)
            exit(FINI_OK);
    }

    int local_argc;
    SCHAR* local_argv[MAXARGS];
    TEXT stuff[MAXSTUFF];

    for (;;)
    {
        if (get_line(&local_argc, local_argv, stuff))
            break;
        if (local_argc > 1)
        {
            ret = parse_cmd_line(local_argc, local_argv, false);
            if (ret == ACT_QUIT)
                break;
            if (ret == FB_SUCCESS)
            {
                ret = SRVRMGR_exec_line(&ibmgr_data);
                if (ret)
                {
                    SRVRMGR_msg_get(ret, msg);
                    fprintf(OUTFILE, "%s\n", msg);
                }
            }
        }
    }
    SRVRMGR_cleanup(&ibmgr_data);
    exit(FINI_OK);
}
Example #27
0
qli_tok* LEX_token()
{
/**************************************
 *
 *	L E X _ t o k e n
 *
 **************************************
 *
 * Functional description
 *	Parse and return the next token.
 *
 **************************************/
	qli_tok* token = QLI_token;
	TEXT* p = token->tok_string;

	// Get next significant byte.  If it's the last EOL of a blob, throw it away

	SSHORT c;

	for (;;)
	{
		c = skip_white();
		if (c != '\n' || QLI_line->line_type != line_blob)
			break;
		qli_line* prior = QLI_line;
		next_line(true);
		if (prior == QLI_line)
			break;
	}

	// If we hit end of file, make up a phoney token

	if (!QLI_line)
	{
		const TEXT* q = eof_string;
		while (*p++ = *q++);
		token->tok_type = tok_eof;
		token->tok_keyword = KW_none;
		return NULL;
	}

	*p++ = c;
	QLI_token->tok_position = QLI_line->line_position + QLI_line->line_ptr - QLI_line->line_data - 1;

	// On end of file, generate furious but phone end of line tokens

	char char_class = classes(c);

	if (char_class & CHR_letter)
	{
		for (c = nextchar(true); classes(c) & CHR_ident; c = nextchar(true))
			*p++ = c;
		retchar();
		token->tok_type = tok_ident;
	}
	else if (((char_class & CHR_digit) || c == '.') && scan_number(c, &p))
		token->tok_type = tok_number;
	else if (char_class & CHR_quote)
	{
		token->tok_type = tok_quoted;
		while (true)
		{
			const SSHORT next = nextchar(false);
			if (!next || next == '\n')
			{
				retchar();
				IBERROR(63);	// Msg 63 unterminated quoted string
				break;
			}
			*p++ = next;
			if ((p - token->tok_string) >= MAXSYMLEN)
				ERRQ_msg_put(470, SafeArg() << MAXSYMLEN);	// Msg 470 literal too long

			// If there are 2 quotes in a row, interpret 2nd as a literal

			if (next == c)
			{
				const SSHORT peek = nextchar(false);
				retchar();
				if (peek != c)
					break;
				nextchar(false);
			}
		}
	}
	else if (c == '\n')
	{
	    // end of line, signal it properly with a phoney token.
		token->tok_type = tok_eol;
		--p;
		const TEXT* q = eol_string;
		while (*q)
			*p++ = *q++;
	}
	else
	{
		token->tok_type = tok_punct;
		*p++ = nextchar(true);
		if (!HSH_lookup(token->tok_string, 2))
		{
			retchar();
			--p;
		}
	}

	token->tok_length = p - token->tok_string;
	*p = '\0';

	if (token->tok_string[0] == '$' && trans_limit < TRANS_LIMIT)
	{
		Firebird::string s;
		if (fb_utils::readenv(token->tok_string + 1, s))
		{
			LEX_push_string(s.c_str());
			++trans_limit;
			token = LEX_token();
			--trans_limit;
			return token;
		}
	}

    qli_symbol* symbol = HSH_lookup(token->tok_string, token->tok_length);
	token->tok_symbol = symbol;
	if (symbol && symbol->sym_type == SYM_keyword)
		token->tok_keyword = (kwwords) symbol->sym_keyword;
	else
		token->tok_keyword = KW_none;

	if (sw_trace)
		puts(token->tok_string);

	return token;
}
Example #28
0
/**

	typeBuffer

	@brief	Prints data, returned by service, using outputFunction


	@param status
	@param buf
	@param offset
	@param uData
	@param outputFunction
	@param functionArg
	@param text

 **/
static int typeBuffer(ISC_STATUS* status, char* buf, int offset,
					   Auth::UserData& uData, Firebird::IListUsers* callback,
					   Firebird::string& text)
{
	const char* p = &buf[offset];

	// Sanity checks
	if (*p++ != isc_info_svc_get_users)
	{
	    status[0] = isc_arg_gds;
	    status[1] = isc_gsec_params_not_allowed;
		status[2] = isc_arg_end;
		return -1;
	}
	FB_SIZE_T loop = static_cast<FB_SIZE_T>(isc_vax_integer (p, sizeof (USHORT)));
	p += sizeof (USHORT);
    if (p[loop] != isc_info_end)
	{
	    status[0] = isc_arg_gds;
	    status[1] = isc_gsec_params_not_allowed;
		status[2] = isc_arg_end;
		return -1;
	}

	// No data - stop processing
	if (! loop)
	{
		return -1;
	}

	// Old data left - use them
	if (offset)
	{
		memmove(&buf[offset], p, loop + 1);
		p = buf;
		loop += offset;
		offset = 0;
	}

	while (*p != isc_info_end)
	{
		fb_assert(p[loop] == isc_info_end);
		try
		{
			switch (*p++)
			{
			case isc_spb_sec_username:
				if (uData.user.get()[0])
				{
					LocalStatus status;
					CheckStatusWrapper statusWrapper(&status);

					if (callback)
					{
						setAttr(&statusWrapper, &uData);
						check(&statusWrapper);
						callback->list(&statusWrapper, &uData);
						check(&statusWrapper);
					}
					uData.clear(&statusWrapper);
					check(&statusWrapper);
				}
				parseString2(p, uData.user, loop);
				break;
			case isc_spb_sec_firstname:
				parseString2(p, uData.first, loop);
				break;
			case isc_spb_sec_middlename:
				parseString2(p, uData.middle, loop);
				break;
			case isc_spb_sec_lastname:
				parseString2(p, uData.last, loop);
				break;
			case isc_spb_sec_groupid:
				parseLong(p, uData.g, loop);
				break;
			case isc_spb_sec_userid:
				parseLong(p, uData.u, loop);
				break;
			case isc_spb_sec_admin:
				parseLong(p, uData.adm, loop);
				break;
			default:	// give up - treat it as gsec error
				text.assign(p - 1, loop + 1);
				return -1;
			}
		}
		catch (FB_SIZE_T newOffset)
		{
			memmove(buf, --p, newOffset);
			return newOffset;
		}
	}
	fb_assert(loop == 0);
	return 0;
}
Example #29
0
/**

	callRemoteServiceManager

	@brief	Calls service manager to execute command,
	specified in userInfo


	@param status
	@param handle
	@param userInfo
	@param outputFunction
	@param functionArg

 **/
void callRemoteServiceManager(ISC_STATUS* status,
							  isc_svc_handle handle,
							  Auth::UserData& userData,
							  Firebird::IListUsers* callback)
{
	char spb_buffer[1024];
	char* spb = spb_buffer;
	const int op = userData.op;
	if (op != Auth::DIS_OPER &&
		op != Auth::OLD_DIS_OPER &&
		op != Auth::MAP_SET_OPER &&
		op != Auth::MAP_DROP_OPER &&
		!userData.user.entered())
	{
	    status[0] = isc_arg_gds;
	    status[1] = isc_gsec_switches_error;
	    status[2] = isc_arg_end;
		return;
	}

	switch (op)
	{
	case Auth::ADD_OPER:
		stuffSpbByte(spb, isc_action_svc_add_user);
		userInfoToSpb(spb, userData);
		break;

	case Auth::MOD_OPER:
		stuffSpbByte(spb, isc_action_svc_modify_user);
		userInfoToSpb(spb, userData);
		break;

	case Auth::DEL_OPER:
		stuffSpbByte(spb, isc_action_svc_delete_user);
		stuffSpb2(spb, isc_spb_sec_username, userData.user.get());
		if (userData.role.entered())
		{
			stuffSpb2(spb, isc_spb_sql_role_name, userData.role.get());
		}
		break;

	case Auth::DIS_OPER:
	case Auth::OLD_DIS_OPER:
		{
			char usersDisplayTag = 0;
			checkServerUsersVersion(handle, usersDisplayTag);
			stuffSpbByte(spb, usersDisplayTag);
		}
		if (userData.user.entered())
		{
			stuffSpb2(spb, isc_spb_sec_username, userData.user.get());
		}
		if (userData.role.entered())
		{
			stuffSpb2(spb, isc_spb_sql_role_name, userData.role.get());
		}
		break;

	case Auth::MAP_SET_OPER:
		stuffSpbByte(spb, isc_action_svc_set_mapping);
		break;

	case Auth::MAP_DROP_OPER:
		stuffSpbByte(spb, isc_action_svc_drop_mapping);
		break;

	default:
	    status[0] = isc_arg_gds;
	    status[1] = isc_gsec_switches_error;
	    status[2] = isc_arg_end;
		return;
	}

	if (userData.database.entered()) {
		stuffSpb2(spb, isc_spb_dbname, userData.database.get());
	}

	fb_assert((size_t)(spb - spb_buffer) <= sizeof(spb_buffer));
	if (isc_service_start(status, &handle, 0, static_cast<USHORT>(spb - spb_buffer), spb_buffer) != 0)
	{
		return;
	}

	spb = spb_buffer;
	stuffSpbByte(spb, isc_info_svc_timeout);
	stuffSpbShort(spb, 4);
	stuffSpbLong(spb, 10);

	char resultBuffer[RESULT_BUF_SIZE + 4];
	Firebird::string text;

	ISC_STATUS_ARRAY temp_status;
	ISC_STATUS* local_status = status[1] ? temp_status : status;
	fb_utils::init_status(local_status);

	if (op == Auth::DIS_OPER || op == Auth::OLD_DIS_OPER)
	{
		const char request[] = {isc_info_svc_get_users};
		int startQuery = 0;
		Auth::StackUserData uData;

		for (;;)
		{
			isc_resv_handle reserved = 0;
			isc_service_query(local_status, &handle, &reserved, static_cast<USHORT>(spb - spb_buffer), spb_buffer,
				sizeof(request), request, RESULT_BUF_SIZE - startQuery, &resultBuffer[startQuery]);
			if (local_status[1])
			{
				return;
			}
			startQuery = typeBuffer(local_status, resultBuffer, startQuery, uData, callback, text);
			if (startQuery < 0)
			{
				break;
			}
		}

		if (uData.user.get()[0] && callback)
		{
			LocalStatus status;
			CheckStatusWrapper statusWrapper(&status);

			setAttr(&statusWrapper, &uData);
			check(&statusWrapper);
			callback->list(&statusWrapper, &uData);
			check(&statusWrapper);
		}
	}
	else
	{
		const char request = isc_info_svc_line;
		for (;;)
		{
			isc_resv_handle reserved = 0;
			isc_service_query(local_status, &handle, &reserved, 0, NULL,
				1, &request, RESULT_BUF_SIZE, resultBuffer);
			if (local_status[1])
			{
				return;
			}
			char *p = resultBuffer;
			if (*p++ == isc_info_svc_line)
			{
				FB_SIZE_T len = static_cast<FB_SIZE_T>(isc_vax_integer(p, sizeof(USHORT)));
				p += sizeof(USHORT);
				if (len > RESULT_BUF_SIZE)
				{
					len = RESULT_BUF_SIZE;
				}
				if (!len)
				{
					if (*p == isc_info_data_not_ready)
						continue;
					if (*p == isc_info_end)
						break;
				}
				p[len] = 0;
				text += p;
			}
		}

	}

	if (! text.isEmpty())
	{
		local_status[0] = isc_arg_interpreted;
		// strdup - memory leak in case of errors
		local_status[1] = reinterpret_cast<ISC_STATUS>(strdup(text.c_str()));
		local_status[2] = isc_arg_end;
	}
}
Example #30
0
// allow different users to read\write\delete files in lock directory
// in case of any error just log it and don't stop engine execution
void adjustLockDirectoryAccess(const char* pathname)
{
	PSECURITY_DESCRIPTOR pSecDesc = NULL;
	PSID pSID_Users = NULL;
	PSID pSID_Administrators = NULL;
	PACL pNewACL = NULL;
	try
	{
		// We should pass root directory in format "C:\" into GetVolumeInformation().
		// In case of pathname is not local folder (i.e. \\share\folder) let
		// GetVolumeInformation() return an error.
		Firebird::PathName root(pathname);
		const Firebird::PathName::size_type pos = root.find(':', 0);
		if (pos == 1)
		{
			root.erase(pos + 1, root.length());
			PathUtils::ensureSeparator(root);
		}

		DWORD fsflags;
		if (!GetVolumeInformation(root.c_str(), NULL, 0, NULL, NULL, &fsflags, NULL, 0))
			Firebird::system_error::raise("GetVolumeInformation");

		if (!(fsflags & FS_PERSISTENT_ACLS))
			return;

		// Adjust security for our new folder : allow BUILTIN\Users group to
		// read\write\delete files
		PACL pOldACL = NULL;

		if (GetNamedSecurityInfo((LPSTR) pathname,
				SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
				NULL, NULL, &pOldACL, NULL,
				&pSecDesc) != ERROR_SUCCESS)
		{
			Firebird::system_error::raise("GetNamedSecurityInfo");
		}

		SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
		if (!AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &pSID_Users))
		{
			Firebird::system_error::raise("AllocateAndInitializeSid");
		}

		if (!AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSID_Administrators))
		{
			Firebird::system_error::raise("AllocateAndInitializeSid");
		}

		EXPLICIT_ACCESS eas[2];
		memset(eas, 0, sizeof(eas));

		eas[0].grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE;
		eas[0].grfAccessMode = GRANT_ACCESS;
		eas[0].grfInheritance = SUB_OBJECTS_ONLY_INHERIT;
		eas[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
		eas[0].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
		eas[0].Trustee.ptstrName  = (LPSTR) pSID_Users;

		eas[1].grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE;
		eas[1].grfAccessMode = GRANT_ACCESS;
		eas[1].grfInheritance = SUB_OBJECTS_ONLY_INHERIT;
		eas[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
		eas[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
		eas[1].Trustee.ptstrName  = (LPSTR) pSID_Administrators;

		if (SetEntriesInAcl(2, eas, pOldACL, &pNewACL) != ERROR_SUCCESS)
			Firebird::system_error::raise("SetEntriesInAcl");

		if (SetNamedSecurityInfo((LPSTR) pathname,
				SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
				NULL, NULL, pNewACL, NULL) != ERROR_SUCCESS)
		{
			Firebird::system_error::raise("SetNamedSecurityInfo");
		}
	}
	catch (const Firebird::Exception& ex)
	{
		Firebird::string str;
		str.printf("Error adjusting access rights for folder \"%s\" :", pathname);

		iscLogException(str.c_str(), ex);
	}

	if (pSID_Users) {
		FreeSid(pSID_Users);
	}
	if (pSID_Administrators) {
		FreeSid(pSID_Administrators);
	}
	if (pNewACL) {
		LocalFree(pNewACL);
	}
	if (pSecDesc) {
		LocalFree(pSecDesc);
	}
}