Proyecto

General

Perfil

« Anterior | Siguiente » 

Revisión 178

Añadido por jredrejo hace casi 14 años

pasada rama de web2py a rama principal

Ver diferencias:

controlies/trunk/debian/changelog
controlies (0.3-3) unstable; urgency=low
* Añade profesores al grupo teachers y alumnos al students
-- José L. Redrejo Rodríguez <jredrejo@debian.org> Tue, 31 May 2011 13:52:41 +0200
controlies (0.3-1) unstable; urgency=low
* Terminado de implementar en web2py todo lo que había con twisted
-- José L. Redrejo Rodríguez <jredrejo@debian.org> Tue, 17 May 2011 13:08:40 +0200
controlies (0.2-2) unstable; urgency=low
* Cambios en la configuración de apache: directorio en vez de vhost
-- José L. Redrejo Rodríguez <jredrejo@debian.org> Mon, 16 May 2011 14:23:55 +0200
controlies (0.2-1) unstable; urgency=low
* Completando funcionalidades
-- José L. Redrejo Rodríguez <jredrejo@debian.org> Fri, 13 May 2011 14:37:17 +0200
controlies (0.1-1) unstable; urgency=low
* First Debian package
-- José L. Redrejo Rodríguez <jredrejo@debian.org> Wed, 04 May 2011 19:20:55 +0200
controlies/trunk/debian/links
var/web2py/applications/controlies var/web2py/applications/init
controlies/trunk/debian/dirs
var/web2py
etc/apache2/conf.d
etc/ldap/ssl
controlies/trunk/debian/postinst
#!/bin/sh
# postinst script for controlies
#
# see: dh_installdeb(1)
set -e
case "$1" in
configure)
chown -R www-data:www-data /var/web2py
a2enmod ssl
a2enmod wsgi
a2ensite default-ssl
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0
controlies/trunk/debian/install
applications var/web2py
wsgihandler.py var/web2py
subwsgihandler.py var/web2py
VERSION var/web2py
controlies-apache etc/apache2/conf.d
applications/__init__.py var/web2py
controlies/trunk/debian/control
Source: controlies
Section: python
Priority: extra
Maintainer: José L. Redrejo Rodríguez <jredrejo@debian.org>
Build-Depends: debhelper (>= 7.0.50~)
Standards-Version: 3.8.4
Package: controlies
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, python-gluon, python-ldap, python-dev, libapache2-mod-wsgi, libapache2-mod-python, libapache2-mod-gnutls, openssl, ssl-cert
Description: Gestión de LDAP para un centro educativo
ControlIES gestiona cuentas de usuarios, grupos, aulas, departamentos,
distintos tipos de ordenadores, importación de Rayuela, etc.
controlies/trunk/debian/copyright
This work was packaged for Debian by:
José L. Redrejo Rodríguez <jredrejo@debian.org> on Tue, 29 Jun 2010 20:40:58 +0200
Upstream Author(s):
Manuel Mora Gordillo <manuito @no-spam@ gmail.com>
Francisco Mendez Palma <fmendezpalma @no-spam@ gmail.com>
Copyright:
Copyright (C) 2011 Manuel Mora Gordillo
Francisco Mendez Palma
License:
ControlIES is Licensed under the LGPL license version 3
see "/usr/share/common-licenses/LGPL-3".
The Debian packaging is:
Copyright (C) 2010 José L. Redrejo Rodríguez <jredrejo@debian.org>
and is licensed under the GPL version 3,
see "/usr/share/common-licenses/GPL-3".
controlies/trunk/debian/rules
#!/usr/bin/make -f
# -*- makefile -*-
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
%:
dh $@
controlies/trunk/debian/compat
7
controlies/trunk/applications/controlies/modules/Users.py
##############################################################################
# -*- coding: utf-8 -*-
# Project: ControlIES
# Module: Users.py
# Purpose: Users class
# Language: Python 2.5
# Date: 7-Feb-2011.
# Ver: 7-Feb-2011.
# Author: Manuel Mora Gordillo
# Copyright: 2011 - Manuel Mora Gordillo <manuito @no-spam@ gmail.com>
#
# ControlIES is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ControlIES is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ControlIES. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import ldap
import logging
import hashlib
import base64
from math import ceil
from operator import itemgetter
from Utils import Utils, LdapUtils
class Users(object):
def __init__(self):
pass
def __init__(self,ldap,type,name,surname,nif,user,password,password2,departments,classrooms):
self.ldap = ldap
self.type = type
self.name = name
self.surname = surname
self.nif = nif
self.user = user
self.password = password
self.password2 = password2
self.departments = departments
self.classrooms = classrooms
if self.departments.__class__.__name__ == 'str': self.departments=[departments]
if self.classrooms.__class__.__name__ == 'str': self.classrooms=[classrooms]
def validation(self,action):
if action == "add":
if self.type == "none":
return "type"
if self.name == "":
return "name"
if self.surname == "":
return "surname"
if self.nif == "":
return "nif"
if self.user == "":
return "user"
if action == "add":
if self.existsUsername():
return "userAlreadyExists"
if self.password == "":
return "password"
if self.password2 == "":
return "password2"
if self.password != self.password2:
return "distinctPassword"
elif action == "modify":
if self.password == "" and self.password2 != "":
return "password"
if self.password != "" and self.password2 == "":
return "password2"
if self.password != "" and self.password2 != "" and self.password != self.password2:
return "distinctPassword"
return "OK"
def process(self,action):
if action == "add":
val = self.validation(action)
if val != "OK":
return val
else:
response = self.add()
return response
if action == "modify":
val = self.validation(action)
if val != "OK":
return val
else:
response = self.modify()
return response
def list(self,args):
filter = self.buildFilter(args)
search = self.ldap.search("ou=People",filter,["employeeNumber","uid","cn","uidnumber","gidnumber","homedirectory"])
# grid parameters
limit = int(args['rows'])
page = int(args['page'])
start = limit * page - limit
finish = start + limit;
# sort by field
sortBy = args['sidx']
if sortBy == "uid":
sortBy = "id"
# reverse Sort
reverseSort = False
if args['sord'] == "asc":
reverseSort = True
# type of user (Teacher/Student)
try:
searchType = args['type']
except LookupError:
searchType = "none"
rows = []
for i in search:
typeRow="Alumno"
userdata=i[0][1]
if userdata["homeDirectory"][0][0:14]=="/home/profesor":
typeRow="Profesor"
if not "employeeNumber" in userdata: userdata["employeeNumber"]=["0"]
if searchType == typeRow or searchType=="none":
row = {
"id":userdata["uid"][0],
"cell":[typeRow, userdata["cn"][0], userdata["uid"][0], userdata["uidNumber"][0], userdata["gidNumber"][0], userdata["employeeNumber"][0]],
"type": typeRow,
"cn":userdata["cn"][0],
"uidNumber":userdata["uidNumber"][0],
"gidNumber":userdata["gidNumber"][0],
"employeeNumber":userdata["employeeNumber"][0]
}
rows.append(row)
# grid parameters
if len(rows) > 0:
totalPages = ceil( len(rows) / int(limit) )
else:
totalPages = 0
if page > totalPages:
page = totalPages
# sort rows
result = sorted(rows, key=itemgetter(sortBy), reverse=reverseSort)
return { "page":page, "total":totalPages, "records":len(rows), "rows":result[start:finish] }
def buildFilter(self, args):
filter = "(&(uid=*)"
try:
filter = filter + "(uid=*" + args['uid'] + "*)"
except LookupError:
pass
try:
filter = filter + "(cn=*" + args['cn'] + "*)"
except LookupError:
pass
try:
filter = filter + "(uidNumber=" + args['uidNumber'] + ")"
except LookupError:
pass
try:
filter = filter + "(gidNumber=" + args['gidNumber'] + ")"
except LookupError:
pass
try:
filter = filter + "(employeeNumber=*" + args['employeeNumber'] + "*)"
except LookupError:
pass
filter = filter + ")"
return filter
def add(self):
maxID = str(LdapUtils.getMaxID(self.ldap))
passwd = '{SSHA}' + Utils.encrypt(self.password)
attr = [
('objectclass', ['top','posixAccount','shadowAccount','person','inetOrgPerson']),
('uid', [self.user]),
('cn', [self.name] ),
('employeenumber', [self.nif] ),
('sn', [self.surname] ),
('uidnumber', [maxID] ),
('gidnumber', [maxID] ),
('loginshell', ['/bin/bash'] ),
('homeDirectory', [LdapUtils.whatHome(self.type) + self.user] ),
#('jpegPhoto', ['jpegPhoto'] ),
('userpassword', [passwd])
]
self.ldap.add("uid="+self.user+",ou=People", attr)
# Add private group
attr = [
('objectclass', ['top','posixGroup','lisGroup']),
('grouptype', ['private']),
('gidnumber', [maxID] ),
('cn', [self.user] ),
('description', [self.name+' personal group'] )
]
self.ldap.add("cn="+self.user+",ou=Group", attr)
# Add selected groups
attr = [
(ldap.MOD_ADD, 'member', ['uid='+self.user+',ou=People,dc=instituto,dc=extremadura,dc=es'] ),
(ldap.MOD_ADD, 'memberUid', [self.user] )
]
for n in self.departments:
self.ldap.modify('cn='+ n +',ou=Group', attr)
for n in self.classrooms:
self.ldap.modify('cn='+ n +',ou=Group', attr)
if self.type=='teacher':
self.ldap.modify('cn=teachers,ou=Group', attr)
elif self.type=='student':
self.ldap.modify('cn=students,ou=Group', attr)
return "OK"
def modify(self):
attr = [
(ldap.MOD_REPLACE, 'cn', [self.name] ),
(ldap.MOD_REPLACE, 'employeenumber', [self.nif] ),
(ldap.MOD_REPLACE, 'sn', [self.surname] )
]
if self.password!="":
passwd = '{SSHA}' + Utils.encrypt(self.password)
attr.append((ldap.MOD_REPLACE, 'userpassword', [passwd]))
self.ldap.modify("uid="+self.user+",ou=People", attr)
# Get current groups
currentGroups = self.getUserGroups()
groupsDepartments = Utils.cmpLists(currentGroups["departments"], self.departments)
groupsClassrooms = Utils.cmpLists(currentGroups["classrooms"], self.classrooms)
# Delete unselected groups
deleteDepartments = groupsDepartments["onlyInList1"]
deleteClassrooms = groupsClassrooms["onlyInList1"]
attr = [
(ldap.MOD_DELETE, 'member', ['uid='+self.user+',ou=People,dc=instituto,dc=extremadura,dc=es'] ),
(ldap.MOD_DELETE, 'memberUid', [self.user] )
]
for d in deleteDepartments:
self.ldap.modify('cn='+ d +',ou=Group', attr)
for d in deleteClassrooms:
self.ldap.modify('cn='+ d +',ou=Group', attr)
# Add selected groups
newDepartments = groupsDepartments["onlyInList2"]
newClassrooms = groupsClassrooms["onlyInList2"]
attr = [
(ldap.MOD_ADD, 'member', ['uid='+self.user+',ou=People,dc=instituto,dc=extremadura,dc=es'] ),
(ldap.MOD_ADD, 'memberUid', [self.user] )
]
for n in newDepartments:
self.ldap.modify('cn='+ n +',ou=Group', attr)
for n in newClassrooms:
self.ldap.modify('cn='+ n +',ou=Group', attr)
return "OK"
def delete(self):
self.ldap.delete('uid='+ self.user +',ou=People')
self.ldap.delete("cn="+self.user+",ou=Group")
# Delete unselected groups
currentGroups = self.getUserGroups()
attr = [
(ldap.MOD_DELETE, 'member', ['uid='+self.user+',ou=People,dc=instituto,dc=extremadura,dc=es'] ),
(ldap.MOD_DELETE, 'memberUid', [self.user] )
]
for d in currentGroups["departments"]:
self.ldap.modify('cn='+ d +',ou=Group', attr)
for d in currentGroups["classrooms"]:
self.ldap.modify('cn='+ d +',ou=Group', attr)
return "OK"
def existsUsername(self):
result = self.ldap.search("ou=People","uid="+self.user,["uid"])
if len(result) > 0:
return True
return False
def searchNewUsername(self):
result = self.ldap.search("ou=People","uid=*",["uid"])
users = []
for i in result:
users.append(i[0][1]['uid'][0])
n = self.name.lower().split(" ")
username = ""
if len(n) > 0:
username = n[0][0:1]
if len(n) > 1:
username = username + n[1]
if len(n) > 2:
username = username + n[2][0:1]
num = 1
searching = username + "0" + str(num)
found = True
while found:
try:
users.index(searching)
num = num + 1
if len(str(num)) == 1:
searching = username + "0" + str(num)
else:
searching = username + str(num)
except:
found = False
return searching
def getUserGroups(self):
result = self.ldap.search("ou=Group","(&(memberUid="+self.user+")(|(groupType=school_department)(groupType=school_class)))",["cn","groupType"])
departments = []
classrooms = []
for g in result:
if g[0][1]["groupType"][0] == "school_department":
departments.append(g[0][1]["cn"][0])
elif g[0][1]["groupType"][0] == "school_class":
classrooms.append(g[0][1]["cn"][0])
departments.sort()
classrooms.sort()
return { "departments":departments, "classrooms":classrooms }
def getUserData(self):
self.getUserGroups()
result = self.ldap.search("ou=People","uid="+self.user,["uid","cn","sn","employeenumber","homedirectory","jpegPhoto"])
if len(result) == 0:
return { "user":"", "name":"", "surname":"", "nif":"", "photo":"", "type":"", "groups":[] }
type = "student"
if result[0][0][1]["homeDirectory"][0][0:14]=="/home/profesor":
type = "teacher"
try:
photo = base64.b64encode(result[0][0][1]["jpegPhoto"][0])
except:
photo = ""
userdata=result[0][0][1]
if "employeeNumber" not in userdata: userdata["employeeNumber"]=["0"]
dataUser = {
"user":userdata["uid"][0],
"name":userdata["cn"][0],
"surname":userdata["sn"][0],
"nif":userdata["employeeNumber"][0],
"photo":photo,
"type":type,
"groups":self.getUserGroups()
}
return dataUser
def getUserPhoto(self):
self.getUserGroups()
result = self.ldap.search("ou=People","uid="+self.user,["jpegPhoto"])
try:
photo = base64.b64encode(result[0][0][1]["jpegPhoto"][0])
except:
photo = ""
dataUser = {
"photo":photo
}
return dataUser
controlies/trunk/applications/controlies/modules/Hosts.py
##############################################################################
# -*- coding: utf-8 -*-
# Project: ControlIES
# Module: Hosts.py
# Purpose: Hosts class
# Language: Python 2.5
# Date: 7-Feb-2011.
# Ver: 7-Feb-2011.
# Author: Manuel Mora Gordillo
# Francisco Mendez Palma
# Copyright: 2011 - Manuel Mora Gordillo <manuito @no-spam@ gmail.com>
# 2011 - Francisco Mendez Palma <fmendezpalma @no-spam@ gmail.com>
#
# ControlIES is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ControlIES is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ControlIES. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import ldap
import logging
import time
from math import ceil
from operator import itemgetter
class Hosts(object):
def __init__(self):
pass
def __init__(self,ldap,name,ip,mac,group,type):
self.ldap = ldap
self.name = name
self.ip = ip
self.mac = mac
self.group = group
self.type = type
def getName (self):
return self.mac
def validation(self,action):
if action == "add":
if self.type == "none":
return "type"
if self.name == "":
return "name"
if self.type <> 'thinclient':
if self.ip == "":
return "ip"
if self.mac == "":
return "mac"
if self.type =="thinclient":
if self.group == "":
return "group"
if self.type == "":
return "type"
if action == "add":
if self.existsHostname():
return "hostAlreadyExists"
# thinclients no requieren ip, la cogen dinamicamente en el aula
if self.type <> "thinclient":
if self.existsIP():
return "ipAlreadyExists"
#controlar overflow en nodos
if self.groupOverflow(300):
return "groupOverflow"
if self.existsMAC():
return "macAlreadyExists"
elif action == "modify":
if self.groupOverflow(300):
return "groupOverflow"
if self.existsMAC():
return "macAlreadyExists"
return "OK"
def process(self,action):
if action == "add":
val = self.validation(action)
if val != "OK":
return val
else:
response = self.add()
return response
if action == "modify":
val = self.validation(action)
if val != "OK":
return val
else:
response = self.modify()
return response
if action == "delete":
response = self.delete()
return response
if action == "list":
response = self.list();
return response
def list(self,args):
#from Plugins.LdapConnection import LdapConnection
#l = LdapConnection("172.23.36.5",'cn=admin,ou=People,dc=instituto,dc=extremadura,dc=es',"Sta1987teleco")
#l.connect()
# grid parameters
limit = int(args['rows'])
page = int(args['page'])
start = limit * page - limit
finish = start + limit;
# sort by field
sortBy = args['sidx']
#if sortBy == "uid":
#sortBy = "id"
# reverse Sort
reverseSort = False
if args['sord'] == "asc":
reverseSort = True
#Distinguimos entre hosts ltsp, workstations y portatiles
type = args['type']
if type == "ltsp":
# Obtengo todos los elementos del nodo hosts
#search = l.search("ou=hosts","cn=*",["cn","ipHostNumber","macAddress"])
#filter = self.buildFilter(args)
search = self.ldap.search("ou=hosts","cn=*",["cn","ipHostNumber","macAddress"])
# triplets que contiene los nombres de los ltsp-servers
hostnames = self.getLTSPServers()
# Ahora tengo que quedarme con los elementos de search que estan en hostnames: los que son ltsp
resultado=list()
for element in search:
if element[0][1]["cn"][0] in hostnames:
resultado.append(element)
search = resultado
rows = []
for i in search:
row = {
"id":i[0][1]["cn"][0],
"cell":[i[0][1]["cn"][0], i[0][1]["ipHostNumber"][0],i[0][1]["macAddress"]],
"cn":i[0][1]["cn"][0],
"ipHostNumber":i[0][1]["ipHostNumber"][0],
"macAddress":i[0][1]["macAddress"][0]
}
#row = { "cn":i[0][0], "cell":[i[0][1]["cn"][0], i[0][1]["ipHostNumber"][0],i[0][1]["macAddress"]]}
rows.append(row)
if len(rows) > 0:
totalPages = ceil( len(rows) / int(limit) )
else:
totalPages = 0
if page > totalPages:
page = totalPages
result = sorted(rows, key=itemgetter(sortBy), reverse=reverseSort)
return { "page":page, "total":totalPages, "records":len(rows), "rows":result[start:finish] }
elif type == "thinclient":
search = self.ldap.search("cn=THINCLIENTS,cn=DHCP Config","cn=*",["cn","dhcpHWAddress"])
filter="(|(dhcpOption=*subnet*)(dhcpOption=*log*))"
rows = []
# esto hay que cambiarlo: tenemos 4 groups en thinclientes
for i in search[6:len(search)]:
nodeinfo=i[0][0].replace ("cn=","").split(",")
row = {
"id":i[0][1]["cn"][0],
"cell":[i[0][1]["cn"][0], i[0][1]["dhcpHWAddress"][0].replace("ethernet ",""), nodeinfo[1]],
"cn":i[0][1]["cn"][0],
"dhcpHWAddress":i[0][1]["dhcpHWAddress"][0],
"groupName":i[0][1]["dhcpHWAddress"][0]
}
rows.append(row)
if len(rows) > 0:
totalPages = ceil( len(rows) / int(limit) )
else:
totalPages = 0
if page > totalPages:
page = totalPages
result = sorted(rows, key=itemgetter(sortBy), reverse=reverseSort)
return { "page":page, "total":totalPages, "records":len(rows), "rows":result[start:finish] }
elif type == "workstation":
# Obtengo todos los elementos del nodo hosts
#search = l.search("ou=hosts","cn=*",["cn","ipHostNumber","macAddress"])
search = self.ldap.search("ou=hosts","cn=*",["cn","ipHostNumber","macAddress"])
# triplets que contiene los nombres de las workstations
#triplets = l.search("ou=Netgroup","cn=workstation-hosts",["nisNetgroupTriple"])
triplets = self.ldap.search("ou=Netgroup","cn=workstation-hosts",["nisNetgroupTriple"])
triplets = triplets [0][0][1]["nisNetgroupTriple"]
hostnames=list()
# obtengo lista de nombres de los hosts workstation
for node in triplets:
name = node.replace(",-,-)","").replace("(","")
hostnames.append(name)
# Ahora tengo que quedarme con los elementos de search que estan en hostnames
resultado=list()
for element in search:
if element[0][1]["cn"][0] in hostnames:
resultado.append(element)
search = resultado
rows = []
for i in search:
row = {
"id":i[0][1]["cn"][0],
"cell":[i[0][1]["cn"][0], i[0][1]["ipHostNumber"][0],i[0][1]["macAddress"]],
"cn":i[0][1]["cn"][0],
"ipHostNumber":i[0][1]["ipHostNumber"][0],
"macAddress":i[0][1]["macAddress"][0]
}
#row = { "cn":i[0][0], "cell":[i[0][1]["cn"][0], i[0][1]["ipHostNumber"][0],i[0][1]["macAddress"]]}
rows.append(row)
if len(rows) > 0:
totalPages = ceil( len(rows) / int(limit) )
else:
totalPages = 0
if page > totalPages:
page = totalPages
result = sorted(rows, key=itemgetter(sortBy), reverse=reverseSort)
return { "page":page, "total":totalPages, "records":len(rows), "rows":result[start:finish] }
def add(self):
if self.type=="thinclient":
attr = [
('objectclass', ['top','dhcpHost']),
('cn', [self.name] ),
('dhcpStatements', ['filename "/var/lib/tftpboot/ltsp/i386/pxelinux.0"'] ),
('dhcpHWAddress', ['ethernet ' + self.mac] )
]
self.ldap.add("cn="+self.name +",cn="+self.group+",cn=THINCLIENTS,cn=DHCP Config", attr)
return "OK"
def modify(self):
attr = [
(ldap.MOD_REPLACE, 'cn', [self.name] ),
(ldap.MOD_REPLACE, 'dhcpHWAddress', ["ethernet "+ self.mac])
]
self.ldap.modify("cn="+self.name+",cn="+self.group +",cn=THINCLIENTS,cn=DHCP Config", attr)
return "OK"
def delete(self):
if self.type=="thinclient":
self.ldap.delete('cn='+ self.name +',cn=' +self.group +',cn=THINCLIENTS,cn=DHCP Config')
return "OK"
def wakeup(self):
from Plugins import NetworkUtils
NetworkUtils.startup(self.mac)
def groupOverflow(self,overflow):
if self.type == 'thinclient':
search = self.ldap.search("cn=" + self.group +",cn=THINCLIENTS,cn=DHCP Config","cn=*",["cn"])
if len(search)-2 >= overflow:
return True
return False
def existsHostname(self):
if self.type == 'thinclient':
result = self.ldap.search("cn=THINCLIENTS,cn=DHCP Config","cn="+self.name,["cn"])
else:
result = self.ldap.search("ou=hosts","cn="+self.name,["cn"])
if len(result) > 0:
return True
return False
def existsMAC(self):
# Compruebo con las macs de la rama hosts
if self.type == 'thinclient':
result = self.ldap.search("cn=THINCLIENTS,cn=DHCP Config","dhcpHWAddress=*",["dhcpHWAddress"])
for i in range (0, len(result) - 1):
if result [i][0][1]['dhcpHWAddress'][0].replace ("ethernet ", "") == self.mac:
return True
else:
result = self.ldap.search("ou=hosts","macAddress="+self.mac,["macAddress"])
if len(result) > 0:
return True
return False
def existsIP (self):
# Cojo las ips de la rama hosts -> arpa -> in-addr
result = self.ldap.search ("dc=23,dc=172,dc=in-addr,dc=arpa,ou=hosts", "dc=*",["associatedDomain"])
myIP = self.ip.split (".")
for i in range (0, len (result) -1):
reverseIP = result [i][0][1]['associatedDomain'][0].replace (".in-addr.arpa","").split(".")
reverseIP.reverse()
if myIP == reverseIP:
return True
return False
def getThinclientGroups (self):
groups = []
search = self.ldap.search("cn=THINCLIENTS,cn=DHCP Config","cn=group*",["cn"])
for g in search:
groups.append (g[0][1]["cn"][0])
return { "groups":groups }
def getInternalGroups (self):
groups = []
search = self.ldap.search("cn=INTERNAL,cn=DHCP Config","cn=group*",["cn"])
for g in search:
groups.append (g[0][1]["cn"][0])
return { "groups":groups }
def getHostData(self):
result1 = self.ldap.search("cn=DHCP Config","cn="+self.name,["cn","dhcpHWAddress"])
result2 = self.ldap.search(" ou=hosts","dc="+self.name,["aRecord"])
dataHost = {
"cn":self.name,
"group":self.group,
"mac":"",
"ip":""
}
if len(result1)==1:
dataHost["mac"]=result1[0][0][1]["dhcpHWAddress"][0].replace("ethernet ","")
if len(result2)==1:
dataHost["ip"]=result2[0][0][1]["aRecord"][0]
return dataHost
def getLTSPServers (self):
triplets = self.ldap.search("ou=Netgroup","cn=ltsp-server-hosts",["nisNetgroupTriple"])
triplets = triplets [0][0][1]["nisNetgroupTriple"]
hostnames=list()
for node in triplets:
name = node.replace(",-,-)","").replace("(","")
hostnames.append(name)
hostnames.sort()
return hostnames
def getLTSPStatus (self):
from Utils.avahiClient import avahiClient
import threading
a = avahiClient()
a.start()
time.sleep(1000)
a.cancel()
names = a.getList()
print names
"""a = avahiClient()
time.sleep(1000)
names = a.getList()
print names
a.kill()"""
return names
# def wakeup(self):
# from twisted.internet.task import LoopingCall
# from twisted.internet import defer
# from Plugins import NetworkUtils
# NetworkUtils.startup(self.mac)
# Encender el equipo
#def wakeup(self):
# macs=[]
# for i in self.targets:
# mac=Configs.MonitorConfigs.GetMAC(i)
# if mac !='':
# macs.append(mac)
# Actions.sendWOLBurst(macs, 2)
#Apagar el equipo
# def sleep(self):
# self.usersCommand(Desktop.sleep)
#def sendWOLBurst(macs,throttle):
# from twisted.internet.task import LoopingCall
# from twisted.internet import defer
# if not macs:
# return defer.succeed(None)
# d = defer.Deferred()
# work = list(macs)
# def sendNext():
# if not work:
# loop.stop()
# d.callback(None)
# return defer.succeed(None)
# next = work.pop(0)
#
# #subprocess.Popen(['wakeonlan',next ])
# #subprocess.Popen(['wakeonlan','-i','192.168.0.255',next ])
# NetworkUtils.startup(next)
#
# return None
# loop = LoopingCall(sendNext)
# loop.start(throttle)
# return d
controlies/trunk/applications/controlies/modules/Security.py
##############################################################################
# -*- coding: utf-8 -*-
# Project: ControlIES
# Module: Security.py
# Purpose: Authentication with ldap server
# Language: Python 2.5
# Date: 7-Feb-2011.
# Ver: 7-Feb-2011.
# Author: Manuel Mora Gordillo
# Copyright: 2011 - Manuel Mora Gordillo <manuito @no-spam@ gmail.com>
#
# ControlIES is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ControlIES is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ControlAula. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from Plugins.LdapConnection import LdapConnection
class Security(object):
def __init__(self,host,user,password):
self.host = host
self.user = user
self.password = password
def validation(self):
if self.host == "":
return "host"
if self.user == "":
return "user"
if self.password == "":
return "password"
return "OK"
def process(self):
val = self.validation()
if val != "OK":
return val
auth = self.authentication()
return auth
def authentication(self):
l = LdapConnection(self.host,'cn='+self.user+',ou=People,dc=instituto,dc=extremadura,dc=es',self.password)
ret = l.connect()
return ret
controlies/trunk/applications/controlies/modules/Utils/avahiClient.py
##############################################################################
# -*- coding: utf-8 -*-
# Project: ControlIES
# Module: avahiClient.py
# Purpose: Avahi client to detect ltsp servers
# Language: Python 2.5
# Date: 27-Feb-2011.
# Ver: 27-Feb-2011.
# Author: José Luis Redrejo Rodriguez
# Copyright: 2011 - José Luis Redrejo Rodriguez <jredrejo @no-spam@ debian.org>
# Modified by: Manuel Mora Gordillo <manuito @no-spam@ gmail.com>
#
# ControlIES is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ControlIES is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ControlIES. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
try:
import dbus
if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
import dbus.glib
except ImportError:
dbus = None
if dbus:
try:
import avahi
except ImportError:
avahi = None
else:
avahi = None
from twisted.internet import defer, threads
from twisted.internet import glib2reactor
import logging
glib2reactor.install()
class avahiClient():
def __init__(self, type):
self._callbacks = {'new-service': [], 'remove-service': [] }
# initialize dbus stuff needed for discovery
self.bus = dbus.SystemBus()
avahi_bus = self.bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER)
self.server = dbus.Interface(avahi_bus, avahi.DBUS_INTERFACE_SERVER)
#stype = '_workstation._tcp'
#stype = '_controlaula._tcp'
stype = type
domain = 'local'
self._plugged = {}
avahi_browser = self.server.ServiceBrowserNew(avahi.IF_UNSPEC, avahi.PROTO_UNSPEC, stype, domain, dbus.UInt32(0))
obj = self.bus.get_object(avahi.DBUS_NAME, avahi_browser)
self.browser = dbus.Interface(obj, avahi.DBUS_INTERFACE_SERVICE_BROWSER)
def start(self):
self.browser.connect_to_signal('ItemNew', self.new_service)
self.browser.connect_to_signal('ItemRemove', self.remove_service)
def stop(self):
self.bus.close()
def new_service(self, interface, protocol, name, type, domain, flags):
def resolve_service_reply(*service):
address, port = service[-4:-2]
name = unicode(service[2])
for cb in self._callbacks['new-service']:
self._plugged[name] = (address,port)
cb(self,name, address, port)
def resolve_service_error(exception):
logging.getLogger().debug('could not resolve daap service %s %s: %s' % (name, domain, exception))
#self.warning('could not resolve daap service %s %s: %s' % (name, domain, exception))
self.server.ResolveService(interface, protocol, name, type, domain,
avahi.PROTO_UNSPEC, dbus.UInt32(0),
reply_handler=resolve_service_reply,
error_handler=resolve_service_error)
def remove_service(self, interface, protocol, name, type, domain,server):
address, port = self._plugged[name]
for cb in self._callbacks['remove-service']:
cb(self,name, address, port)
def add_callback(self, sig_name, callback):
self._callbacks[sig_name].append(callback)
def remove_callback(self, sig_name, callback):
self._callback[sig_name].remove(callback)
controlies/trunk/applications/controlies/modules/Utils/Configs.py
LOG_FILENAME= '/tmp/controlies.log'
controlies/trunk/applications/controlies/modules/Utils/Utils.py
##############################################################################
# -*- coding: utf-8 -*-
# Project: ControlIES
# Module: Groups.py
# Purpose: Groups class
# Language: Python 2.5
# Date: 18-Feb-2011.
# Ver: 18-Feb-2011.
# Author: Manuel Mora Gordillo
# Francisco Mendez Palma
# Copyright: 2011 - Manuel Mora Gordillo <manuito @no-spam@ gmail.com>
# 2011 - Francisco Mendez Palma <fmendezpalma @no-spam@ gmail.com>
#
# ControlIES is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ControlIES is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ControlIES. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
def cmpLists(list1, list2):
onlyInList1 = set(list1).difference(set(list2))
onlyInList2 = set(list2).difference(set(list1))
inTwoLists = set(list1) & set(list2)
return { 'onlyInList1':onlyInList1, 'onlyInList2':onlyInList2, 'inTwoLists':inTwoLists }
def parseToLdap(string):
string = string.replace(" ","_")
string = string.replace("á","a").replace("é","e").replace("í","o").replace("ó","o").replace("ú","u")
string = string.replace("Á","A").replace("É","E").replace("Í","I").replace("Ó","O").replace("Ú","U")
string = string.replace("ñ","n").replace("Ñ","N")
return string
def generate_salt():
# Salt can be any length, but not more than about 37 characters
# because of limitations of the binascii module.
# 7 is what Netscape's example used and should be enough.
# All 256 characters are available.
from random import randrange
salt = ''
for n in range(7):
salt += chr(randrange(256))
return salt
def encrypt(password):
import sha
from binascii import b2a_base64
password = str(password)
salt = generate_salt()
return b2a_base64(sha.new(password + salt).digest() + salt)[:-1]
controlies/trunk/applications/controlies/modules/Utils/LdapUtils.py
##############################################################################
# -*- coding: utf-8 -*-
# Project: ControlIES
# Module: LdapUtils.py
# Purpose: Ldap utils
# Language: Python 2.5
# Date: 18-Feb-2011.
# Ver: 18-Feb-2011.
# Author: Manuel Mora Gordillo
# Francisco Mendez Palma
# Copyright: 2011 - Manuel Mora Gordillo <manuito @no-spam@ gmail.com>
# 2011 - Francisco Mendez Palma <fmendezpalma @no-spam@ gmail.com>
#
# ControlIES is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ControlIES is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ControlIES. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
# Get all users
def getAllUsers(ldap):
result = ldap.search("ou=People","uid=*",["uid","cn"])
rows = []
for u in result:
rows.append([u[0][1]['uid'][0] , u[0][1]['cn'][0] ]);
return rows
# Get all groups classified by type
def getAllGroups(ldap):
result = ldap.search("ou=Group","(|(groupType=school_department)(groupType=school_class))",["cn","groupType"])
departments = []
classrooms = []
for g in result:
if g[0][1]["groupType"][0] == "school_department":
departments.append(g[0][1]["cn"][0])
elif g[0][1]["groupType"][0] == "school_class":
classrooms.append(g[0][1]["cn"][0])
departments.sort()
classrooms.sort()
return { "departments":departments, "classrooms":classrooms }
# Get the max ID of the groups and users
def getMaxID(ldap):
result = ldap.search("ou=Group","cn=*",["gidNumber"])
numbers = []
for i in result:
numbers.append(int(i[0][1]['gidNumber'][0]))
result = ldap.search("ou=People","uid=*",["gidNumber","uidNumber"])
for i in result:
numbers.append(int(i[0][1]['gidNumber'][0]))
numbers.append(int(i[0][1]['uidNumber'][0]))
numbers.sort()
maxID = 1
if len(numbers) > 0:
maxID = numbers[len(numbers)-1] + 1
return maxID
def whatHome(type):
if type == "teacher":
return "/home/profesor/"
else:
return "/home/alumnos/"
controlies/trunk/applications/controlies/modules/NetworkUtils.py
##############################################################################
# -*- coding: utf-8 -*-
# Project: Controlaula
# Module: NetworkUtils.py
# Purpose: Several network utilities to be used in Python
# Language: Python 2.5
# Date: 17-Jan-2010.
# Ver: 17-Jan-2010.
# Author: José L. Redrejo Rodríguez
# Copyright: 2009 - José L. Redrejo Rodríguez <jredrejo @nospam@ debian.org>
#
# ControlAula is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ControlAula is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ControlAula. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import array,fcntl,socket,struct,os,re
import logging,subprocess
gateway='0'
ltspGateway='0'
essid=''
bssid=''
IFNAMSIZE = 16
IW_ESSID_MAX_SIZE = 16
SIOCGIWESSID = 0x8B1B
SIOCGIWAP = 0x8B15
def get_ip_address(ifname):
"""Returns the ip address of the interface ifname"""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
ip= socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15]) )[20:24]
)
except:
ip=''
return ip
def get_ip_inet_address(connection_ip='198.41.0.4'):
"""Returns the ip address of the interface used to connect to the given ip
198.41.0.4 is a DNS ROOT Server, so it's the default value to connect to Internet
"""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect((connection_ip, 0))
inet_address= s.getsockname()[0]
except:
inet_address=''
s.close()
logging.getLogger().debug("Inet Address:" + inet_address)
return inet_address
def get_inet_HwAddr(connection_ip='192.168.0.254'):
"""Returns the mac address of the interface used to connect to the given ip"""
interfaces=all_interfaces()
rightIP=get_ip_inet_address(connection_ip)
mac=''
ifname=''
for i in interfaces:
if rightIP== get_ip_address(i[0]):
... Diferencia truncada por exceder el máximo tamaño visualizable.

Exportar a: Unified diff