2 * Unix SMB/CIFS implementation.
3 * Group Policy Update event for winbindd
4 * Copyright (C) David Mulder 2017
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "param/param.h"
21 #include "param/loadparm.h"
23 #include "lib/global_contexts.h"
27 * return Random integer between 5400 and 7200, the group policy update
30 * Group Policy should be updated every 90 minutes in the background,
31 * with a random offset between 0 and 30 minutes. This ensures mutiple
32 * clients will not update at the same time.
34 #define GPUPDATE_INTERVAL (90*60)
35 #define GPUPDATE_RAND_OFFSET (30*60)
36 static uint32_t gpupdate_interval(void)
38 int rand_int_offset
= generate_random() % GPUPDATE_RAND_OFFSET
;
39 return GPUPDATE_INTERVAL
+rand_int_offset
;
42 struct gpupdate_state
{
44 struct loadparm_context
*lp_ctx
;
47 static void gpupdate_callback(struct tevent_context
*ev
,
48 struct tevent_timer
*tim
,
49 struct timeval current_time
,
52 struct tevent_timer
*time_event
;
53 struct timeval schedule
;
54 struct tevent_req
*req
= NULL
;
55 struct gpupdate_state
*data
=
56 talloc_get_type_abort(private_data
, struct gpupdate_state
);
57 const char *const *gpupdate_cmd
=
58 lpcfg_gpo_update_command(data
->lp_ctx
);
59 const char *smbconf
= lp_default_path();
61 /* Execute gpupdate */
62 req
= samba_runcmd_send(data
->ctx
, ev
, timeval_zero(), 2, 0,
70 DEBUG(0, ("Failed to execute the gpupdate command\n"));
74 /* Schedule the next event */
75 schedule
= tevent_timeval_current_ofs(gpupdate_interval(), 0);
76 time_event
= tevent_add_timer(ev
, data
->ctx
, schedule
,
77 gpupdate_callback
, data
);
78 if (time_event
== NULL
) {
79 DEBUG(0, ("Failed scheduling the next gpupdate event\n"));
83 void gpupdate_init(void)
85 struct tevent_timer
*time_event
;
86 struct timeval schedule
;
87 TALLOC_CTX
* ctx
= talloc_new(global_event_context());
88 struct gpupdate_state
*data
= talloc(ctx
, struct gpupdate_state
);
89 struct loadparm_context
*lp_ctx
=
90 loadparm_init_s3(NULL
, loadparm_s3_helpers());
93 * Check if gpupdate is enabled for winbind, if not
94 * return without scheduling any events.
96 if (!lpcfg_apply_group_policies(lp_ctx
)) {
101 * Execute the first event immediately, future events
102 * will execute on the gpupdate interval, which is every
103 * 90 to 120 minutes (at random).
105 schedule
= tevent_timeval_current_ofs(0, 0);
107 data
->lp_ctx
= lp_ctx
;
108 if (data
->lp_ctx
== NULL
) {
109 smb_panic("Could not load smb.conf\n");
111 time_event
= tevent_add_timer(global_event_context(), data
->ctx
,
112 schedule
, gpupdate_callback
, data
);
113 if (time_event
== NULL
) {
114 DEBUG(0, ("Failed scheduling the gpupdate event\n"));