1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-04 08:22:08 +03:00

gpo: Read GPO versions locally, not from sysvol

Non-kdc clients cannot read directly from the
sysvol, so we need to store the GPT.INI file
locally to read each gpo version.

Signed-off-by: David Mulder <dmulder@suse.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
David Mulder
2018-01-08 07:17:29 -07:00
committed by Andrew Bartlett
parent 4c7348e44d
commit 57faf35cf8
2 changed files with 89 additions and 5 deletions

View File

@ -17,6 +17,7 @@
import sys
import os
import errno
import tdb
sys.path.insert(0, "bin/python")
from samba import NTSTATUSError
@ -29,6 +30,7 @@ from samba.net import Net
from samba.dcerpc import nbt
from samba import smb
import samba.gpo as gpo
from tempfile import NamedTemporaryFile
try:
from enum import Enum
@ -423,6 +425,49 @@ def get_gpo_list(dc_hostname, creds, lp):
gpos = ads.get_gpo_list(creds.get_username())
return gpos
def cache_gpo_dir(conn, cache, sub_dir):
loc_sub_dir = sub_dir.upper()
local_dir = os.path.join(cache, loc_sub_dir)
try:
os.makedirs(local_dir, mode=0o755)
except OSError as e:
if e.errno != errno.EEXIST:
raise
for fdata in conn.list(sub_dir):
if fdata['attrib'] & smb.FILE_ATTRIBUTE_DIRECTORY:
cache_gpo_dir(conn, cache, os.path.join(sub_dir, fdata['name']))
else:
local_name = fdata['name'].upper()
f = NamedTemporaryFile(delete=False, dir=local_dir)
fname = os.path.join(sub_dir, fdata['name']).replace('/', '\\')
f.write(conn.loadfile(fname))
f.close()
os.rename(f.name, os.path.join(local_dir, local_name))
def check_safe_path(path):
dirs = re.split('/|\\\\', path)
if 'sysvol' in path:
dirs = dirs[dirs.index('sysvol')+1:]
if not '..' in dirs:
return os.path.join(*dirs)
raise OSError(path)
def check_refresh_gpo_list(dc_hostname, lp, creds, gpos):
conn = smb.SMB(dc_hostname, 'sysvol', lp=lp, creds=creds, sign=True)
cache_path = lp.cache_path('gpo_cache')
for gpo in gpos:
if not gpo.file_sys_path:
continue
cache_gpo_dir(conn, cache_path, check_safe_path(gpo.file_sys_path))
def gpo_version(lp, path):
# gpo.gpo_get_sysvol_gpt_version() reads the GPT.INI from a local file,
# read from the gpo client cache.
gpt_path = lp.cache_path(os.path.join('gpo_cache', path))
return int(gpo.gpo_get_sysvol_gpt_version(gpt_path)[1])
def apply_gp(lp, creds, test_ldb, logger, store, gp_extensions):
gp_db = store.get_gplog(creds.get_username())
dc_hostname = get_dc_hostname(creds, lp)
@ -432,14 +477,19 @@ def apply_gp(lp, creds, test_ldb, logger, store, gp_extensions):
logger.error('Error connecting to \'%s\' using SMB' % dc_hostname)
raise
gpos = get_gpo_list(dc_hostname, creds, lp)
try:
check_refresh_gpo_list(dc_hostname, lp, creds, gpos)
except:
logger.error('Failed downloading gpt cache from \'%s\' using SMB' \
% dc_hostname)
return
for gpo_obj in gpos:
guid = gpo_obj.name
if guid == 'Local Policy':
continue
path = os.path.join(lp.get('realm').lower(), 'Policies', guid)
local_path = os.path.join(lp.get("path", "sysvol"), path)
version = int(gpo.gpo_get_sysvol_gpt_version(local_path)[1])
path = os.path.join(lp.get('realm'), 'Policies', guid).upper()
version = gpo_version(lp, path)
if version != store.get_int(guid):
logger.info('GPO %s has changed' % guid)
gp_db.state(GPOSTATE.APPLY)