How do I assign variables within WMI calls? - python

Using WMI within Python to request data from other servers. I know my credentials are correct, as I can hard-code them in the file and connect without issues. However, my string formatting for variables doesn't seem to be working.
I've tried both of these with no luck:
wmi_sql = wmi.WMI(SQLServer_raw, user="%s\\%s", password="%s") % (sql_domain, sql_user, sql_pass)
and
wmi_sql = wmi.WMI(SQLServer_raw, user="{0}\\{1}", password="{2}").format(sql_domain, sql_user, sql_pass)
Tried moving the format() call inside, but it didn't work either:
wmi_sql = wmi.WMI(SQLServer_raw, user="{0}\\{1}", password="{2}".format(sql_domain, sql_user, sql_pass))

You've got the string formatters in the wrong place. They need to be used for each string, not the result of the call. As written, python thinks you want to call wmi.WMI and then apply the formatting to whatever is returned.
Try:
wmi_sql = wmi.WMI(SQLServer_raw, user="%s\\%s" % (sql_domain, sql_user),
password=sql_pass)

In one and two you are executing wmi.WMI() and then doing the formatting on the return type. In the third example you are formatting the value of the password but providing three parameters to it hoping it would build user variable. If you really want to build user and password dynamically do this:
usr ="{0}\\{1}".format(sql_domain,ql_user)
wmi.WMI(SQLServer_raw, user=usr, password=sql_pass)

Related

Create strings with user defined variables from user input string

Is there a method to get a user input with a variable from the user input?
I don't even know how to describe it.
Consider this.
I want to have a user input a string and within that string have a variable.
user_defined_command_input = "config ap {ap_name} {old_ap_name}"
The idea is, instead of me generating a template for every possible command, they can generate the command template using string interpolation without having to know python. The idea is that they have a list of commands generated for hundreds of devices and they get to manage the template of the commands they need.
user_defined_command_input = "config ap {new_AP_name} {mac_address} {description}"
OR
user_defined_command_input = "config description {short_description}
Since they should be able to name their own variables, I can't hardcode them.
I understand that there are security risks with unsanitized code being injected. So I would love to learn about that too.
Use .format()
user_defined_command = "config ap {ap_name} {old_ap_name}"
user_defined_variables = {"ap_name": "freewifi", "old_ap_name": "wifi"}
command = user_defined_command.format(**user_defined_variables)
# command == "config ap freewifi wifi"
Do not ever trust user input though! Always sanitize their input and use a whitelist of allowed values/characters. Arbitrary command injections are a huge deal and can negate any other security you have in place.
Also, in my honest opinion it would be best to reconsider implementing this, as it is very hard to get right.
You can use the command .split("") for the most part and that solves a lot fo your problems.
Where command = input("What's your command").split() for the input "config ap newTestVar oldTestVar" would set the command variable to ["config", "ap", "newTestVar", "oldTestVar"]
if your user never inputs spaces to screw with your commands, you can see config and AP are always at 0 and 1 index and what your looking for is the 2nd and 3rd variable always.
Next you can use globals() and vars() which can get and create the values of variables to do
vars()[command[2]] = globals()[command[3]]
and you'll see that if you check the variable now named newTestVarit should be set to the value of oldTestVar
You can use eval() and do something like this:
formatter = lambda text: eval(f'f"""{text}"""')
ap_name = 'AP NAME' # Example data
old_ap_name = 'OLD AP NAME' # More example data
user_defined_command_input = 'config ap {ap_name}{old_ap_name}'
print(formatter(user_defined_command_input))
Output: config ap AP NAMEOLD AP NAME
But as you have mentioned, be careful with injection like this. It can be quite dangerous.
It's not clear to me what exactly you're asking, but here's a guess based on the accepted answer to How to postpone/defer the evaluation of f-strings?:
import inspect
class MagicFstring:
def __init__(self, payload):
self.payload = payload
def __str__(self):
vars = inspect.currentframe().f_back.f_globals.copy()
vars.update(inspect.currentframe().f_back.f_locals)
return self.payload.format(**vars)
user_defined_command_input = MagicFstring("config ap {ap_name} {old_ap_name}")
ap_name = 'someapp'
old_ap_name = 'oldapp'
print(user_defined_command_input) # -> config ap someapp oldapp

LLDB: Set breakpoint at offset from function start using python api

I have a lldb python module with a simple setup:
def __lldb_init_module (debugger, dict):
target = debugger.GetSelectedTarget()
target.DeleteAllBreakpoints()
process = target.GetProcess()
I can easily set a breakpoint at the start of a function using:
breakpoint = target.BreakpointCreateByName("functionName", "moduleName")
breakpoint.SetScriptCallbackFunction( "python_module.bp_hit" )
and I know this works because my bp_hit function is called correctly.
However, I really need the breakpoint set at X number of bytes from the start of the address of functionName. If I knew the address of the functionName, I could simply add X to the address and use BreakpointCreateByAddress.
What is the python code that will provide me the address of the functionName?
Use SBTarget::FindFunctions to find the SBSymbolContext(s) that match a your function name. That returns a list of SBSymbolContext matches (since there may be more than one.) SBSymbolContext::GetStartAddress will give you an SBAddress for the start of that symbol. Then use SBAddress::OffsetAddress to add your offset. There is a SBTarget::CreateBreakpointByAddress but annoyingly enough it only takes an lldb::addr_t not an SBAddress. You can get an lldb::addr_t from an SBAddress with SBAddress::GetLoadAddress() passing in your target.
An alternative to Jim's answer is to use the FindSymbols function of SBTarget.

Making all attributes and methods available for a socket server in Python

I use a Raspberry Pi to collect sensor data and set digital outputs, to make it easy for other applications to set and get values I'm using a socket server. But I am having some problems finding an elegant way of making all the data available on the socket server without having to write a function for each data type.
Some examples of values and methods I have that I would like to make available on the socket server:
do[2].set_low() # set digital output 2 low
do[2].value=0 # set digital output 2 low
do[2].toggle() # toggle digital output 2
di[0].value # read value for digital input 0
ai[0].value # read value for analog input 0
ai[0].average # get the average calculated value for analog input 0
ao[4].value=255 # set analog output 4 to byte value 255
ao[4].percent=100 # set analog output 4 to 100%
I've tried eval() and exec():
self.request.sendall(str.encode(str(eval('item.' + recv_string)) + '\n'))
eval() works unless I am using equal sign (=), but I'm not to happy about the solution because of dangers involved. exec() does the work but does not return any value, also dangerous.
I've also tried getattr():
recv_string = bytes.decode(self.data).lower().split(';')
values = getattr(item, recv_string[0])
self.request.sendall(str.encode(str(values[int(recv_string[1])].value) + '\n'))
^^^^^
This works for getting my attributes, and the above example works for getting the value of the attribute I am getting with getattr(). But I can not figure out how to use getattr() on the value attribute as well.
The semi-colon (;) is used to split the incoming command, I've experimented with multiple ways of formatting the commands:
# unit means that I want to talk to a I/O interface module,
# and the name specified which one
unit;unit_name;get;do;1
unit;unit_name;get;do[1]
unit;unit_name;do[1].value
I am free to choose the format since I am also writing the software that uses these commands. I have not yet found a good format which covers all my needs.
Any suggestions how I can write an elegant way of accessing and returning the data above? Preferably with having to add new methods to the socket server every time a new value type or method is added to my I/O ports.
Edit: This is not public, it's only available on my LAN.
Suggestions
Make your API all methods so that eval can always be used:
def value_m(self, newValue=None):
if newValue is not None:
self.value = newValue
return self.value
Then you can always do
result = str(eval(message))
self.request.sendall(str.encode(result + '\n'))
For your message, I would suggest that your messages are formatted to include the exact syntax of the command exactly so that it can be evaled as-is, e.g.
message = 'do[1].value_m()' # read a value, alternatively...
message = 'do[1].value_m(None)'
or to write
message = 'do[1].value_m(0)' # write a value
This will make it easy to keep your messages up-to-date with your API, because they must match exactly, you won't have a second DSL to deal with. You really don't want to have to maintain a second API, on top of your IO one.
This is a very simple scheme, suitable for a home project. I would suggest some error handling in evaluation, like so:
import traceback
try:
result = str(eval(message))
except Exception:
result = traceback.format_exc()
self.request.sendall(str.encode(result + '\n'))
This way your caller will receive a printout of the exception traceback in the returned message. This will make it much, much easier to debug bad calls.
NOTE If this is public-facing, you cannot do this. All input must be sanitised. You will have to parse each instruction and compare it to the list of available (and desirable) commands, and verify input validity and validity ranges for everything. For such a scenario you are better off simply using one of the input validation systems used for web services, where this problem receives a great deal of attention.

Python hash holding file handles

So I'm working on a script that will automatically download certain files from IRC XDCC bots when run. These requests are asynchronous and there can be a varying number, depending on a config file so I wanted to keep the file handles in a hash table or library so they could easily be referenced based on who the file sender was and the file they are sending (read during a triggered event). Python is complaining saying SyntaxError: can't assign to function call so I'm guessing it won't work quite how I want.
Any easier way to do this? Am I barking up the wrong tree here?
Thanks! -Russell
The problem is that the left side of an assignment statement must be an lvalue, that is something that the compiler knows has a memory address, like a variable. It is the same in other programming languages. The return value of a function is an rvalue, or a pure value.
These are other illegal assignments:
f() = 1
2 = 1
None = 0
[1,2] = []
Note that the follwing are syntactically correct because the compiler knows how to compute an address for the memory location to be assigned:
f().a = None
[1,2][0] = 0
Create an empty hash:
files = {}
Add items to the hash:
files["gin"] = open('ginpachi.txt','w')
files["ahq"] = open('ahq[DaBomb].txt','w')
Reference them like you would a normal file handler
files["gin"].close()
...
Unfortunately, there wasn't any information on this on the web (specifically with hashes and file handles).
Case closed

How do you escape a dash in Jython/Websphere?

I have a Jython script that is used to set up a JDBC datasource on a Websphere 7.0 server. I need to set several properties on that datasource. I am using this code, which works, unless value is '-'.
def setCustomProperty(datasource, name, value):
parms = ['-propertyName', name, '-propertyValue', value]
AdminTask.setResourceProperty(datasource, parms)
I need to set the dateSeparator property on my datasource to just that - a dash. When I run this script with setCustomProperty(ds, 'dateSeparator', '-') I get an exception that says, "Invalid property: ". I figured out that it thinks that the dash means that another parameter/argument pair is expected.
Is there any way to get AdminTask to accept a dash?
NOTE: I can't set it via AdminConfig because I cannot find a way to get the id of the right property (I have multiple datasources).
Here is a solution that uses AdminConfig so that you can set the property value to the dash -. The solution accounts for multiple data sources, finding the correct one by specifying the appropriate scope (i.e. the server, but this could be modified if your datasource exists within a different scope) and then finding the datasource by name. The solution also accounts for modifying the existing "dateSeparator" property if it exists, or it creates it if it doesn't.
The code doesn't look terribly elegant, but I think it should solve your problem :
def setDataSourceProperty(cell, node, server, ds, propName, propVal) :
scopes = AdminConfig.getid("/Cell:%s/Node:%s/Server:%s/" % (cell, node, server)).splitlines()
datasources = AdminConfig.list("DataSource", scopes[0]).splitlines()
for datasource in datasources :
if AdminConfig.showAttribute(datasource, "name") == ds :
propertySet = AdminConfig.list("J2EEResourcePropertySet", datasource).splitlines()
customProp = [["name", propName], ["value", propVal]]
for property in AdminConfig.list("J2EEResourceProperty", propertySet[0]).splitlines() :
if AdminConfig.showAttribute(property, "name") == propName :
AdminConfig.modify(property, customProp)
return
AdminConfig.create("J2EEResourceProperty", propertySet[0], customProp)
if (__name__ == "__main__"):
setDataSourceProperty("myCell01", "myNode01", "myServer", "myDataSource", "dateSeparator", "-")
AdminConfig.save()
Please see the Management Console preferences settings. You can do what you are attempting now and you should get to see the Jython equivalent that the Management Console is creating for its own use. Then just copy it.
#Schemetrical solution worked for me. Just giving another example with jvm args.
Not commenting on the actual answer because I don't have enough reputation.
server_name = 'server1'
AdminTask.setGenericJVMArguments('[ -serverName %s -genericJvmArguments "-agentlib:getClasses" ]' % (server_name))
Try using a String instead of an array to pass the parameters using double quotes to surround the values starting with a dash sign
Example:
AdminTask.setVariable('-variableName JDK_PARAMS -variableValue "-Xlp -Xscm250M" -variableDescription "-Yes -I -can -now -use -dashes -everywhere :-)" -scope Cell=MyCell')

Categories

Resources