-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Webpage to change passwords for a given OU in active directory. This only uses HTTP authentication and there is no SSL yet. This is not recommended for users that must have secure accounts. It’s current implementation is simply to allow our school librarians an easy to use interface which gives them the ability to reset student passwords. The users in the config.dat are users who will have access to the webpage.
- Loading branch information
0 parents
commit 39ba861
Showing
3 changed files
with
184 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"Users": [["test0","test0Pass"],["test1","test1Pass"]]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import web, json | ||
from web import form | ||
import re, os, subprocess | ||
import base64 | ||
|
||
render = web.template.render('templates/') | ||
|
||
urls = ( | ||
'/','Index', | ||
'/login','Login', | ||
'/getOUs', 'getOUs', | ||
'/getNames', 'getNames', | ||
'/setPass', 'setPass' | ||
) | ||
|
||
app = web.application(urls,globals()) | ||
|
||
allowed = [] | ||
c = open("config.dat", 'r') | ||
config = json.load(c) | ||
c.close() | ||
users = config["Users"] | ||
for user in users: | ||
userObj = (user[0].encode("ascii"), user[1].encode("ascii")) | ||
allowed.append(userObj) | ||
|
||
class Index: | ||
def GET(self): | ||
if web.ctx.env.get('HTTP_AUTHORIZATION') is not None: | ||
return render.base() | ||
else: | ||
raise web.seeother('/login') | ||
|
||
class Login: | ||
def GET(self): | ||
auth = web.ctx.env.get('HTTP_AUTHORIZATION') | ||
authreq = False | ||
if auth is None: | ||
authreq = True | ||
else: | ||
auth = re.sub('^Basic ','',auth) | ||
username,password = base64.decodestring(auth).split(':') | ||
if (username,password) in allowed: | ||
raise web.seeother('/') | ||
else: | ||
authreq = True | ||
if authreq: | ||
web.header('WWW-Authenticate','Basic realm="Auth example"') | ||
web.ctx.status = '401 Unauthorized' | ||
return | ||
|
||
class getOUs: | ||
def POST(self): | ||
w = open("getOUs.ps1", 'w') | ||
w.write("import-module ActiveDirectory -Force\n") | ||
#w.write("#requires -Modules ActiveDirectory") | ||
w.write("Get-ADOrganizationalUnit -LDAPFilter '(name=*)' -SearchBase 'OU=Students,DC=School,DC=edu' -SearchScope OneLevel | ft Name | Out-File C:\folder\YOGs.txt\n") | ||
w.close() | ||
cmd = subprocess.Popen(["C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe", "-ExecutionPolicy", "Unrestricted", ".\"./getOUs.ps1\";"]) | ||
OUs = open("YOGs.txt", 'r') | ||
OUs.readline() | ||
OUs.readline() | ||
OUs.readline() | ||
ouArray = [] | ||
for each in range(0, 13): | ||
line = OUs.readline() | ||
line = re.sub(r'\W+', '', line) | ||
ouArray.append(line) | ||
web.header('Content-Type', 'application/json') | ||
return json.dumps({'ouArray': ouArray}) | ||
|
||
class getNames: | ||
def POST(self): | ||
YOG = web.input().Year | ||
fileName = YOG+"names.txt" | ||
filePath = os.path.normpath("C:\\folder\\"+fileName) | ||
w = open("get"+YOG+"Names.ps1", 'w') | ||
w.write("import-module activedirectory -Force\n") | ||
w.write("Get-ADUser -LDAPFilter '(name=*)' -SearchBase 'OU="+YOG+",OU=Students,DC=School,DC=edu' -SearchScope OneLevel | ft SamAccountName | Out-File "+filePath+"\n") | ||
w.close() | ||
cmd = subprocess.Popen(["C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe", "-ExecutionPolicy", "Unrestricted", ".\"./get"+YOG+"names.ps1\";"]) | ||
names = open(fileName, 'r') | ||
names.readline() | ||
names.readline() | ||
names.readline() | ||
nameArray = [] | ||
for each in names: | ||
each = re.sub(r'\W+', '', each) | ||
count = 0 | ||
index = 0 | ||
for char in each: | ||
if char.isupper() == 1: | ||
count += 1 | ||
if count == 2: | ||
accountName = each[:index]+'.'+each[index:] | ||
index += 1 | ||
if count < 2: | ||
continue | ||
nameArray.append(accountName) | ||
web.header('Content-Type', 'application/json') | ||
return json.dumps({'nameArray': nameArray}) | ||
|
||
class setPass: | ||
def POST(self): | ||
global status | ||
userName = web.input().userName | ||
value = web.input().password | ||
w = open("changePassword.ps1", 'w') | ||
w.write("import-module activedirectory -Force\n") | ||
w.write("$userpwd = ConvertTo-SecureString "+value+" -AsPlainText -Force\n") | ||
w.write("Set-ADAccountPassword "+userName+" -NewPassword $userpwd\n") | ||
w.close() | ||
cmd = subprocess.Popen(["C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe", "-ExecutionPolicy", "Unrestricted", ".\"./changePassword.ps1\";"]) | ||
print "Password for "+userName+" set to: "+value | ||
return | ||
|
||
|
||
if __name__=='__main__': | ||
web.internalerror = web.debugerror | ||
app.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<html> | ||
<center> | ||
<head> | ||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> | ||
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/themes/smoothness/jquery-ui.css" /> | ||
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script> | ||
<style> | ||
.ui-menu {width: 300px;} | ||
</style> | ||
<script> | ||
function setPass(){ | ||
jQuery.ajaxSetup({async:false}); | ||
var user = document.getElementById("userToChange").innerHTML; | ||
var pass = jQuery("#userPass").val(); | ||
jQuery.post("/setPass",{userName: user, password: pass}); | ||
} | ||
function onOpen(){ | ||
jQuery.ajaxSetup({async:false}); | ||
var YOGs = ""; | ||
var yogMenu = ""; | ||
jQuery.post("/getOUs", function(data) {YOGs=data.ouArray}); | ||
for (var i = 0; i < YOGs.length; i++){ | ||
yogMenu += "<li>"; | ||
yogMenu += YOGs[i]; | ||
var names = ""; | ||
var nameMenu = ""; | ||
jQuery.post("/getNames", {Year: YOGs[i]}, function(data) {names=data.nameArray}); | ||
if(names.length > 0){ | ||
nameMenu += "<ul>"; | ||
for (var j = 0; j < names.length; j++){ | ||
nameMenu += "<li>"+names[j]+"</li>"; | ||
} | ||
nameMenu += "</ul>"; | ||
yogMenu += nameMenu; | ||
} | ||
yogMenu += "</li>"; | ||
} | ||
var menuLoc = document.getElementById("menu"); | ||
menuLoc.innerHTML += yogMenu; | ||
jQuery("#menu").menu({ | ||
select: function(event, ui){ | ||
var nameLoc = document.getElementById("userToChange"); | ||
nameLoc.innerHTML = ui.item.text(); | ||
} | ||
}); | ||
} | ||
</script> | ||
</head> | ||
<title>Password Reset Utility</title> | ||
<body onload="onOpen()"> | ||
<ul id="menu"> | ||
</ul> | ||
</br> | ||
User to change password for: <div id="userToChange"></div> | ||
</br> | ||
<form action="" method="get"> | ||
Set Password to: <input type="text" id="userPass"> | ||
</br> | ||
<input type="submit" onclick="setPass(); location.href='/';" value='Set Password'> | ||
</form> | ||
</body> | ||
</center> | ||
</html> |