自己在公司 的虚拟机上用samba4搭了一个AD域控,用python (pyqt4, ldap)写个不入域直接修改域用户密码的客户端 ,window和linux中都能用 ,包括3个python文件.
练习之作,以后要加个设置功能,这样别人也能用。 windows 下用pyinstall 打包成单独exe文件有13M大!
1. 主程序maincontrol.py
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
from mainview import Ui_mainView
import sys
from change_passwd import ChangeADPasswd
class mainControl(QtGui.QMainWindow):
def __init__(self, host, base, bind_user, bind_pwd, parent=None):
self.host = host
self.base = base
self.bind_user = bind_user
self.bind_pwd = bind_pwd
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_mainView()
self.ui.setupUi(self)
QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL("clicked()"), self.changeAction)
def changeAction(self):
if self.ui.newPasswd1.text() != self.ui.newPasswd2.text() :
self.ui.messageArea.setText("New Passwords are not indentical!")
else:
# self.ui.messageArea.setText("New Passwords are indentical!")
username = self.ui.userName.text()
oldpasswd = self.ui.oldPasswd.text()
newpasswd = self.ui.newPasswd1.text()
changePasswd = ChangeADPasswd(self.host, self.base, self.bind_user, self.bind_pwd)
outputmessage = changePasswd.changepasswd(username, oldpasswd, newpasswd)
print(outputmessage)
self.ui.messageArea.setText(outputmessage)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
myapp = mainControl('192.168.1.100:636', 'CN=Users,dc=samba,dc=ddd,dc=com', '[email protected]', 'tessdfsfsfsfsf')
myapp.show()
sys.exit(app.exec_())
2. 用Qtdesigner设计后用pyuic4生成的mainview.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'mainview.ui'
#
# Created: Fri Jan 16 10:16:55 2015
# by: PyQt4 UI code generator 4.10.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_mainView(object):
def setupUi(self, mainView):
mainView.setObjectName(_fromUtf8("mainView"))
mainView.resize(306, 341)
self.centralwidget = QtGui.QWidget(mainView)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.pushButton = QtGui.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(183, 210, 81, 31))
self.pushButton.setObjectName(_fromUtf8("pushButton"))
self.messageArea = QtGui.QLabel(self.centralwidget)
self.messageArea.setGeometry(QtCore.QRect(40, 260, 231, 51))
self.messageArea.setFrameShape(QtGui.QFrame.Box)
self.messageArea.setFrameShadow(QtGui.QFrame.Sunken)
self.messageArea.setText(_fromUtf8(""))
self.messageArea.setObjectName(_fromUtf8("messageArea"))
self.widget = QtGui.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(40, 30, 231, 166))
self.widget.setObjectName(_fromUtf8("widget"))
self.gridLayout = QtGui.QGridLayout(self.widget)
self.gridLayout.setMargin(0)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.oldPasswd = QtGui.QLineEdit(self.widget)
self.oldPasswd.setObjectName(_fromUtf8("oldPasswd"))
self.gridLayout.addWidget(self.oldPasswd, 1, 1, 1, 1)
self.label_2 = QtGui.QLabel(self.widget)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
self.newPasswd2 = QtGui.QLineEdit(self.widget)
self.newPasswd2.setEchoMode(QtGui.QLineEdit.Password)
self.newPasswd2.setObjectName(_fromUtf8("newPasswd2"))
self.gridLayout.addWidget(self.newPasswd2, 3, 1, 1, 1)
self.label_3 = QtGui.QLabel(self.widget)
self.label_3.setObjectName(_fromUtf8("label_3"))
self.gridLayout.addWidget(self.label_3, 2, 0, 1, 1)
self.label = QtGui.QLabel(self.widget)
self.label.setObjectName(_fromUtf8("label"))
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.userName = QtGui.QLineEdit(self.widget)
self.userName.setObjectName(_fromUtf8("userName"))
self.gridLayout.addWidget(self.userName, 0, 1, 1, 1)
self.newPasswd1 = QtGui.QLineEdit(self.widget)
self.newPasswd1.setEchoMode(QtGui.QLineEdit.Password)
self.newPasswd1.setObjectName(_fromUtf8("newPasswd1"))
self.gridLayout.addWidget(self.newPasswd1, 2, 1, 1, 1)
mainView.setCentralWidget(self.centralwidget)
self.retranslateUi(mainView)
QtCore.QMetaObject.connectSlotsByName(mainView)
mainView.setTabOrder(self.userName, self.oldPasswd)
mainView.setTabOrder(self.oldPasswd, self.newPasswd1)
mainView.setTabOrder(self.newPasswd1, self.newPasswd2)
mainView.setTabOrder(self.newPasswd2, self.pushButton)
def retranslateUi(self, mainView):
mainView.setWindowTitle(_translate("mainView", "Change AD Password", None))
self.pushButton.setText(_translate("mainView", "Change", None))
self.label_2.setText(_translate("mainView", "Old Passwd:", None))
self.label_3.setText(_translate("mainView", "New Passwd:", None))
self.label.setText(_translate("mainView", "User Name:", None))
3. 用来同AD服务器通信的change_passwd.py
import ldap
import sys
class ChangeADPasswd:
def __init__(self, host, base, bind_user, bind_pwd):
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
self.conn = None
self.host = host
self.uri = 'ldaps://%s' % (host)
self.base = base
try:
self.conn = ldap.initialize(self.uri)
self.conn.set_option(ldap.OPT_REFERRALS, 0)
self.conn.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
self.conn.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)
self.conn.set_option(ldap.OPT_X_TLS_DEMAND, True)
self.conn.set_option(ldap.OPT_DEBUG_LEVEL, 255)
self.conn.simple_bind_s(bind_user, bind_pwd)
except ldap.LDAPError, e:
raise self.ldap_error(e)
def changepasswd(self, user, current_pwd, new_pwd):
current_pwd = unicode('\"' + current_pwd + '\"').encode('utf-16-le')
new_pwd = unicode('\"' + new_pwd + '\"').encode('utf-16-le')
#pass_mod = [(ldap.MOD_DELETE, 'unicodePwd', [current_pwd]), (ldap.MOD_ADD, 'unicodePwd', [new_pwd])]
pass_mod = [(ldap.MOD_DELETE, 'unicodePwd', current_pwd), (ldap.MOD_ADD, 'unicodePwd', new_pwd)]
user_filter = "(sAMAccountName=%s)" % (user)
user_scope = ldap.SCOPE_SUBTREE
status_attribs = ['sAMAccountName']
try:
results = self.conn.search_s(self.base, user_scope, user_filter, status_attribs)
except ldap.LDAPError, e:
return str(e)
# print(results)
if not len(results):
return "No such UserName"
result = results[0]
user_dn = result[0]
user_name = result[1]
#print(user_dn)
#print(user_name)
try:
self.conn.modify_s(user_dn, pass_mod)
except ldap.LDAPError, e:
# print e
messg = e[0]['info'][62:]
if len(messg) > 32 :
messg1 = messg[:31] + '\n' + messg[31:]
return messg1
else:
return messg
return "Succeed!"
class ldap_error(ldap.LDAPError):
def __init__(self, e):
self.msg = 'LDAP Error. desc: %s info: %s' % (e[0]['desc'], e[0]['info'])
def __str__(self):
return str(self.msg)
if __name__ == '__main__':
host = '192.168.1.100:636'
base = 'CN=Users,dc=samba,dc=ddd,dc=com'
bind_user = '[email protected]'
bind_pwd = 'test1@lslllslls'
chanpass = ChangeADPasswd(host, base, bind_user, bind_pwd)
chanpass.changepasswd('wiwerl.chen', '12345', 'srqarawl')