2

I have a socket connection where the client submits their Windows username. The server then runs 'net user username /domain' to find their expiration date. I am trying to find the string "Password expires" and print that line.

print(line) 

Gives me nothing. If I use

print(result) 

I do get the entire results for the command but it is kind of garbled looking. How do I get the line with "Password expires"? And do I need to format this a certain way so the "result" doesn't look messed up?

 import subprocess import os from socket import socket, gethostbyname, AF_INET, SOCK_DGRAM import sys PORT_NUMBER = 3555 SIZE = 1024 hostName = gethostbyname( '0.0.0.0' ) mySocket = socket( AF_INET, SOCK_DGRAM ) mySocket.bind( (hostName, PORT_NUMBER) ) print ("Test server listening on port {0}\n".format(PORT_NUMBER)) # Receive no more than 1024 bytes while True: (data,addr) = mySocket.recvfrom(SIZE) try: #print >>sys.stderr, 'Received data from', addr while True: print (data.decode()) batcmd=('net user ' + data.decode() + ' /domain') result = subprocess.check_output(batcmd, shell=True) # print (result) shows details but it is messy looking for line in result: if str(line).startswith("Password expires"): print (line) # if data: # print >>sys.stderr, 'sending data back to the client' # mySocket.sendto({ },addr).format(line) # # TypeError: sendto() argument 1 must be string or buffer, not dict # else: # print >>sys.stderr, 'no more data from', client_address # break break # send result back to client ? #mySocket.send(result.encode('ascii')) sys.exit() finally: print('closing socket') mySocket.close() 

If I print(result), everything looks like this:

.local.\r\n\r\nUser Name js83838\r\nFull Name John Doe \r\n\Country Code Comment Here. Account active Locked\r\nAccount expires more data like this and this 

UPDATE

I am trying this and it displays every single line instead of 1. Every line has a b' in front of it and looks aligned properly.

while True: (data,addr) = mySocket.recvfrom(SIZE) #print >>sys.stderr, 'Received data from', addr while True: print (data.decode()) batcmd=('net user ' + data.decode() + ' /domain') result = subprocess.check_output(batcmd, shell=True) # print (result) # shows details but it is messy looking for line in result.splitlines(): if str(line).find("Password expires"): print (line) 
1
  • It displays results but they don't look exactly like when running the command in the cmd prompt. Several of the lines run together and some of the lines are tabbed in further than the next. So it looks like everything is printed at an angle. Commented Sep 21, 2017 at 15:53

2 Answers 2

1

subprocess.check_output does not return lines but a buffer of bytes.

After decoding it to a string (required in Python 3):

result = result.decode("ascii",errors="ignore") 

you need to split according to lines, or your loop will yield char by char, and startswith doesn't crash but finds nothing.

for line in result.splitlines(): 

does the trick. So there were 2 issues: checking whole buffer with startswith, and not decoding to str which made the searches find nothing.

Alternately, don't decode but do if line.startswith(b"Password expires"):. This makes the code compatible with Python 2 as a bonus.

Aside: be careful when parsing output of net user as string localization may make your program miss the information.

Sign up to request clarification or add additional context in comments.

8 Comments

when I add .splitlines() is still doesn't display anything
try to print line and see what's printed.
I added "for line in result.splitlines():" to the code above and when I run it with the print (line), it prints the username and goes straight to "closing socket"
also tried changing startswith("Password") to contains("Password") and that gives me an error 'str' object has no attribute 'contains'
I took out try/except and it still doesn't display anything. I changed startswith("Password expires") to find("Password expires") and it displays every single line formatted properly
|
0

Here is a solution that allows you to: get the output line by line, get only the line with "Password expires", not use shell=True.

batcmd=['net', 'user', data.decode(), '/domain') net_process = subprocess.Popen(batcmd, stdout=subprocess.PIPE) grep_process= subprocess.Popen(["findstr", "Password expires"], stdin=net_process.stdout, stdout=subprocess.PIPE) # or grep depending on your system for line in grep_process.stdout.readlines(): # do what you want 

2 Comments

I get an error \lib\subrocess.py line 947, in init line 1224, in _execute_child startupinfo) FileNotFoundError: [WinError 2] The system cannot find the file specified
Ok, this is probably because grep doesn't exist in windows. Google tells me an equivalent is findstr.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.