Skip to content

Commit

Permalink
gpo: Add the winbind call to gpupdate
Browse files Browse the repository at this point in the history
Signed-off-by: David Mulder <[email protected]>
Reviewed-by: Garming Sam <[email protected]>
Reviewed-by: Andrew Bartlett <[email protected]>
  • Loading branch information
dmulder authored and metze-samba committed Jan 13, 2018
1 parent fb5241a commit 2ca73cb
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 20 deletions.
11 changes: 7 additions & 4 deletions docs-xml/smbdotconf/domain/gpoupdatecommand.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
<description>
<para>This option sets the command that is called to apply GPO policies.
The samba_gpoupdate script applies System Access and Kerberos Policies.
System Access policies set minPwdAge, maxPwdAge, minPwdLength, and
pwdProperties in the samdb. Kerberos Policies set kdc:service ticket lifetime,
kdc:user ticket lifetime, and kdc:renewal lifetime in smb.conf.
The samba_gpoupdate script applies System Access and Kerberos Policies
to the KDC, or Environment Variable policies to client machines. System
Access policies set minPwdAge, maxPwdAge, minPwdLength, and
pwdProperties in the samdb. Kerberos Policies set kdc:service ticket
lifetime, kdc:user ticket lifetime, and kdc:renewal lifetime in
smb.conf. Environment Variable policies apply environment variables,
such as PATH, to /etc/profile.
</para>
</description>

Expand Down
19 changes: 19 additions & 0 deletions docs-xml/smbdotconf/winbind/applygrouppolicies.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<samba:parameter name="apply group policies"
context="G"
type="boolean"
xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
<description>

<para>This option controls whether winbind will execute the gpupdate
command defined in <smbconfoption name="gpo update command"/> on the
Group Policy update interval. The Group Policy update interval is
defined as every 90 minutes, plus a random offset between 0 and 30
minutes. This applies Group Policy Machine polices to the client or
KDC and machine policies to a server.
</para>

</description>

<value type="default">no</value>
<value type="example">yes</value>
</samba:parameter>
1 change: 1 addition & 0 deletions lib/param/loadparm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2734,6 +2734,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
lpcfg_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
lpcfg_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR);
lpcfg_do_global_parameter_var(lp_ctx, "gpo update command", "%s/samba_gpoupdate", dyn_SCRIPTSBINDIR);
lpcfg_do_global_parameter_var(lp_ctx, "apply group policies", "False");
lpcfg_do_global_parameter_var(lp_ctx, "dns update command", "%s/samba_dnsupdate", dyn_SCRIPTSBINDIR);
lpcfg_do_global_parameter_var(lp_ctx, "spn update command", "%s/samba_spnupdate", dyn_SCRIPTSBINDIR);
lpcfg_do_global_parameter_var(lp_ctx, "samba kcc command",
Expand Down
9 changes: 1 addition & 8 deletions python/samba/gpclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,12 @@
import os
import tdb
sys.path.insert(0, "bin/python")
import samba.gpo as gpo
import optparse
import ldb
from samba.auth import system_session
import samba.getopt as options
from samba.samdb import SamDB
from samba.netcmd import gpo as gpo_user
import codecs
from samba import NTSTATUSError
from ConfigParser import ConfigParser
from StringIO import StringIO
from abc import ABCMeta, abstractmethod
import xml.etree.ElementTree as etree
import re

try:
from enum import Enum
Expand Down
2 changes: 1 addition & 1 deletion selftest/target/Samba4.pm
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ sub provision_raw_step1($$)
rndc command = true
dns update command = $ctx->{samba_dnsupdate}
spn update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba_spnupdate -s $ctx->{smb_conf}
gpo update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba_gpoupdate -s $ctx->{smb_conf} -H $ctx->{privatedir}/sam.ldb
gpo update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba_gpoupdate -s $ctx->{smb_conf} -H $ctx->{privatedir}/sam.ldb --machine
dreplsrv:periodic_startup_interval = 0
dsdb:schema update allowed = yes
Expand Down
2 changes: 2 additions & 0 deletions source3/param/loadparm.c
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
Globals.gpo_update_command = str_list_make_v3_const(NULL, s, NULL);
TALLOC_FREE(s);

Globals.apply_group_policies = false;

s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
if (s == NULL) {
smb_panic("init_globals: ENOMEM");
Expand Down
2 changes: 2 additions & 0 deletions source3/winbindd/winbindd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1790,6 +1790,8 @@ int main(int argc, const char **argv)
daemon_ready("winbindd");
}

gpupdate_init();

/* Loop waiting for requests */
while (1) {
frame = talloc_stackframe();
Expand Down
116 changes: 116 additions & 0 deletions source3/winbindd/winbindd_gpupdate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Unix SMB/CIFS implementation.
* Group Policy Update event for winbindd
* Copyright (C) David Mulder 2017
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "param/param.h"
#include "param/loadparm.h"
#include "winbindd.h"

/*
* gpupdate_interval()
* return Random integer between 5400 and 7200, the group policy update
* interval in seconds
*
* Group Policy should be updated every 90 minutes in the background,
* with a random offset between 0 and 30 minutes. This ensures mutiple
* clients will not update at the same time.
*/
#define GPUPDATE_INTERVAL (90*60)
#define GPUPDATE_RAND_OFFSET (30*60)
static uint32_t gpupdate_interval(void)
{
int rand_int_offset = rand() % GPUPDATE_RAND_OFFSET;
return GPUPDATE_INTERVAL+rand_int_offset;
}

struct gpupdate_state {
TALLOC_CTX *ctx;
struct loadparm_context *lp_ctx;
};

static void gpupdate_callback(struct tevent_context *ev,
struct tevent_timer *tim,
struct timeval current_time,
void *private_data)
{
struct tevent_timer *time_event;
struct timeval schedule;
struct tevent_req *req = NULL;
struct gpupdate_state *data =
talloc_get_type_abort(private_data, struct gpupdate_state);
const char *const *gpupdate_cmd =
lpcfg_gpo_update_command(data->lp_ctx);
const char *smbconf = lp_default_path();

/* Execute gpupdate */
req = samba_runcmd_send(data->ctx, ev, timeval_zero(), 2, 0,
gpupdate_cmd,
"-s",
smbconf,
"--machine",
"--machine-pass",
NULL);
if (req == NULL) {
DEBUG(0, ("Failed to execute the gpupdate command\n"));
return;
}

/* Schedule the next event */
schedule = tevent_timeval_current_ofs(gpupdate_interval(), 0);
time_event = tevent_add_timer(ev, data->ctx, schedule,
gpupdate_callback, data);
if (time_event == NULL) {
DEBUG(0, ("Failed scheduling the next gpupdate event\n"));
}
}

void gpupdate_init(void)
{
struct tevent_timer *time_event;
struct timeval schedule;
TALLOC_CTX * ctx = talloc_new(server_event_context());
struct gpupdate_state *data = talloc(ctx, struct gpupdate_state);
struct loadparm_context *lp_ctx =
loadparm_init_s3(NULL, loadparm_s3_helpers());

/*
* Check if gpupdate is enabled for winbind, if not
* return without scheduling any events.
*/
if (!lpcfg_apply_group_policies(lp_ctx)) {
return;
}

/*
* Execute the first event immediately, future events
* will execute on the gpupdate interval, which is every
* 90 to 120 minutes (at random).
*/
schedule = tevent_timeval_current_ofs(0, 0);
data->ctx = ctx;
data->lp_ctx = lp_ctx;
if (data->lp_ctx == NULL) {
smb_panic("Could not load smb.conf\n");
}
time_event = tevent_add_timer(server_event_context(), data->ctx,
schedule, gpupdate_callback, data);
if (time_event == NULL) {
DEBUG(0, ("Failed scheduling the gpupdate event\n"));
}
}

3 changes: 3 additions & 0 deletions source3/winbindd/winbindd_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -942,4 +942,7 @@ NTSTATUS wb_irpc_register(void);
/* The following definitions come from winbindd/winbindd_reconnect.c */
bool reconnect_need_retry(NTSTATUS status, struct winbindd_domain *domain);

/* The following definitions come from winbindd/winbindd_gpupdate.c */
void gpupdate_init(void);

#endif /* _WINBINDD_PROTO_H_ */
3 changes: 2 additions & 1 deletion source3/winbindd/wscript_build
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ bld.SAMBA3_BINARY('winbindd',
winbindd_pam_logoff.c
winbindd_pam_chauthtok.c
winbindd_pam_auth_crap.c
winbindd_pam_chng_pswd_auth_crap.c''',
winbindd_pam_chng_pswd_auth_crap.c
winbindd_gpupdate.c''',
deps='''
talloc
tevent
Expand Down
21 changes: 19 additions & 2 deletions source4/scripting/bin/samba_gpoupdate
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,18 @@ sys.path.insert(0, "bin/python")

import optparse
from samba import getopt as options
from samba.auth import system_session
try:
from samba.samdb import SamDB
except:
SamDB = None
from samba.gpclass import *
from samba.net import Net
from samba.dcerpc import nbt
from samba import smb
import samba.gpo as gpo
import logging
import chardet

''' Fetch the hostname of a writable DC '''
def get_dc_hostname(creds, lp):
Expand Down Expand Up @@ -117,6 +124,8 @@ if __name__ == "__main__":
parser.add_option('-H', '--url', dest='url', help='URL for the samdb')
parser.add_option('-X', '--unapply', help='Unapply Group Policy',
action='store_true')
parser.add_option('-M', '--machine', help='Apply machine policy',
action='store_true', default=False)
parser.add_option_group(credopts)

# Set the options and the arguments
Expand Down Expand Up @@ -150,10 +159,18 @@ if __name__ == "__main__":
cache_dir = lp.get('cache directory')
store = GPOStorage(os.path.join(cache_dir, 'gpo.tdb'))

gp_extensions = [gp_sec_ext(logger)]
gp_extensions = []
if opts.machine:
if lp.get('server role') == 'active directory domain controller':
gp_extensions.append(gp_sec_ext(logger))
else:
pass # User extensions

# Get a live instance of Samba
test_ldb = SamDB(url, session_info=session, credentials=creds, lp=lp)
if SamDB:
test_ldb = SamDB(url, session_info=session, credentials=creds, lp=lp)
else:
test_ldb = None

if not opts.unapply:
apply_gp(lp, creds, test_ldb, logger, store, gp_extensions)
Expand Down
2 changes: 1 addition & 1 deletion source4/scripting/bin/wscript_build
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ if bld.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'):
'samba_kcc',
'samba_upgradeprovision',
'samba_upgradedns',
'samba_gpoupdate',
'gen_output.py']:
bld.SAMBA_SCRIPT(script, pattern=script, installdir='.')
bld.SAMBA_SCRIPT('samba_gpoupdate', pattern='samba_gpoupdate', installdir='.')
7 changes: 4 additions & 3 deletions source4/scripting/wscript_build
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

from samba_utils import MODE_755

sbin_files = None
sbin_files = ''
if bld.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'):
sbin_files = 'bin/samba_dnsupdate bin/samba_spnupdate bin/samba_upgradedns bin/samba_kcc bin/samba_gpoupdate'
man_files = 'man/samba_gpoupdate.8'
sbin_files = 'bin/samba_dnsupdate bin/samba_spnupdate bin/samba_upgradedns bin/samba_kcc '
sbin_files += 'bin/samba_gpoupdate'
man_files = 'man/samba_gpoupdate.8'

if sbin_files:
bld.INSTALL_FILES('${SBINDIR}',
Expand Down

0 comments on commit 2ca73cb

Please sign in to comment.