def list_groups(self,grouptype,groupname=None):
		
		if groupname==None:
			groupname = '*'
		grouptype_ids = groupdef.list_grouptypes_by_id()
		grouptype_objectclasses = {}
		for id in grouptype_ids:
			grouptype_objectclasses[id] = ldapdef.objectclass_by_grouptype(id)
			
		path = conf.get('LDAPSERVER','basedn')
		if grouptype:
			path = ldapdef.basedn_by_grouptype(grouptype)
			if not path:
				return {}
			
		
		res = self.l.search(path,ldap.SCOPE_SUBTREE,'(& (cn=%s) (objectclass=posixgroup))' % groupname ,\
			['cn','displayedName','description','gidNumber','objectClass','dn'])

		group_dict = {}
		while 1:
			sres = self.l.result(res,0)
			if sres[1]==[]:
				break
			if not sres[1][0][1].has_key('cn'):
				continue
			
			cn = sres[1][0][1]['cn'][0]
			group_dict[cn] = {}
			for (k,v) in sres[1][0][1].items():
				if k=='objectClass':
					for grouptype_id,objectclasses in grouptype_objectclasses.items():
						had_all_classes = True
						for objcls in objectclasses:
							if not v.count(objcls):
								had_all_classes = False
								break
						if had_all_classes == True:
							group_dict[cn]['grouptype_id'] = grouptype_id
							break
					continue
				if len(v)==1:
					group_dict[cn][k] = v[0]
				else:
					group_dict[cn][k] = v
				group_dict[cn]['dn'] = sres[1][0][0]
		return group_dict
	def creategroup(self,groupname,displayed_name,grouptype,description=None,force_gid=None):
		"""
		Add a user to the schools authentication directory service.
		The grouptype must be one of the constants PRIMARY, SYSTEM or SERVICE
		"""
		if description=='':
			description=None
		# check if the group exists already
		if self.group_exists(groupname):
			return -1
	
		path = "cn=%s,%s" % (groupname,ldapdef.basedn_by_grouptype(grouptype))
		if not path:
			return -4	# invalid grouptype
		
		if not displayed_name or len(displayed_name.strip())==0:
			return -5
		
		if force_gid:
			gid = force_gid
		else:
			gid = self.max(conf.get('LDAPSERVER','basedn'),
				'objectclass=posixgroup','gidNumber',
				int(conf.get('DOMAIN','gid_start')))+1
		group_info = {'cn': groupname,
			'gidNumber':str(gid),
			'displayedName': str(displayed_name),
			'objectclass':ldapdef.objectclass_by_grouptype(grouptype)}
		
		if description:
			group_info['description'] = description
		
		self.bind(conf.get('LDAPSERVER','admin'),conf.get('LDAPSERVER','passwd'))
		self.touch_by_dict({path:group_info})
		
		try:
			gid = grp.getgrnam(groupname)[2]
		except Exception, e:
			print e
			return -2