LDAPã€ã³ã¿ãŒãã§ãŒã¹ããè¡ããããã¹ãŠã®ããšã¯ãSamba 4 Python Scriptingã§è¡ãããšãã§ããŸãã å©ç¹-ãã¡ã€ã«ã¢ã¯ã»ã¹ãããã¯ãLDAPã«ã¯ãªãé«éã§ããã€ãã®æ©èœãæå³ããŸãã ããšãã°ãããããŒã¿ããŒã¹ãããŠãŒã¶ãŒãã¹ã¯ãŒãã®ããã·ã¥ãååŸããŠãå¥ã®ããŒã¿ããŒã¹ã«è»¢éã§ããŸãã ãŸããSIDããã¹ã¯ãŒãããã®ä»ãã¹ãŠãåãããŠãŒã¶ãŒèªèº«ãå¥ã®ãã¡ã€ã³ã«è»¢éããå¿ èŠããããŸãïŒSIDã®å±¥æŽã«åé¡ã¯ãããŸããïŒã
ããã¥ã¡ã³ãã ãã§ã¯ååã§ã¯ãããŸãããã ãœãŒã¹ãããå Žåã¯<samba-source> / python / sambaãã£ã¬ã¯ããªã«ããããã以å€ã®å Žåã¯/usr/lib/python2.7/dist-packages/sambaã«ãããŸãã
æãèå³æ·±ãã®ã¯ãsamdb.pyãã¡ã€ã«ã§ããããã¯ãADã®ã»ãšãã©ã®æäœã®å®è£ ã§ãã
ADãã¡ã€ã³ã³ã³ãããŒã©ãŒã®æ§æã«Samba4ãã€ã³ã¹ããŒã«ãããŠãããšããŸãã Pythonããã°ã©ã ããADããŒã¿ããŒã¹ã«æ¥ç¶ããŠã¿ãŸãããã ãŸããå¿ èŠãªã©ã€ãã©ãªãã€ã³ããŒãããŸãã
#!/usr/bin/env python # -*- coding: utf-8 -*- import ldb from samba.samdb import SamDB from samba.auth import system_session from samba.ndr import ndr_pack, ndr_unpack from samba.dcerpc import security import samba.param import base64 import binascii
ã¡ã€ã³ããŒã¿ããŒã¹/sam.ldbãžã®æ¥ç¶ïŒ
lp = samba.param.LoadParm() lp.load(samba.param.default_path()) # lp.load("/etc/samba/smb.conf") sam = SamDB(lp=lp,session_info=system_session())
ïŒSamba4ã€ã³ã¹ããŒã«ã®ãã¡ã€ã«ããã³ãã£ã¬ã¯ããªã®éæšæºã®é 眮ãããã«ã¯å¥ã®äžæããŒã¹ã«æ¥ç¶ããããšãå¯èœã§ããããã«ã€ããŠã¯ä»¥äžãåç §ããŠãã ãããïŒ
ããã§ãsamãªããžã§ã¯ãã䜿çšããŠãLDAPæ§æã«å®å šã«åŸã£ãŠADããŒã¿ããŒã¹ãæ€çŽ¢ããã³å€æŽã§ããŸãã
ããšãã°ãããŒã¿ããŒã¹æ€çŽ¢ïŒããŒã¹ã¯ãCN =ãŠãŒã¶ãŒãDC = myDomãDC = lanãã¿ã€ãã®LDAPããªãŒããŒããåŒã¯ãªãã·ã§ã³ã®éžææ¡ä»¶ãattrsã¯å¿ èŠãªå±æ§ã®ãªã¹ãã§ãïŒïŒ
res = sam.search(base=base, expression=expression, attrs=[*])
ãŠãŒã¶ãŒãOSã«æšªãããããšãèš±å¯ããŸãã
base = "OU=myUsers,DC=myDom,DC=lan" # base = "CN=Users,DC=myDom,DC=lan"
ãã¹ã¯ãŒããsecretãã§ãŠãŒã¶ãŒãtstããäœæããŸãã SamDBã¯ã©ã¹ã«ã¯æ¢è£œã®ã¡ãœãã-newuserïŒïŒããããŸããããããè©Šãããšãã§ããŸãã
newUsr = "tst" usrPass = "secret" ld = {'dn': 'CN=%s,%s' % (newUsr,base), "sAMAccountName": newUsr, "userPrincipalName": "%s@%s" % (newUsr,"myDom.lan"), "objectClass": "user", "displayName": newUsr, "description": newUsr, "homeDirectory": r"\\%s\users\%s" % ("myHost",newUsr), 'scriptPath': "loginScr.cmd", } sam.transaction_start() try: sam.add(ld) sam.setpassword("(samAccountName=%s)" % ldb.binary_encode(newUsr), usrPass, False) except: sam.transaction_cancel() print '!!!error' else: sam.transaction_commit()
ã芧ã®ãšãããSamDBã¯ãã©ã³ã¶ã¯ã·ã§ã³ããµããŒãããŠããŸãã
ADããŒã¿ããŒã¹å šäœãããã»ã©å€§ãããªãå Žåã¯ã次ã®ã³ãã³ãã§è¡šç€ºïŒããã³ç·šéïŒã§ããŸãã
:~# ldbedit -e nano -H /var/lib/samba/private/sam.ldb
ãã ãã-sãŸãã¯-bïŒããŒã¹ïŒãªãã·ã§ã³ã䜿çšããŠéžæãå¶éããããšããå§ãããŸããããšãã°ã -b 'CN = RID Manager $ãCN = SystemãDC = myDomãDC = com'ã§ãã
ãã¹ã¯ãŒãããã·ã¥ã®è»¢éã¯ã次ã®ããã«å®è¡ã§ããŸãã
Samba4ã«ãå€ãADããŒã¹ããããšããŸãã æ°ããSamba4ã€ã³ã¹ããŒã«ãè¿œå ã®AD DCãšããŠæ¥ç¶ããããšã«ãããWindows ADããããŒã¿ããŒã¹ã®ã¬ããªã«ãååŸã§ããŸã-ããææžåãããç°¡åãªæé - ãã¡ããåç §ããŠãã ãã ã
ã³ããŒããŠæ¥ç¶ããŸã-æ¥ç¶sam0ãåŒã³åºããŸãããã éæšæºãã¹ãšã®æ¥ç¶ïŒåãå Žæã§/ tmp / privãšsmb.confã«ã³ããŒãããŠãã ããïŒïŒ
lp0 = samba.param.LoadParm() lp0.load('/tmp/priv/smb.conf') lp0.set('private directory','/tmp/priv') sam0 = SamDB(lp=lp0,session_info=system_session())
ãŠãŒã¶ãŒã®ãªã¹ãå šäœãååŸãããã¹ã¯ãŒãã䜿çšããŠã次ã®ãªã¯ãšã¹ããè¡ããŸãã
res = sam0.search(base="DC=oldDom,DC=myDom,DC=ru",expression="(&(objectCategory=person)(objectClass=user))", attrs=['*','unicodePwd'])
ãŠãŒã¶ãŒããŒã¹ã䞊ã¹æ¿ããŠãæ°ããããŒã¿ããŒã¹ã«è¿œå ããŸãã æŠç¥çã«ã¯ã次ã®ããã«ãªããŸãã
for r in res: dn = str(r.dn)# DN , . ! ------- sd = ndr_unpack(security.dom_sid,r['objectSid'][0])# SID , (dom_sid, rid) = sd.split()# SID SID RID ------- #.... - sam.add(ld). ( - ) # : setpw = """ dn: %s changetype: modify replace: unicodePwd unicodePwd:: %s """ % (dn, base64.b64encode(str(r['unicodePwd']))) sam.transaction_start() try: sam.modify_ldif(setpw,["local_oid:1.3.6.1.4.1.7165.4.3.12:0"]) except: sam.transaction_cancel() print( '!!! ERROR SET PASSWORD USER : %s' % r['sAMAccountName']) else: sam.transaction_commit()
ããã§ãWin 2003ã®ãã¡ã€ã³ããSamba4ã«ãŠãŒã¶ãŒã転éããå®éã®äŸã§ãã
å€ããã¡ã€ã³ã«ã¯åé¡ãèç©ãããŠããŸãïŒééã£ããã¡ã€ã³åã§å§ãŸã£ãŠããŠãïŒã DCããSamba4ãžã®éåžžã®ã¬ããªã±ãŒã·ã§ã³ïŒå察æ¹å-Samba4 DC-> W2003 DCïŒã¯ããããããã¡ã€ã³å ã®åé¡ãåå ã§éå§ãããŸããã§ããã
ã¿ã¹ã¯ã¯Samba3äžã®ãã¡ã€ã«ãµãŒããŒã®ååšã«ãã£ãŠæªåãããããSAM3ã«æ¢ã«ååšããsAMAccountName <->ãããã³ã°ïŒUIDãGIDïŒïŒéåžžã¯/var/lib/samba/winbindd_idmap.tdb ïŒãä¿åããå¿ èŠããããŸããã å®éã«ã¯ãã¿ã¹ã¯ã¯ããã§èª¬æããã¿ã¹ã¯ã«äŒŒãŠããŸãã ã
ãã¹ãŠã®å®éšãšæçµããŒãžã§ã³ã¯ãOpenVZã³ã³ãããŒïŒCentOS 6ïŒã§å®è¡ãããŠããUbuntu 14.04ãµãŒããŒã§è¡ãããŸãã
Samba4ã®ã€ã³ã¹ããŒã«ãæ§æã¯äœåºŠã説æãããŠããŸãã ããšãã°ããã§ã«ããã§èšåãããŠããŸã ã rfc2307ã䜿çšããã¹ããŒã ã§ã®Unix IDã®éåžžã®è¡šç€ºã«ã¯ã sssdã䜿çšãããŸããã ã¡ãªã¿ã«ãå€ãã®äººããå§ãããsernet Samba4ã¢ã»ã³ããªã¯äœ¿çšããªãã»ãããã-sssdããã±ãŒãžãšåéã«ãªãã®ã¯é£ããã
ãŠãŒã¶ãŒã®ãã¹ã¯ãŒããšSIDãä¿åããã«ã¯ãåè¿°ã®ããã«ãå€ãADããŒã¿ããŒã¹ããã©ã€ããŒããã£ã¬ã¯ããªSamba4ã®åœ¢ã§æ¢ã«ååšããŠããå¿ èŠããããŸãã è©³çŽ°ïŒ ãããåç §ïŒããsamba-tool domain join samdom.example.com DC -Uadministrator --realm = samdom.example.comããã¹ããããããšãå¿ èŠãªããŒã¿ããŒã¹ãæ¢ã«äœæãããŠãããããsambaãµãŒãã¹ãéå§ããã«ããã§åæ¢ã§ããŸãã ã ããŒã¿ããŒã¹ãããã«æŽæ°ããå¿ èŠãããå Žåã¯ãsambaãµãŒãã¹ãéå§ããã«è¡ãããšã¯ã§ããŸããã
æ¢åã®Win ADãã¡ã€ã³ãžã®åœ±é¿ã¯æå°éã§ãïŒã»ãšãã©ã¢ã€ãã«ç¶æ ã®ã³ã³ãããŒã©ãŒããã1ã€äœæãããããããã°ã«å€ãã®NTDSã¬ããªã±ãŒã·ã§ã³ãšã©ãŒãçºçããŸãïŒãã¹ã¿ã³ãã¢ãã³ADããŒã¿ããŒã¹ãäœæããåŸããªã¹ã¯ãªãã§ä»®æ³ç°å¢ã§å®è¡ã§ããŸãã MS Winãã¡ã€ã³ããã°ããã®éæ£åžžã«åäœããå¿ èŠãããå Žåããã®äžæçãªSamba4ã匷å¶çµäºããåäœäžã®DCãããã®DCã«é¢ããæ å ±ãã¯ãªãŒã³ã¢ããããããšããå§ãããŸãã
çµæã®ãã©ã€ããŒããã£ã¬ã¯ããªïŒéåžž/ var / lib / samba / privateãŸãã¯/ usr / local / samba / private ïŒã¯å°æ¥ã®Samba4ã«ã©ããã«ã³ããŒãã/ etc / sambaããsmb.confãã³ããŒããå¿ èŠããããŸãã ããã§ãå€ããã¡ã€ã³ã«é¢ãããã¹ãŠã®ããŒã¿ã1ãæã«ä¿åãããããŒã«ã«FSã§ã䜿çšã§ããããã«ãªããŸããã
Samba3ã«ãã¡ã€ã«ãµãŒããŒããŸã ããå ŽåãSamba3ã§éçºããidmapãä¿æãããå Žåã¯ãSamba3ãã/ var / lib / sambaãã£ã¬ã¯ããªã眮ãå¿ èŠããããŸãïŒwinbindd_idmap.tdbãšgroup_mapping.tdbã®2ã€ã®ãã¡ã€ã«ãå¿ èŠã§ãïŒã ã
conf.pyãã¡ã€ã«ã®åœ¢åŒã§åæãã©ã¡ãŒã¿ãŒããã©ãŒãããããŸãã
#!/usr/bin/env python # -*- coding: utf-8 -*- smb_conf = '/etc/samba/smb.conf' smb_priv = '/var/lib/samba/private' dom0 = 'olddom.mydom.ru' # dom1 = 'newdom.lan' # . (!) , - host = 'newdc' # maildom = 'mydom.ru' # . #homeDirectory, homeDrive = r'\\newdc\Users','Z:' # smb_priv0 = '/var/lib/samba/private-0' #private directory samba4 ( smb.conf!) smb3db = '/var/lib/samba/samba3' # - 3 ( /var/lib/samba ()), None start_unix_id = 50000 # GID UID . ############ d0, d1 = dom0.split('.'), dom1.split('.') base0 = ','.join(['DC='+x for x in d0]) base, dom, realm = ','.join(['DC='+x for x in d1]), d1[0].upper(), '.'.join(d1).upper()
ã¡ã€ã³ã®äŒéé¢æ°ã1ã€ã®ãã¡ã€ã«ã«éããŸããã
lib1.py
mk_domïŒïŒé¢æ°ã®å€éšããã°ã©ã ãšããŠget_dom_sid.pyã®åŒã³åºãããããŸã-æ°ãããã¡ã€ã³ãåæåããŸãã
get_dom_sid.pyã¯ãå€ããã¡ã€ã³ã®SIDãåºåããã ãã§ãïŒ
ããã¯ãæ°ãããã¡ã€ã³ãäœæããã®ãšåãã¹ããªãŒã ã§å€ããã¡ã€ã³ã®ããŒã¿ããŒã¹ã«æ¥ç¶ãããšãã«ãç°å¢å€æ°ãå€ãããŒã¿ã§çœ®ãæãããããããå®è¡ããå¿ èŠããããŸããã
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import string import ldb from struct import unpack #from samba.idmap import IDmapDB from samba.samdb import SamDB from samba.auth import system_session from samba.ndr import ndr_unpack from samba.dcerpc import security import samba.param import base64 from conf import * def get_1out(cmd): # 1 import subprocess return subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout.read().splitlines()[0] if not 'host' in globals(): host = get_1out('hostname').upper() if not 'smb3db' in globals(): smb3db = None my_log = lambda *x: None chgDc = lambda x: x def set_my_log(): # -. . from datetime import datetime global my_log f_log = open(datetime.strftime(datetime.now(), "log_%y-%m-%d_%H:%M:%S.txt"),'w') def my_log(*x): try: xx = ' '.join(x) except: xx = ' '.join(map(lambda a: str(a),x)) f_log.write(xx+'\n') print xx def mk_chg(d0=d0,d1=d1): # . d0,d1 . !!!: len(d0) >= len(d1) import re global chgDc if d0 == d1: return dif = len(d0)-len(d1)+1 # , ddx = [d0[0],] + d0[dif:] # , ddx == d0 #1 , 2 , 3 .. : myRe = [('',re.compile(r'\b(DC=)?%s\b[,.]?' % x, re.I)) for x in d0[1:dif]] +\ [(b,re.compile(r'\b%s\b' % a)) for (a,b) in zip(ddx,d1)] +\ [(b.upper(),re.compile(r'\b%s\b' % a.upper(), re.I)) for (a,b) in zip(ddx,d1)] def chg(s): # d0 -> d1 for r in myRe: s = r[1].sub(r[0],s) return s chgDc = chg return chg def mk_sam0(smb_priv0=smb_priv0): # . smb_priv0 - private directory ( smb.conf!) import os global sam0 lp0 = samba.param.LoadParm() lp0.load(smb_priv0+'/smb.conf') # smb.conf private directory!!! lp0.set('private directory',smb_priv0) sam0 = SamDB(lp=lp0,session_info=system_session()) os.unsetenv('SMB_CONF_PATH') return sam0 def mk_sam(host=host): # global sam, ridSet, ridMan, sfu, idmap, minRid, nis lp = samba.param.LoadParm() lp.load(smb_conf) lp.set('private directory',smb_priv) sam = SamDB(lp=lp,session_info=system_session()) # idmap = IDmapDB(lp=lp) sfu = "CN=%s,CN=ypservers,CN=ypServ30,CN=RpcServices,CN=System,%s" % (dom,base) # dn sfu (msSFU30OrderNumber...) ridSet = "CN=RID Set,CN=%s,OU=Domain Controllers,%s" % (host, base) # dn rIDNextRID ridMan = "CN=RID Manager$,CN=System,"+base # dn RID Manager if not 'minRid' in globals(): minRid = int(sam.search(base = ridSet, attrs=["rIDNextRID"])[0]["rIDNextRID"][0]) my_log('\tminRid=%s' % str(minRid)) if not 'nis' in globals(): nis = str(sam.search(base=sfu, attrs=['msSFU30Domains'])[0]['msSFU30Domains'][0]) sam.nis = nis return sam def get_map0(i=None, path=smb3db, maps = {}): # sAMAccountName <-> UID idmap smb3 - maps if not maps: if path != None: from samba.samba3 import DbDatabase mapdb = DbDatabase(path+'/group_mapping') for x in mapdb.db.iterkeys(): if x.startswith('UNIXGROUP') : y = mapdb.db.get(x) maps[y[8:-2]] = ('GID',unpack('<L',y[0:4])[0]) mapdb.close() mapdb = DbDatabase(path+'/winbindd_idmap') for x in mapdb.db.iterkeys(): if x.startswith('S-1'): y = mapdb.db.get(x) res = sam0.search(base=base0,expression="(objectSid=%s)" % x.rstrip("\x00"), scope=ldb.SCOPE_SUBTREE, attrs=["sAMAccountName"]) if len(res) > 0 and 'sAMAccountName' in res[0]: maps[str(res[0]["sAMAccountName"][0])] = y.rstrip("\x00").split(" ") mapdb.close() else: # idmap, ID 'Domain Users' my_log('!? Not MAP0') maps['Domain Users'] = ['GID',start_unix_id] if 'sam' in globals(): res = sam.search(base=base,expression="(sAMAccountName=Domain Users)",attrs=['gidNumber']) if len(res) > 0 and 'gidNumber' in res[0]: maps['Domain Users'][1] = int(res[0]['gidNumber'][0]) maps['_users'] = maps['Domain Users'][1] # . my_log('Set Domain Users = %d' % maps['_users']) maps['Administrator'] = ('UID',0) maps['Administrators'] = ('GID',0) if i == None: return maps return maps[i] if i in maps else False def mk_fill_matrix(m,r): # helper m cp_usr() cp_grp() def rp(k,chg=0): # chg!=0 - ! if k in r: m[k] = str(r[k][0]) if chg==0 else chgDc(str(r[k][0])) return rp def mk_fill_ldb_msg(dn): # helper ldb.Message m2 m2 = ldb.Message() m2.dn = ldb.Dn(sam, str(dn)) def rp(fld=None,val='',flg=ldb.FLAG_MOD_REPLACE): if fld: m2[fld] = ldb.MessageElement(str(val), flg, fld) return m2 return rp def usn_sort(res): # res - (ou, grp) x = [r for r in res] x.sort(key = lambda r: int(r["uSNCreated"][0])) return x def rid_sort(res): # res RID x = [r for r in res] x.sort(key = lambda r: int(unpack('<I',r['objectSid'][0][-4:])[0])) return x def set_grp_gid(r,gid): # Unix GID rp = mk_fill_ldb_msg(r.dn) rp("msSFU30NisDomain",nis) rp("msSFU30Name",r['sAMAccountName'][0]) rp("gidNumber",gid) sam.modify(rp()) def set_usr_gid_uid(r,uid): # Unix GID, UID rp = mk_fill_ldb_msg(r.dn) rp("msSFU30NisDomain",nis) rp("uid",r['sAMAccountName'][0]) rp("uidNumber",uid) rp("gidNumber",get_map0('_users')) # rp('objectClass','posixAccount',ldb.FLAG_MOD_ADD) sam.modify(rp()) def map_grp(): # GID IdMap Samba 3 res = sam.search(base=base,expression="(objectClass=group)") my_log( "\tmap_grp ALL GRP COUNT: %s" % len(res)) sam.transaction_start() try: for r in res: x = get_map0(str(r['sAMAccountName'][0])) if x: set_grp_gid(r,x[1]) except: sam.transaction_cancel() my_log( '!!! ERROR MAP GRP %s' % r['sAMAccountName']) else: sam.transaction_commit() def map_usr(): # UID IdMap Samba 3 res = sam.search(base=base,expression="(&(objectCategory=person)(objectClass=user))",attrs=["sAMAccountName"]) my_log( "\tmap_usr ALL USR COUNT: %s" % len(res)) sam.transaction_start() try: for r in res: x = get_map0(str(r['sAMAccountName'][0])) if x: set_usr_gid_uid(r,x[1]) except: sam.transaction_cancel() my_log( '!!! ERROR SET SFU30 ATTR. USER %s !!!' % x[1]) else: sam.transaction_commit() def cp_ou(): # organizationalUnit ous = [str(r.dn) for r in sam.search(base=base,expression="(objectClass=organizationalUnit)", attrs=[])] res = sam0.search(base=base0,expression="(objectClass=organizationalUnit)") my_log( "\tOU COUNT: %s" % len(res)) for r in usn_sort(res): dn = chgDc(str(r.dn)) if not dn in ous: m = {"dn": dn, "objectClass": "organizationalUnit", "name": str(r["name"][0])} try: sam.add(m) except: my_log("!!!Error Add OU : %s" % dn) def cp_usr(): # users = [str(r.dn) for r in sam.search(base=base,expression="(&(objectCategory=person)(objectClass=user))", attrs=[])] res = sam0.search(base=base0,expression="(&(objectCategory=person)(objectClass=user))", attrs=['*','unicodePwd']) my_log( "\tNEW USR COUNT: %s" % len(res)) for r in res: dn = chgDc(str(r.dn)) if dn in users: continue sd = ndr_unpack(security.dom_sid,r['objectSid'][0]) (group_dom_sid, rid) = sd.split() if rid <= minRid: my_log( '!! MinRid ERR : ', r['sAMAccountName'][0] ) continue m = {"dn": dn, "objectClass": "user"} rp = mk_fill_matrix(m,r) rp('userPrincipalName',1) rp('sAMAccountName') rp('sn') rp('name') rp('initials') rp('displayName') rp('scriptPath') rp('description') rp('userAccountControl') rp('pwdLastSet') m["nTSecurityDescriptor"] = r['objectSid'] if 'maildom' in globals(): m["mail"] = "%s@%s" % (r['sAMAccountName'][0], maildom) if 'homeDirectory' in globals(): m["homeDirectory"] = r"%s\%s" % (homeDirectory,r['sAMAccountName'][0]) if 'homeDrive' in globals(): m["homeDrive"] = homeDrive sam.transaction_start() try: sam.add(m) except: sam.transaction_cancel() my_log( '!!! ERROR ADD USER : %s' % m['sAMAccountName']) else: sam.transaction_commit() # Copy the password for it if not 'unicodePwd' in r: my_log( '!!! NOT PASSWD FOR USER : %s' % m['sAMAccountName']) continue setpw = """ dn: %s changetype: modify replace: unicodePwd unicodePwd:: %s """ % (dn, base64.b64encode(str(r['unicodePwd']))) sam.transaction_start() try: sam.modify_ldif(setpw,["local_oid:1.3.6.1.4.1.7165.4.3.12:0"]) except: sam.transaction_cancel() my_log( '!!! ERROR SET PASSWORD USER : %s' % m['sAMAccountName']) else: sam.transaction_commit() def cp_grp(): # grps = [str(r.dn) for r in sam.search(base=base,expression="(objectClass=group)", attrs=[])] res = sam0.search(base=base0,expression="(&(objectClass=group)(objectCategory=Group))") my_log( "\tNEW GRP COUNT: %s" % len(res)) for r in usn_sort(res): dn = chgDc(str(r.dn)) if dn in grps: continue sd = ndr_unpack(security.dom_sid,r['objectSid'][0]) (group_dom_sid, rid) = sd.split() if rid <= minRid: my_log( '!! MinRid ERR : ', r['name'][0] ) continue m = {"dn": dn, "objectClass": "group"} rp = mk_fill_matrix(m,r) rp('sAMAccountName') rp('groupType') rp('description') m["nTSecurityDescriptor"] = r['objectSid'] sam.transaction_start() try: sam.add(m) except: sam.transaction_cancel() my_log( '!!! ERROR add GRP %s !!!' % m['sAMAccountName']) else: sam.transaction_commit() def grp_fill(): # my_log( "\tgrp_fill") grps ={} for r in sam.search(base=base,expression="(&(objectClass=group)(objectCategory=Group))",attrs=['member']): grps[str(r.dn)] = r['member'] if 'member' in r else [] users = [str(r.dn) for r in sam.search(base=base,expression="(&(objectCategory=person)(objectClass=user))", attrs=[])] for r in sam0.search(base=base0,expression="(&(objectClass=group)(objectCategory=Group))",attrs=['member']): if not 'member' in r: continue grp = chgDc(str(r.dn)) if not grps.has_key(grp): my_log( "!!not found group:\t",grp) continue add_m = '' for m in r['member']: m = chgDc(m) if m in grps[grp]: continue if not m in users: try: sam.search(base=m, attrs=[]) except: my_log( "!? err (not found) add %s \tto %s" % (m,grp)) continue add_m += "add: member\nmember: %s\n" % (m) if add_m == '': continue add_m = "\ndn: %s\nchangetype: modify\n%s\n" % (grp,add_m) sam.transaction_start() try: sam.modify_ldif(add_m) except: sam.transaction_cancel() my_log( "!!!Error fill grp "+grp) else: sam.transaction_commit() def set_max_gid_uid(max_gid=start_unix_id, max_uid=start_unix_id): # max GID, UID my_log('set_max_gid_uid start: set max_gid=%s, max_uid=%s' % (max_gid, max_uid)) chg = '' r = sam.search(base=sfu)[0] for x in (['msSFU30MaxGidNumber',max_gid],['msSFU30MaxUidNumber',max_uid]): x[1] = max(x[1],start_unix_id) if not x[0] in r or x[1] > int(r[x[0]][0]): chg += "replace: %s\n%s: %d\n" % (x[0],x[0],x[1]) if chg != '': chg = "\ndn: %s\nchangetype: modify\n%s\n" % (sfu,chg) sam.transaction_start() try: sam.modify_ldif(chg) except: sam.transaction_cancel() my_log( "!!!Error set msSFU30Max...") else: sam.transaction_commit() def get_next_uid(): # UID nm = 'msSFU30MaxUidNumber' r = sam.search(base=sfu)[0] x = start_unix_id if nm in r: x = max(x, int(r[nm][0])) sam.transaction_start() try: sam.modify_ldif("\ndn: %s\nchangetype: modify\nreplace: %s\n%s: %d\n" % (sfu,nm,nm,x+1)) except: sam.transaction_cancel() my_log( "!!!Error set msSFU30Max...") raise else: sam.transaction_commit() return x def set_max_id(): # max GID, UID, , +1 max_gid = max([int(r['gidNumber'][0]) for r in sam.search(base=base,expression="(&(objectClass=group)(gidNumber=*))",attrs=['gidNumber'])]+[0]) max_uid = max([int(r['uidNumber'][0]) for r in sam.search(base=base,expression="(&(objectCategory=person)(objectClass=user)(uidNumber=*))",attrs=['uidNumber'])]+[0]) set_max_gid_uid(max_gid=max_gid+1,max_uid=max_uid+1) def check_id(): # . GID, UID r = sam.search(base=sfu)[0] (max_gid,max_uid) = [int(r[x][0]) if x in r else start_unix_id for x in ('msSFU30MaxGidNumber','msSFU30MaxUidNumber')] my_log('check_id start: initial max_gid=%d, max_uid=%d' % (max_gid, max_uid)) sam.transaction_start() try: for r in rid_sort(sam.search(base=base,expression="(&(objectClass=group)(!(gidNumber=*)))",attrs=['sAMAccountName','objectSid'])): set_grp_gid(r,max_gid) max_gid += 1 for r in usn_sort(sam.search(base=base,expression="(&(objectCategory=person)(objectClass=user)(!(uidNumber=*)))",attrs=['sAMAccountName','uSNCreated'])): set_usr_gid_uid(r,max_uid) max_uid += 1 except: sam.transaction_cancel() my_log( '!!! ERROR check_id %s' % r['sAMAccountName']) else: sam.transaction_commit() set_max_gid_uid(max_gid=max_gid,max_uid=max_uid) def set_max_rid(): # max RID , "RID Set" "RID Manager" res = sam.search(base=base,expression="(&(sAMAccountName=*)(objectSid=*))",attrs=["objectSid"]) my_log( "\tSID COUNT: %s" % len(res)) x = max([int(unpack('<I',r['objectSid'][0][-4:])[0]) for r in res]) rmin = (x-100)/500*500+100 pool = rmin + ((rmin + 499) << 32) my_log("\tRid Set: %d %d %d " % (rmin,x,rmin + 499)) m = mk_fill_ldb_msg(ridSet) m('rIDNextRID',x) m('rIDAllocationPool',pool) m('rIDPreviousAllocationPool',pool) m2 = mk_fill_ldb_msg(ridMan) m2('rIDAvailablePool',rmin + 500 + (1073741823 << 32)) sam.transaction_start() try: sam.modify(m()) sam.modify(m2()) except: sam.transaction_cancel() my_log( '!!! ERROR Set rIDNextRID %s' % x) else: sam.transaction_commit() return x def mk_dom(): # samba 4 SID, administrator = "1" !!! from samba.netcmd.main import cmd_sambatool def cmd(args, subcom='domain'): cmd = cmd_sambatool() try: retval = cmd._run("samba-tool", subcom, *args) except SystemExit, e: retval = e.code except Exception, e: cmd.show_command_error(e) retval = 1 if retval: sys.exit(retval) cmd(('provision', '--host-name=%s' % host, '--realm=%s' % realm, '--domain=%s' % dom, '--domain-sid=%s' % get_1out('./get_dom_sid.py'), '--adminpass=UJHkjhm7KH$$2vrXy', '--function-level=2003', '--server-role=dc', '--use-rfc2307', '--dns-backend=SAMBA_INTERNAL')) cmd(('passwordsettings', 'set', '--complexity=off', '--history-length=0', '--min-pwd-length=0', '--min-pwd-age=0', '--max-pwd-age=0')) cmd(('setpassword', 'administrator', '--newpassword=1'),subcom='user') # 1. !!
mk_domïŒïŒé¢æ°ã®å€éšããã°ã©ã ãšããŠget_dom_sid.pyã®åŒã³åºãããããŸã-æ°ãããã¡ã€ã³ãåæåããŸãã
get_dom_sid.pyã¯ãå€ããã¡ã€ã³ã®SIDãåºåããã ãã§ãïŒ
#!/usr/bin/env python from lib1 import mk_sam0 print mk_sam0().domain_sid
ããã¯ãæ°ãããã¡ã€ã³ãäœæããã®ãšåãã¹ããªãŒã ã§å€ããã¡ã€ã³ã®ããŒã¿ããŒã¹ã«æ¥ç¶ãããšãã«ãç°å¢å€æ°ãå€ãããŒã¿ã§çœ®ãæãããããããå®è¡ããå¿ èŠããããŸããã
ãããã£ãŠãå¿ èŠãªãã¹ãŠã®ããã±ãŒãžïŒsamba4ãsssdãããã³äŸåé¢ä¿ïŒãã€ã³ã¹ããŒã«ãããåŸãå€ãããŒã¿ããŒã¹ã®ãã£ã¬ã¯ããªãé©åãªå Žæã«ã³ããŒãããæ°ãããã¡ã€ã³ã®äœæãéå§ã§ããŸãã
ãã¡ã€ã³ã®åæå-mk_dom.pyãèµ·åããŸãã
#!/usr/bin/env python # -*- coding: utf-8 -*- from lib1 import * set_my_log() mk_dom()
ãã¹ãŠãããŸããã£ãå ŽåïŒãã°ãã¡ã€ã«ã®ååã¯log_ïŒ y-ïŒ m-ïŒ d_ïŒ HïŒïŒ MïŒïŒ S.txtïŒãsmb.confãèŠãŠã[global]ã»ã¯ã·ã§ã³ã«äžæçã«è¿œå ããŸãã
dns forwarder = <å€ãDCã¢ãã¬ã¹>ïŒã¯ãŒã¯ã¹ããŒã·ã§ã³ãæ°ãããã¡ã€ã³ã«è»¢éããæç¹ïŒã
/ var / lib / samba / privateãã/ etcã«krb5.confãã³ããŒããŸãïŒãŸãã¯ã·ã³ããªãã¯ãªã³ã¯ãäœæããŸãïŒã 次ã«ãã¹ã¯ãªãããå®è¡ããŠãå€ããã¡ã€ã³cp_dom.pyã®ãªããžã§ã¯ããã³ããŒããŸãã
#!/usr/bin/env python # -*- coding: utf-8 -*- from lib1 import * set_my_log() my_log(base0,' ->',base, dom, realm) mk_chg() # mk_sam0() # mk_sam() # cp_ou() # organizationalUnit cp_grp() # cp_usr() # grp_fill() # get_map0() # sAMAccountName <-> UID ( idmap Samba3) map_grp() # unix GID map_usr() # unix GID, UID set_max_rid() # max RID , "RID Set" "RID Manager" set_max_id() # max GID, UID, , +1 check_id() # GID, UID
ãšã©ãŒã¯å¿ ç¶çã«ãã°ãã¡ã€ã«ã«åé¡ãããŸãã æãæ·±å»ãª-3ã€ã®æåãïŒã åã«ã ã¿ã€ãïŒ
!!! ãŠãŒã¶ãŒè¿œå ãšã©ãŒïŒ5CA6ADDF-A2C8-46E5-A
!!! ãã¹ã¯ãŒãèšå®ãŠãŒã¶ãŒã®ãšã©ãŒïŒ5CA6ADDF-A2C8-46E5-A
ã»ãšãã©ã®å Žåããããã¯çŸåšã®ã¹ããŒã ã«ã¯ååšãããæ¬è³ªçã«äžèŠãªãªããžã§ã¯ãã§ãã ãã¡ã€ã³å ã®ãã©ã¬ã¹ãã«å¥ã®ãã¡ã€ã³ããã®ãŠãŒã¶ãŒãããå Žåããããã®è¿œå ãæ©èœããããã°ã«èšé²ãããŸãã åãšã©ãŒã¯éèŠã§ã¯ãããŸãã!! MinRid ERRïŒDCOMãŠãŒã¶ãŒ
ãã¹ãŠãèããããå Žåã¯ãSambaãèµ·åããŸãã
start samba-ad-dc
sssdèšå®ã«ã€ããŠå°ã
詳现ã«ã€ããŠã¯ã ããã§èª¬æããŸã ïŒæ¹æ³1ïŒKerberosãä»ããADãžã®æ¥ç¶ïŒã
sssdçšã®Kerberosã®æºåïŒ
ãã¡ã€ã«/etc/sssd/sssd.confïŒ
sssdãã£ãã·ã¥ããªã»ããããŸãã
sssdã®åèµ·åïŒ
ãšããã§ãsssdãã£ãã·ã¥ããã©ãã·ã¥ããŠããADã«å€§ããªå€æŽãå ããããªãå ŽåããããŸãã 次ã«ãsssdãåæ¢ãããã/ var / lib / sss /ãããã£ã¬ã¯ããªãåé€ãã空ã®æ§é ãïŒã€ã³ã¹ããŒã«ããã±ãŒãžããïŒåŸ©å ããå¿ èŠããããŸãã
sssdçšã®Kerberosã®æºåïŒ
samba-tool domain exportkeytab /etc/krb5.sssd.keytab --principal=<myHostName>$ chown root:root /etc/krb5.sssd.keytab chmod 600 /etc/krb5.sssd.keytab
ãã¡ã€ã«/etc/sssd/sssd.confïŒ
[sssd] services = nss, pam config_file_version = 2 domains = newdom.lan [nss] [pam] [domain/newdom.lan] id_provider = ad auth_provider = ad ldap_schema = ad krb5_keytab = /etc/krb5.sssd.keytab access_provider = ad ldap_id_mapping=false enumerate = true
sssdãã£ãã·ã¥ããªã»ããããŸãã
sss_cache -GU
sssdã®åèµ·åïŒ
restart sssd
ãšããã§ãsssdãã£ãã·ã¥ããã©ãã·ã¥ããŠããADã«å€§ããªå€æŽãå ããããªãå ŽåããããŸãã 次ã«ãsssdãåæ¢ãããã/ var / lib / sss /ãããã£ã¬ã¯ããªãåé€ãã空ã®æ§é ãïŒã€ã³ã¹ããŒã«ããã±ãŒãžããïŒåŸ©å ããå¿ èŠããããŸãã
ãŠãŒã¶ãŒãšã°ã«ãŒãã®è¡šç€ºã確èªããŸãïŒsssdããŒã¿ããŒã¹ã¯ãã°ããã®éãã£ã±ãã«ãªã£ãŠããŸãïŒã
getent passwd getent group
ãŠãŒã¶ãŒããã©ãã°ã¢ã³ãããããããæãç°¡åãªæ¹æ³ã¯ã netdom.exeãŠãŒãã£ãªãã£ïŒnetdom.exe move /ïŒïŒã䜿çšããŠãå€ããµãŒããŒã®ãã°ãªã³ã¹ã¯ãªããã«è¿œå ããããšã§ãã OSã«é©ããnetdom.exeã®ããŒãžã§ã³ãå®è¡ããå¿ èŠããããŸãã SIDãGIDãUIDãããã³ãŠãŒã¶ãŒãã¹ã¯ãŒããä¿åãããŠããããã移åã¯ãŠãŒã¶ãŒã«å¯ŸããŠã»ãšãã©ééçã§ããããŒã«ã«ãã©ã«ããŒã¯ãããã¯ãŒã¯ãªãœãŒã¹ãå«ãããŸãŸã§ãã Sambaãã¡ã€ã«ãµãŒããŒæ§æã§ãã¡ã€ã³ã®ååãå€æŽããã ãã§ãã
ç§ã«ãšã£ãŠã¯ããã«ç°¡åã§ãã-åç©åå šäœãOpenVZã®äžã«äœãã§ãããããå¥ã®FSäžã®ãããã¯ãŒã¯ãªãœãŒã¹ã¯ç°ãªããã¡ã€ã«ãµãŒããŒã«åæã«ç°¡åã«ããŠã³ãã§ãïŒDCããã¡ã€ã«ãµãŒããŒã«ããããšãå¯èœã§ãïŒãã¢ã¯ã»ã¹ã®åé¡ã¯GIDãšUIDãäžèŽãããããšã§èªåçã«è§£æ±ºãããŸããã
ã°ã«ãŒãããªã·ãŒãªããžã§ã¯ãã¯æ°ãããã¡ã€ã³ã«ç§»è¡ãããŸããã§ããã