def list_users(self,usertype,uid=None):
		if uid==None:
			uid = '*'
		usertype_ids = userdef.list_usertypes_by_id()
		usertype_objectclasses = {}
		for id in usertype_ids:
			usertype_objectclasses[id] = ldapdef.objectclass_by_usertype(id) + ['sambaSamAccount']
			
		path = conf.get('LDAPSERVER','basedn')
		if usertype:
			path = ldapdef.basedn_by_usertype(usertype)
			if not path:
				return {}
				
		res = self.l.search(path,ldap.SCOPE_SUBTREE,'(& (uid=%s)(objectclass=posixaccount)(objectclass=person))' % uid ,[])
			
		user_dict = {}
		while 1:
			sres = self.l.result(res,0)
			if sres[1]==[]:
				break
			if not sres[1][0][1].has_key('uid'):
				continue
			
			uid = sres[1][0][1]['uid'][0]
			user_dict[uid] = {}
			user_dict[uid]['dn'] = sres[1][0][0]
			for (k,v) in sres[1][0][1].items():
				if k=='objectClass':
					for usertype_id,objectclasses in usertype_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:
							user_dict[uid]['usertype_id'] = usertype_id
							break
					continue
				if len(v)==1:
					user_dict[uid][k] = v[0]
				else:
					user_dict[uid][k] = v
		return user_dict
	def createuser(self,uid,givenname,familyname,passwd,usertype,primarygid=1000,firstyear=None):
		"""
		Add a user to the schools authentication directory service.
		The usertype must be one of the constants TEACHER,STUDENT,PARENT or OTHER
		"""
		# check if the group exists already
		if self.user_exists(uid):
			return -10001
		
		title = userdef.usertype_as_text(usertype)
		if not title:
			return -10005	# invalid usertype id
		usertype_ou = ldapdef.ou_confkey_by_usertype(usertype)
		objectclass = ldapdef.objectclass_by_usertype(usertype)
		if not objectclass:
			return -10006	# Object classes have not been defined for this usertype
			
		path = "uid=%s,%s" % (uid,ldapdef.basedn_by_usertype(usertype))
		
		# Check the group for existance
		import groupmanager as gman
		gm = gman.GroupManager()
		gl = gm.list_groups(None)
		glgid = {}
		for groupname in gl.keys():
			glgid[int(gl[groupname]['gidNumber'])]=groupname
		if not glgid.has_key(primarygid):
			return -10004
		
		
		#uidnumber = self.max(conf.get('LDAPSERVER','basedn'),
		#		'objectclass=posixaccount','uidNumber',
		#		int(conf.get('DOMAIN','uid_start')))+1
		
		uidnumber = None
		uidnumbers = []
		for pw in pwd.getpwall():
			if int(pw[2]) >= int(conf.get('DOMAIN','uid_start')):
				uidnumbers += [int(pw[2])]
		uidnumbers.sort()
		expect_uidnumber = int(conf.get('DOMAIN','uid_start'))
		for i in range(100000):
			if expect_uidnumber != uidnumbers[i]:
				uidnumber = expect_uidnumber
				break
			expect_uidnumber += 1
		
		if uidnumber == None:
			return -10007 # failed to pick an uidnumber
		
		cn = '%s %s' % (givenname,familyname)

		user_info = {'uid':uid,
			'givenname':'%s' % givenname,
			'cn':cn,
			'gidNumber': str(primarygid),
			'uidnumber': str(uidnumber),
			'homeDirectory':'%s/%s/users/%s/.linux' % (conf.get('DOMAIN','domain_root'),conf.get('DOMAIN','domain_name'),uid),
			'sn':'%s' % familyname,
			'objectclass':objectclass,
			'mail': uid,
			'title':title,
			'loginShell': '/bin/zsh',
			'userPassword':mkpasswd(passwd,3,'ssha')}
		if userdef.usertype_as_id(usertype) == userdef.usertype_as_id('student') and firstyear != None:
			user_info['firstSchoolYear'] = str(firstyear)
			
		
		self.bind(conf.get('LDAPSERVER','admin'),conf.get('LDAPSERVER','passwd'))
		self.touch_by_dict({path:user_info})
		
		try:
			posix_uid = pwd.getpwnam(uid)[2]
		except Exception, e:
			print e
			return -10002