# SPDX-License-Identifier: AGPL-3.0-or-later # kpov_util should be imported by add_assignment.py # Poveži se na strežnik LDAP prek spletnega vmesnika. Ustvari uporabnika z danim imenom in geslom. # Napiši skripto, ki izpiše podatke o tem uporabniku z ldapsearch. # TODO: finish this! instructions = { 'si': '''\
Ustvari dva navidezna računalnika: SimpleArbiter in LDAPServer.
Na LDAPServer namesti strežnik LDAP. Strežnik naj skrbi za domeno
DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
V imeniku ustvari uporabnika
CN={{LDAP_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
z geslom {{LDAP_PASSWORD}}
in uporabnika
CN={{BIND_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
z geslom {{BIND_PASSWORD}}
.
Poskrbi, da se bo lahko klient s SimpleArbiter povezal na LDAP strežnik na LDAPServer.
V primeru, da se klient poveže kot {{BIND_USERNAME}}
z geslom {{BIND_PASSWORD}}
,
naj strežnik omogoči spreminjanje podatkov za objekt
CN={{LDAP_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
ter ustvarjanje novih objektov v
DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
CN = Common Name
O = Organization
OU = Organizational Unit
DC = Domain Component
''',
'en': '''\
Create two virtual machines: SimpleArbiter and LDAPServer.
Set up an LDAP server on LDAPServer. Make it responsible for
DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
Create a user
CN={{LDAP_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
with the password {{LDAP_PASSWORD}}
, and a user
CN={{BIND_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
with the password {{LDAP_PASSWORD}}
.
Make sure that a client from SimpleArbiter can connect to the LDAP server on LDAPServer. If the client identifies themself as {{BIND_USERNAME}}
with the password {{BIND_PASSWORD}}
, allow it to change data for the object
CN={{LDAP_USERNAME}},ou=users,DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
and to create objects in
DC={{DOMAIN}},DC=kpov,DC=lusy,DC=fri,DC=uni-lj,DC=si
CN = Common Name
O = Organization
OU = Organizational Unit
DC = Domain Component
''',
}
computers = {
'LDAPServer': {
'disks': [
{ 'name': 'student-LDAPServer',
},
#{ 'name': 'CDROM',
# 'options':{'readonly': True},
# 'parts': [],# no parts, no mounting.
#}
],
'network_interfaces': [{'network': 'net1'}],
'flavor': 'm1.tiny',
'config_drive': False
},
'SimpleArbiter': {
'disks': [
{ 'name': 'simpleArbiterDhcpGWLDAP',
# attempt automount
},
#{ 'name': 'CDROM',
# 'options': {'readonly': True},
# 'parts': [{'dev': 'b1', 'path': '/cdrom'}],
#},
],
'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
'flavor': 'm1.tiny',
'config_drive': False
}
}
networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
params_meta = {
'LDAP_IP': {'descriptions': {'si': 'IP strežnika', 'en': 'Server IP'}, 'w': True, 'public':True, 'type': 'IP', 'generated': False},
'DOMAIN': {'descriptions': {'si': 'Domena (poddomena kpov.lusy.fri.uni-lj.si)', 'en': 'Domain (subdomain of kpov.lusy.fri.uni-lj.si)'}, 'w': False, 'public':True, 'type': 'username', 'generated': True},
'LDAP_USERNAME': {'descriptions': {'si': 'Uporabniško ime v LDAP', 'en': 'Username in LDAP'}, 'w': False, 'public':True, 'type': 'username', 'generated': True},
'LDAP_PASSWORD': {'descriptions': {'si': 'Geslo v LDAP', 'en': 'LDAP password'}, 'w': False, 'public':True, 'type': 'password', 'generated': True},
'BIND_USERNAME': {'descriptions': {'si': 'Uporabniško ime za dostop do LDAP (bind)', 'en': 'Bind username in LDAP'}, 'w': False, 'public':True, 'type': 'username', 'generated': True},
'BIND_PASSWORD': {'descriptions': {'si': 'Geslo za dostop do LDAP (bind)', 'en': 'Bind password in LDAP'}, 'w': False, 'public':True, 'type': 'password', 'generated': True},
}
def task(LDAP_IP, DOMAIN, LDAP_USERNAME, LDAP_PASSWORD, BIND_USERNAME, BIND_PASSWORD):
from pexpect import pxssh
import pexpect
results = dict()
FULLDOMAIN = "dc={DOMAIN},dc=kpov,dc=lusy,dc=fri,dc=uni-lj,dc=si".format(
**locals())
BIND_DN = "cn={BIND_USERNAME},ou=Users,{FULLDOMAIN}".format(**locals())
s = "ldapsearch -D {BIND_DN} -b {FULLDOMAIN} -w {BIND_PASSWORD}\
-h {LDAP_IP}".format(
**locals())
results['ldapsearch_before'] = pexpect.run(s)
s = "ldapmodify -D {BIND_DN} -w {BIND_PASSWORD} -h {LDAP_IP}".format(
**locals())
modify = pexpect.spawn(s)
FORTUNE = kpov_util.hostname_gen(random.Random(str(LDAP_USERNAME)))
results['fortune'] = FORTUNE
s1 = """
dn: cn={LDAP_USERNAME},ou=Users,{FULLDOMAIN}
changetype: modify
replace: description
description: {FORTUNE}
""".format(**locals())
modify.write(s1)
modify.sendeof()
modify.expect(pexpect.EOF)
results['modify'] = modify.before
s = "ldapsearch -D {BIND_DN} -b {FULLDOMAIN} -w {BIND_PASSWORD}\
-h {LDAP_IP}".format(**locals())
results['ldapsearch_after'] = pexpect.run(s)
return results
def gen_params(user_id, params_meta):
params = dict()
r = random.Random(user_id)
params['DOMAIN'] = kpov_util.hostname_gen(r)
params['LDAP_USERNAME'] = kpov_util.username_gen(r)
params['LDAP_PASSWORD'] = kpov_util.alnum_gen(r, 6)
params['BIND_USERNAME'] = kpov_util.username_gen(r)
params['BIND_PASSWORD'] = kpov_util.alnum_gen(r, 6)
return params
def task_check(results, params):
import re
score = 0
hints = []
s = """.*dn: dc={DOMAIN},dc=kpov,dc=lusy,dc=fri,dc=uni-lj,dc=si\r[^#]*
objectClass: top\r
objectClass: dcObject\r
objectClass: organization\r
.*""".format(**params)
#dc: {DOMAIN}\r
if re.match(s, results['ldapsearch_before'], re.DOTALL):
score += 2
else:
hints += ["domain missing in ldapsearch result"]
s = ".*cn: {}.*".format(re.escape(params['LDAP_USERNAME']))
if re.search(s, results['ldapsearch_before']):
score += 2
else:
hints += ["LDAP_USERNAME missing in: " + s + str(results['ldapsearch_before'])]
fortune = kpov_util.hostname_gen(random.Random(str(params['LDAP_USERNAME'])))
s = ".*cn: {0}.*description: {1}.*".format(
re.escape(params['LDAP_USERNAME']), re.escape(fortune))
if re.match(s, results['ldapsearch_after'], re.DOTALL):
score += 2
else:
hints += ["description missing after update:" + fortune + "\n" + s + str(results['modify']) + str(results['ldapsearch_after'])]
if results['ldapsearch_before'][:100] == results['ldapsearch_after'][:100]:
score += 2
else:
hints += ["ldapsearch before equals after. This should not happen."]
s = '.*\r\nmodifying entry "cn={LDAP_USERNAME},ou=Users,dc={DOMAIN},dc=kpov,dc=lusy,dc=fri,dc=uni-lj,dc=si".*'.format(
**params)
if re.match(s, results['modify'], re.DOTALL):
score += 2
else:
hints += ['Modify error' + s + str(results['modify'])]
return score, hints
def prepare_disks(templates, task_params, global_params):
write_default_config(templates['simpleArbiterDhcpGWLDAP'], global_params)