Python variable substitution - python

I have a script that calls a list of linux guests I am trying to tidy up. Here is the code:
#!/usr/bin/python
guests = ['guest1','guest2','guest3','guest*']
def serverCheck(guestList)
for g in guestList:
server = AdminControl.completeObjectName('cell=tstenvironment,node=guest1,name=uatenvironment,type=Server,*')
try:
status = AdminControl.getAttribute(server, 'state')
print g + status
except:
print "Error %s is down." % g
serverCheck(guests)
The problem lies in this line:
server = AdminControl.completeObjectName('cell=Afcutst,node=%s,name=afcuuat1,type=Server,*') % g
How do I use my list to populate the node variable while still being able to pass the info within the parentheses to the AdminControl function?

The argument string itself is the argument to the % operator, not the return value of the function call.
server = AdminControl.completeObjectName(
'cell=Afcutst,node=%s,name=afcuuat1,type=Server,*' % (g,)
)
Peeking into the crystal ball, Python 3.6 will allow you to write
server = AdminControl.completeObjectName(
f'cell=Afcutst,node={g},name=afcuuat1,type=Server,*'
)
embedding the variable directly into a special format string literal.

can you try like this
AdminControl.completeObjectName('cell=tstenvironment,node=%s,name=uatenvironment,type=Server,*'%g)

For more readability I would suggest this and also using the same way to format strings from variables (here I chose str.format)
guests = ['guest1','guest2','guest3','guest*']
def serverCheck(guestList)
name_tpl = 'cell=tstenvironment,node={},name=uatenvironment,type=Server,*'
for g in guestList:
obj_name = name_tpl.format(g)
server = AdminControl.completeObjectName(obj_name)
try:
status = AdminControl.getAttribute(server, 'state')
print '{}: {}'.format(g, status)
except:
print 'Error {} is down'.format(g)
serverCheck(guests)

Related

python-ldap unable to do any basic search queries on open server

I have been trying to do some basic search queries, but I am unable to connect to an open LDAP server regardless. I tried a couple of servers, and none of them worked. I used Apache Directory Studio to make sure that the keyword was there but it did not work either way. I tried a variety of different code from different sources.
This was the first one I used
:
https://www.linuxjournal.com/article/6988
import ldap
keyword = "boyle"
def main():
server = "ldap.forumsys.com"
username = "cn=read-only-admin,dc=example,dc=com"
password = "password"
try:
l = ldap.open(server)
l.simple_bind_s(username,password)
print "Bound to server . . . "
l.protocol_version = ldap.VERSION3
print "Searching . . ."
mysearch (l,keyword)
except ldap.LDAPError:
print "Couldnt connect"
def mysearch(l, keyword):
base = ""
scope = ldap.SCOPE_SUBTREE
filter = "cn=" + "*" + keyword + "*"
retrieve_attributes = None
count = 0
result_set = []
timeout = 0
try:
result_id = l.search(base, scope, filter, retrieve_attributes)
while l != 1:
result_id = l.search(base, scope,filter, retrieve_attributes)
result_type, result_data = l.result(result_id, timeout)
if result_data == []:
break
else:
if result_type == ldap.RES_SEARCH_ENTRY:
result_set.append(result_data)
if len (result_set = 0):
print "No Results"
for i in range (len(result_set)):
for entry in result_set[i]:
try:
name = entry[1]['cn'][0]
mail = entry[1]['mail'][0]
#phone = entry[1]['telephonenumber'][0]
#desc = entry[1]['description'][0]
count = count + 1
print name + mail
except:
pass
except ldap.LDAPError, error_message:
print error_message
main()
Every time I ran this program, I received an error
{'desc': u"No such object"}
I also tried this
import ldap
try:
l = ldap.open("ldap.example.com")
except ldap.LDAPError, e:
print e
base_dn = "cn=read-only-admin,dc=example,dc=com"
search_scope = ldap.SCOPE_SUBTREE
retrieve_attributes = None
search_filter = "uid=myuid"
try:
l_search = l.search(base_dn, search_scope, search_filter, retrieve_attributes)
result_status, result_data = l.result(l_search, 0)
print result_data
except ldap.LDAPError, e:
print e
The error on this one was
{'desc': u"Can't contact LDAP server"}
I spent about 5 hours trying to figure this out. I would really appreciate it if you guys could give me some advice. Thanks.
There are several bogus things in there.
I will only comment your first code sample because it can be used by anyone with that public LDAP server.
l = ldap.open(server)
Function ldap.open() is deprecated since many years. You should use function ldap.initialize() with LDAP URI as argument instead like this:
l = ldap.initialize("ldap://ldap.forumsys.com")
l_search = l.search(..)
This is the asynchronous method which just returns a message ID (int) of the underlying OpenLDAP C API (libldap). It's needed if you want to retrieve extended controls returned by the LDAP server along with search results. Is that what you want?
As a beginner you probably want to use the simpler method LDAPObject.search_s() which immediately returns a list of (DN, entry) 2-tuples.
See also: python-ldap -- Sending LDAP requests
while l != 1
This does not make sense at all because l is your LDAPObject instance (LDAP connection object). Note that LDAPObject.search() would raise an exception if it gets an Integer error code from OpenLDAP's libldap. No need to do C-style error checks at this level.
filter = "cn=" + "" + keyword + ""
If keyword can be arbitrary input this is a prone to LDAP injection attacks. Don't do that.
For adding arbitrary input into a LDAP filter use function ldap.filter.escape_filter_chars() to properly escape special characters. Also avoid using variable name filter because it's the name of a built-in Python function and properly enclose the filter in parentheses.
Better example:
ldap_filter = "(cn=*%s*)" % (ldap.filter.escape_filter_chars(keyword))
base = ""
The correct search base you have to use is:
base = "dc=example,dc=com"
Otherwise ldap.NO_SUCH_OBJECT is raised.
So here's a complete example:
import pprint
import ldap
from ldap.filter import escape_filter_chars
BINDDN = "cn=read-only-admin,dc=example,dc=com"
BINDPW = "password"
KEYWORD = "boyle"
ldap_conn = ldap.initialize("ldap://ldap.forumsys.com")
ldap_conn.simple_bind_s(BINDDN, BINDPW)
ldap_filter = "(cn=*%s*)" % (ldap.filter.escape_filter_chars(KEYWORD))
ldap_results = ldap_conn.search_s(
"dc=example,dc=com",
ldap.SCOPE_SUBTREE,
ldap_filter,
)
pprint.pprint(ldap_results)

How to write an exception in the following case in Python3?

I need to revise a python code (given by a programmer) which I would like to use for a genealogy project of mine. I am very new to python and start being able to read code. Yet, I do not know how to fix the following thing.
I get the following error message when executing the code:
self['gebort'] += ", Taufe: %s" % place.get_title()
KeyError: 'gebort'
The issue is that for one of the persons in my database only the date of baptism (here: Taufe) is known but not the date of birth. This is were the code fails.
This is the relevant snippet of the code basis:
birth_ref = person.get_birth_ref()
if birth_ref:
birth = database.get_event_from_handle(birth_ref.ref)
self['gjahr'] = birth.get_date_object().get_year()
if self['gjahr'] >= 1990:
self['mindj'] = True
self['gebdat'] = dd.display(birth.get_date_object())
self['plaingebdat'] = self['gebdat']
place_handle = birth.get_place_handle()
self['geborthandle'] = place_handle
place = database.get_place_from_handle(place_handle)
if place:
self['gebort'] = place.get_title()
self['plaingebort'] = self['gebort']
for eventref in person.get_event_ref_list():
event = database.get_event_from_handle(eventref.ref)
if event.get_type() in (gramps.gen.lib.EventType.CHRISTEN, gramps.gen.lib.EventType.BAPTISM):
self['gebdat'] += ", Taufe: %s" % dd.display(event.get_date_object())
place_handle = event.get_place_handle()
place = database.get_place_from_handle(place_handle)
if place:
self['gebort'] += ", Taufe: %s" % place.get_title()
Now, I do not know to add an exception handling when there is no birth date/place found so that the code would not give out any values of birth. Would somebody be able to point me to the right direction?
Instead of:
dict_name['gebort'] += ", Taufe: %s" % place.get_title()
you could write
dict_name['gebort'] = dict_name.get('gebort', '') + ", Taufe: %s" % place.get_title()
As already written, naming something self is not clever, or is the code above from a class derived from dict? Using .get you can define what is returned in case if there is no key of that name, in the exampe an empty string.

Input parameter instead of using raw_input to write python function

we are writing a def. here is our logic:
input table's field name,
input parameter to the parentheses(parentheses is set for some commands who needs to input string such as:
interface fa(1)/(2)
ip address (3) (4))
input parameter to the parentheses (if requested),then will select command from sqlite db.
interface fa0/1
ip address 192.168.1.1 255.255.255.0
Finally output commands.
Recently, my partner requests me that I have not to use input. He told me that I should use "input parameter". And I didn't understand him and he is not responding me about this question.
I have no idea now. What does it mean?
This is my and my partners python codes:
def get_input():
a = input("function and params (comma separated):")
b = input("device:")
pattern = re.compile('\(.*?\)')
output_commands = []
params = a.split(',')
function = params[0]
print (params)
counter = 1
for result in readciscodevice(function,b):
command = result[0]
found_parentheses_list = re.findall(pattern, command)
output_command = command
for i, param_placeholder in enumerate(found_parentheses_list):
param = params[counter]
output_command = re.sub(pattern, param, output_command, count=1)
counter +=1
output_commands.append(output_command)
return output_commands
# other program calls:
commands = get_input()
for command in commands:
#do sth, print for example
print(command)

winappdbg NtWriteVirtualMemory handle error

I'm using winappdbg in order to set breakpoint on ntdll!NtWriteVirtualMemory.
My goal is to check if the memory protection of the remote process is page_execute.
So I succeeded set breakpoint on NtWriteVirtualMemory, the problem is that I got handle in
one of the parameters in the function(for example 0x20) , but when I use it in the script it's invalid.
I tried using winappdbg.win32.VirtualQueryEx(got handle is invalid)
Any ideas?
def action_callback( event ):
print "ntdll!NtWriteVirtualMemory was called!"
process = event.get_process()
thread = event.get_thread()
# Get the address of the top of the stack.
stack = thread.get_sp()
# Get the return address of the call.
retAddress = process.read_pointer( stack)
print "ret address " + hex(retAddress)
processHandle = process.read_pointer( stack+4 )
print "processHandle " + hex(processHandle)
BaseAddress = process.read_pointer( stack+8 )
print "BaseAddress " + hex(BaseAddress)
Buffer = process.read_pointer( stack+12 )
print "Buffer " + hex(Buffer)
NumberOfBytesToWrite = process.read_pointer( stack+16 )
print "NumberOfBytesToWrite " + hex(NumberOfBytesToWrite)
NumberOfBytesWritten = process.read_pointer( stack+16 )
print "NumberOfBytesWritten " + hex(NumberOfBytesWritten)
print "====================="
print "virtualQuery - " + VirtualQueryEx(int(processHandle), BaseAddress)
Thanks!!
I'm afraid what you're trying to do can never work - Win32 handles are only valid within the process that creates them, and you're trying to use a handle in your script that was created by the process you're debugging.
What you need to do is try to get the process ID instead. Process IDs are global, and you can create your own handles to them using OpenProcess(). You'll have to hook all of the functions that can return a process handle, get their parameters and return values, and from there you can map the foreign handles into process IDs.
Another choice is to try to resolve the handle into a process ID by calling GetProcessID() within the target process (it will fail if you do it from the script for the same reasons explained above). This is a bit tricky since code injection may fail at times, I'd recommend using more hooks instead. But if you want to try this out anyway, event.get_process().inject_code() is your friend: http://winappdbg.sourceforge.net/doc/latest/reference/winappdbg.process.Process-class.html#inject_code
Finally I used DuplicateHandle. It worked fine!
source_pid = event.get_process().get_pid()
print 'source pid =', source_pid
source_phandle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, FALSE, source_pid)
print 'source phandle =', source_phandle
current_phandle = win32process.GetCurrentProcess()
print 'current phandle =', current_phandle
duplicated_handle = win32api.DuplicateHandle(source_phandle, processHandle, current_phandle,
0, FALSE, win32con.DUPLICATE_SAME_ACCESS)
print 'dup h =', duplicated_handle
source_process_name = win32process.GetModuleFileNameEx(source_phandle, 0)
print "source_process_name - ", (source_process_name)
q = VirtualQueryEx(duplicated_handle.handle, BaseAddress)
print "virtualQuery - is_executable() " + str(q.is_executable())
target_process_name = win32process.GetModuleFileNameEx(duplicated_handle.handle, 0)
print "target_process_name - ", (target_process_name)
VirtualQueryEx works fine!
The problem now that GetModulefileNameEx to the duplicated handle returns me "the handle is invalid".
How can I reveal the target process name?
Thanks!

Userfriendly way of handling config files in python?

I want to write a program that sends an e-mail to one or more specified recipients when a certain event occurs. For this I need the user to write the parameters for the mail server into a config. Possible values are for example: serveradress, ports, ssl(true/false) and a list of desired recipients.
Whats the user-friendliest/best-practice way to do this?
I could of course use a python file with the correct parameters and the user has to fill it out, but I wouldn't consider this user friendly. I also read about the 'config' module in python, but it seems to me that it's made for creating config files on its own, and not to have users fill the files out themselves.
Are you saying that the fact that the config file would need to be valid Python makes it unfriendly? It seems like having lines in a file like:
server = 'mail.domain.com'
port = 25
...etc would be intuitive enough while still being valid Python. If you don't want the user to have to know that they have to quote strings, though, you might go the YAML route. I use YAML pretty much exclusively for config files and find it very intuitive, and it would also be intuitive for an end user I think (though it requires a third-party module - PyYAML):
server: mail.domain.com
port: 25
Having pyyaml load it is simple:
>>> import yaml
>>> yaml.load("""a: 1
... b: foo
... """)
{'a': 1, 'b': 'foo'}
With a file it's easy too.
>>> with open('myconfig.yaml', 'r') as cfile:
... config = yaml.load(cfile)
...
config now contains all of the parameters.
I doesn't matter technically proficient your users are; you can count on them to screw up editing a text file. (They'll save it in the wrong place. They'll use MS Word to edit a text file. They'll make typos.) I suggest making a gui that validates the input and creates the configuration file in the correct format and location. A simple gui created in Tkinter would probably fit your needs.
I've been using ConfigParser. It's designed to read .ini style files that have:
[section]
option = value
It's quite easy to use and the documentation is pretty easy to read. Basically you just load the whole file into a ConfigParser object:
import ConfigParser
config = ConfigParser.ConfigParser()
config.read('configfile.txt')
Then you can make sure the users haven't messed anything up by checking the options. I do so with a list:
OPTIONS =
['section,option,defaultvalue',
.
.
.
]
for opt in OPTIONS:
section,option,defaultval = opt.split(',')
if not config.has_option(section,option):
print "Missing option %s in section %s" % (option,section)
Getting the values out is easy too.
val = config.get('section','option')
And I also wrote a function that creates a sample config file using that OPTIONS list.
new_config = ConfigParser.ConfigParser()
for opt in OPTIONS:
section,option,defaultval = opt.split(',')
if not new_config.has_section(section):
new_config.add_section(section)
new_config.set(section, option, defaultval)
with open("sample_configfile.txt", 'wb') as newconfigfile:
new_config.write(newconfigfile)
print "Generated file: sample_configfile.txt"
What are the drawbacks of such a solution:
ch = 'serveradress = %s\nport = %s\nssl = %s'
a = raw_input("Enter the server's address : ")
b = 'a'
bla = "\nEnter the port : "
while not all(x.isdigit() for x in b):
b = raw_input(bla)
bla = "Take care: you must enter digits exclusively\n"\
+" Re-enter the port (digits only) : "
c = ''
bla = "\nChoose the ssl option (t or f) : "
while c not in ('t','f'):
c = raw_input(bla)
bla = "Take care: you must type f or t exclusively\n"\
+" Re-choose the ssl option : "
with open('configfile.txt','w') as f:
f.write(ch % (a,b,c))
.
PS
I've read in the jonesy's post that the value in a config file may have to be quoted. If so, and you want the user not to have to write him/her-self the quotes, you simply add
a = a.join('""')
b = b.join('""')
c = c.join('""')
.
EDIT
ch = 'serveradress = %s\nport = %s\nssl = %s'
d = {0:('',
"Enter the server's address : "),
1:("Take care: you must enter digits exclusively",
"Enter the port : "),
2:("Take care: you must type f or t exclusively",
"Choose the ssl option (t or f) : ") }
def func(i,x):
if x is None:
return False
if i==0:
return True
elif i==1:
try:
ess = int(x)
return True
except:
return False
elif i==2:
if x in ('t','f'):
return True
else:
return False
li = len(d)*[None]
L = range(len(d))
while True:
for n in sorted(L):
bla = d[n][1]
val = None
while not func(n,val):
val = raw_input(bla)
bla = '\n '.join(d[n])
li[n] = val.join('""')
decision = ''
disp = "\n====== If you choose to process, =============="\
+"\n the content of the file will be :\n\n" \
+ ch % tuple(li) \
+ "\n==============================================="\
+ "\n\nDo you want to process (type y) or to correct (type c) : "
while decision not in ('y','c'):
decision = raw_input(disp)
disp = "Do you want to process (type y) or to correct (type c) ? : "
if decision=='y':
break
else:
diag = False
while not diag:
vi = '\nWhat lines do you want to correct ?\n'\
+'\n'.join(str(j)+' - '+line for j,line in enumerate((ch % tuple(li)).splitlines()))\
+'\nType numbers of lines belonging to range(0,'+str(len(d))+') separated by spaces) :\n'
to_modify = raw_input(vi)
try:
diag = all(int(entry) in xrange(len(d)) for entry in to_modify.split())
L = [int(entry) for entry in to_modify.split()]
except:
diag = False
with open('configfile.txt','w') as f:
f.write(ch % tuple(li))
print '-*- Recording of the config file : done -*-'

Categories

Resources