From 5662e49b49f6557c80f216f510f224bbf800f40a Mon Sep 17 00:00:00 2001 From: Garming Sam Date: Wed, 9 Aug 2017 14:17:09 +1200 Subject: [PATCH] gpo: Create the gpo update service Split from "Initial commit for GPO work done by Luke Morrison" by David Mulder Signed-off-by: Garming Sam Signed-off-by: Luke Morrison Signed-off-by: David Mulder Then adapted to current master Signed-off-by: Andrew Bartlett --- .../smbdotconf/domain/gpoupdatecommand.xml | 17 ++ lib/param/loadparm.c | 1 + source3/param/loadparm.c | 7 + source4/dsdb/gpo/gpo_update.c | 188 ++++++++++++++++++ 4 files changed, 213 insertions(+) create mode 100644 docs-xml/smbdotconf/domain/gpoupdatecommand.xml create mode 100644 source4/dsdb/gpo/gpo_update.c diff --git a/docs-xml/smbdotconf/domain/gpoupdatecommand.xml b/docs-xml/smbdotconf/domain/gpoupdatecommand.xml new file mode 100644 index 00000000000..22a42163f27 --- /dev/null +++ b/docs-xml/smbdotconf/domain/gpoupdatecommand.xml @@ -0,0 +1,17 @@ + + + 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. + + + +&pathconfig.SCRIPTSBINDIR;/samba_gpoupdate +/usr/local/sbin/gpoupdate + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index a1adb99b1f4..d788ffbe36f 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2730,6 +2730,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "require strong key", "True"); 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, "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", diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 485d3f75b04..d3463246704 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -913,6 +913,13 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL); TALLOC_FREE(s); + s = talloc_asprintf(talloc_tos(), "%s/samba_gpoupdate", get_dyn_SCRIPTSBINDIR()); + if (s == NULL) { + smb_panic("init_globals: ENOMEM"); + } + Globals.gpo_update_command = str_list_make_v3_const(NULL, s, NULL); + TALLOC_FREE(s); + s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR()); if (s == NULL) { smb_panic("init_globals: ENOMEM"); diff --git a/source4/dsdb/gpo/gpo_update.c b/source4/dsdb/gpo/gpo_update.c new file mode 100644 index 00000000000..6f234b42898 --- /dev/null +++ b/source4/dsdb/gpo/gpo_update.c @@ -0,0 +1,188 @@ +/* + Unix SMB/CIFS mplementation. + GPO update service + + Copyright (C) Luke Morrison 2013 + + Inspired by dns_updates.c written by Andrew Trigell 2009 + + 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 sysvscan */ + struct { + uint32_t interval; + struct tevent_timer *te; + struct tevent_req *subreq; + NTSTATUS status; + } sysvscan; +}; + +/* +Called when the sysvol scan has finished +*/ +static void gpoupdate_sysvscan_done(struct tevent_req *subreq) +{ + struct gpoupdate_service *service = tevent_req_callback_data(subreq, + struct + gpoupdate_service); + int ret; + int sys_errno; + + service->sysvscan.subreq = NULL; + + ret = samba_runcmd_recv(subreq, &sys_errno); + TALLOC_FREE(subreq); + if (ret != 0) { + service->sysvscan.status = + map_nt_error_from_unix_common(sys_errno); + } else { + service->sysvscan.status = NT_STATUS_OK; + } + + if (!NT_STATUS_IS_OK(service->sysvscan.status)) { + DEBUG(0, (__location__ ": Failed GPO update - %s\n", + nt_errstr(service->sysvscan.status))); + } else { + DEBUG(3, ("Completed GPO update check OK\n")); + } +} + +static NTSTATUS gpoupdate_sysvscan_schedule(struct gpoupdate_service *service); + +static void gpoupdate_scan_apply(struct gpoupdate_service *service); + +static void gpoupdate_sysvscan_handler_te(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, void *ptr) +{ + struct gpoupdate_service *service = + talloc_get_type(ptr, struct gpoupdate_service); + + gpoupdate_scan_apply(service); + gpoupdate_sysvscan_schedule(service); +} + +static NTSTATUS gpoupdate_sysvscan_schedule(struct gpoupdate_service *service) +{ + /* For the moment the interval is hard coded to 5 sec */ + DEBUG(0, + ("calling %s interval = %d\n", __FUNCTION__, + service->sysvscan.interval)); + service->sysvscan.te = + tevent_add_timer(service->task->event_ctx, service, + timeval_current_ofs(service->sysvscan.interval, 0), + gpoupdate_sysvscan_handler_te, service); + NT_STATUS_HAVE_NO_MEMORY(service->sysvscan.te); + return NT_STATUS_OK; +} + +static void gpoupdate_scan_apply(struct gpoupdate_service *service) +{ + const char *const *gpo_update_command = + lpcfg_gpo_update_command(service->task->lp_ctx); + const char *smbconf = lpcfg_configfile(service->task->lp_ctx); + /* /home/john/samba/samba/source4/scripting/bin/gpoupdate */ + TALLOC_FREE(service->sysvscan.subreq); + DEBUG(3, ("Calling GPO update script\n")); + service->sysvscan.subreq = samba_runcmd_send(service, + service->task->event_ctx, + timeval_current_ofs(20, 0), + 2, 0, + gpo_update_command, + smbconf, NULL); + if (service->sysvscan.subreq == NULL) { + DEBUG(0, + (__location__ + ": samba_runcmd_send() failed with no memory\n")); + return; + } + tevent_req_set_callback(service->sysvscan.subreq, + gpoupdate_sysvscan_done, service); +} + +static void gpoupdate_task_init(struct task_server *task) +{ + NTSTATUS status; + struct gpoupdate_service *service; + + if (lpcfg_server_role(task->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC) { + /* not useful for non-DC */ + return; + } + + task_server_set_title(task, "task[gpoupdate]"); + + service = talloc_zero(task, struct gpoupdate_service); + if (!service) { + task_server_terminate(task, + "gpoupdate_task_init: out of memory", + true); + return; + } + service->task = task; + task->private_data = service; + + service->system_session_info = system_session(service->task->lp_ctx); + if (!service->system_session_info) { + task_server_terminate(task, + "gpoupdate: Failed to obtain server credentials\n", + true); + return; + } + + service->sysvscan.interval = lpcfg_parm_int(task->lp_ctx, NULL, "gpoupdate", "config interval", 900); /* in seconds */ + status = gpoupdate_sysvscan_schedule(service); + if (!NT_STATUS_IS_OK(status)) { + task_server_terminate(task, talloc_asprintf(task, + "gpoupdate: Failed to update sysvol scan schedule: %s\n", + nt_errstr(status)), + true); + return; + } +} + +NTSTATUS server_service_gpoupdate_init(TALLOC_CTX *ctx); + +/* + register ourselves as a available server +*/ +NTSTATUS server_service_gpoupdate_init(TALLOC_CTX *ctx) +{ + struct service_details details = { + .inhibit_fork_on_accept = true, + .inhibit_pre_fork = true + }; + return register_server_service(ctx, "gpoupdate", + gpoupdate_task_init, + &details); +} -- 2.34.1