s4:dsdb: Fix stack use after scope in gkdi_create_root_key()
[samba.git] / source3 / modules / onefs_config.c
1 /*
2  * Unix SMB/CIFS implementation.
3  * Support for OneFS
4  *
5  * Copyright (C) Todd Stecher, 2009
6  * Copyright (C) Tim Prouty, 2009
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "includes.h"
23 #include "smbd/smbd.h"
24 #include "onefs_config.h"
25
26 #include <ifs/ifs_syscalls.h>
27
28 #define ONEFS_DATA_FASTBUF      10
29
30 struct onefs_vfs_share_config vfs_share_config[ONEFS_DATA_FASTBUF];
31 struct onefs_vfs_share_config *pvfs_share_config;
32
33 static void onefs_load_faketimestamp_config(struct connection_struct *conn,
34                                             struct onefs_vfs_share_config *cfg)
35 {
36         const char **parm;
37         int snum = SNUM(conn);
38
39         parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_NOW,
40                                    PARM_ATIME_NOW_DEFAULT);
41
42         if (parm) {
43                 cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
44                 set_namearray(&cfg->atime_now_list,*parm);
45         }
46
47         parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_CTIME_NOW,
48                                    PARM_CTIME_NOW_DEFAULT);
49
50         if (parm) {
51                 cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
52                 set_namearray(&cfg->ctime_now_list,*parm);
53         }
54
55         parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_NOW,
56                                    PARM_MTIME_NOW_DEFAULT);
57
58         if (parm) {
59                 cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
60                 set_namearray(&cfg->mtime_now_list,*parm);
61         }
62
63         parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_STATIC,
64                                    PARM_ATIME_STATIC_DEFAULT);
65
66         if (parm) {
67                 cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
68                 set_namearray(&cfg->atime_static_list,*parm);
69         }
70
71         parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_STATIC,
72                                    PARM_MTIME_STATIC_DEFAULT);
73
74         if (parm) {
75                 cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
76                 set_namearray(&cfg->mtime_static_list,*parm);
77         }
78
79         cfg->atime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_ATIME_SLOP,
80                                       PARM_ATIME_SLOP_DEFAULT);
81         cfg->ctime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_CTIME_SLOP,
82                                       PARM_CTIME_SLOP_DEFAULT);
83         cfg->mtime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_MTIME_SLOP,
84                                       PARM_MTIME_SLOP_DEFAULT);
85 }
86
87 /**
88  * Set onefs-specific vfs global config parameters.
89  *
90  * Since changes in these parameters require calling syscalls, we only want to
91  * call them when the configuration actually changes.
92  */
93 static void onefs_load_global_config(connection_struct *conn)
94 {
95         static struct onefs_vfs_global_config global_config;
96         bool dot_snap_child_accessible;
97         bool dot_snap_child_visible;
98         bool dot_snap_root_accessible;
99         bool dot_snap_root_visible;
100         bool dot_snap_tilde;
101         bool reconfig_dso = false;
102         bool reconfig_tilde = false;
103
104         /* Check if this is the first time setting the config options. */
105         if (!(global_config.init_flags & ONEFS_VFS_CONFIG_INITIALIZED)) {
106                 global_config.init_flags |= ONEFS_VFS_CONFIG_INITIALIZED;
107
108                 /* Set process encoding */
109                 onefs_sys_config_enc();
110
111                 reconfig_dso = true;
112                 reconfig_tilde = true;
113         }
114
115         /* Get the dot snap options from the conf. */
116         dot_snap_child_accessible =
117             lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
118                          PARM_DOT_SNAP_CHILD_ACCESSIBLE,
119                          PARM_DOT_SNAP_CHILD_ACCESSIBLE_DEFAULT);
120         dot_snap_child_visible =
121             lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
122                          PARM_DOT_SNAP_CHILD_VISIBLE,
123                          PARM_DOT_SNAP_CHILD_VISIBLE_DEFAULT);
124         dot_snap_root_accessible =
125             lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
126                          PARM_DOT_SNAP_ROOT_ACCESSIBLE,
127                          PARM_DOT_SNAP_ROOT_ACCESSIBLE_DEFAULT);
128         dot_snap_root_visible =
129             lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
130                          PARM_DOT_SNAP_ROOT_VISIBLE,
131                          PARM_DOT_SNAP_ROOT_VISIBLE_DEFAULT);
132         dot_snap_tilde =
133             lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
134                          PARM_DOT_SNAP_TILDE,
135                          PARM_DOT_SNAP_TILDE_DEFAULT);
136
137         /* Check if any of the dot snap options need updating. */
138         if (dot_snap_child_accessible !=
139             global_config.dot_snap_child_accessible) {
140                 global_config.dot_snap_child_accessible =
141                     dot_snap_child_accessible;
142                 reconfig_dso = true;
143         }
144         if (dot_snap_child_visible !=
145             global_config.dot_snap_child_visible) {
146                 global_config.dot_snap_child_visible =
147                     dot_snap_child_visible;
148                 reconfig_dso = true;
149         }
150         if (dot_snap_root_accessible !=
151             global_config.dot_snap_root_accessible) {
152                 global_config.dot_snap_root_accessible =
153                     dot_snap_root_accessible;
154                 reconfig_dso = true;
155         }
156         if (dot_snap_root_visible !=
157             global_config.dot_snap_root_visible) {
158                 global_config.dot_snap_root_visible =
159                     dot_snap_root_visible;
160                 reconfig_dso = true;
161         }
162         if (dot_snap_tilde != global_config.dot_snap_tilde) {
163                 global_config.dot_snap_tilde = dot_snap_tilde;
164                 reconfig_tilde = true;
165         }
166
167         /* If a dot snap option has changed update the process.  */
168         if (reconfig_dso) {
169                 onefs_sys_config_snap_opt(&global_config);
170         }
171
172         /* If the dot snap tilde option has changed update the process.  */
173         if (reconfig_tilde) {
174                 onefs_sys_config_tilde(&global_config);
175         }
176 }
177
178 int onefs_load_config(connection_struct *conn)
179 {
180         int snum = SNUM(conn);
181         int share_count = lp_numservices();
182
183         /* Share config */
184         if (!pvfs_share_config) {
185
186                 if (share_count <= ONEFS_DATA_FASTBUF)
187                         pvfs_share_config = vfs_share_config;
188                 else {
189                         pvfs_share_config =
190                             SMB_MALLOC_ARRAY(struct onefs_vfs_share_config,
191                                              share_count);
192                         if (!pvfs_share_config) {
193                                 errno = ENOMEM;
194                                 return -1;
195                         }
196
197                         memset(pvfs_share_config, 0,
198                             (sizeof(struct onefs_vfs_share_config) *
199                                     share_count));
200                 }
201         }
202
203         if ((pvfs_share_config[snum].init_flags &
204                 ONEFS_VFS_CONFIG_INITIALIZED) == 0) {
205                         pvfs_share_config[snum].init_flags =
206                             ONEFS_VFS_CONFIG_INITIALIZED;
207                         onefs_load_faketimestamp_config(conn,
208                                                         &pvfs_share_config[snum]);
209         }
210
211         /* Global config */
212         onefs_load_global_config(conn);
213
214         return 0;
215 }
216
217 bool onefs_get_config(int snum, int config_type,
218                       struct onefs_vfs_share_config *cfg)
219 {
220         if ((pvfs_share_config != NULL) &&
221             (pvfs_share_config[snum].init_flags & config_type))
222                 *cfg = pvfs_share_config[snum];
223         else
224                 return false;
225
226         return true;
227 }
228
229
230 /**
231  * Set the per-process encoding, ignoring errors.
232  */
233 void onefs_sys_config_enc(void)
234 {
235         int ret;
236
237         ret = enc_set_proc(ENC_UTF8);
238         if (ret) {
239                 DEBUG(0, ("Setting process encoding failed: %s\n",
240                         strerror(errno)));
241         }
242 }
243
244 /**
245  * Set the per-process .snpashot directory options, ignoring errors.
246  */
247 void onefs_sys_config_snap_opt(struct onefs_vfs_global_config *global_config)
248 {
249         struct ifs_dotsnap_options dso;
250         int ret;
251
252         dso.per_proc = 1;
253         dso.sub_accessible = global_config->dot_snap_child_accessible;
254         dso.sub_visible = global_config->dot_snap_child_visible;
255         dso.root_accessible = global_config->dot_snap_root_accessible;
256         dso.root_visible = global_config->dot_snap_root_visible;
257
258         ret = ifs_set_dotsnap_options(&dso);
259         if (ret) {
260                 DEBUG(0, ("Setting snapshot visibility/accessibility "
261                         "failed: %s\n", strerror(errno)));
262         }
263 }
264
265 /**
266  * Set the per-process flag saying whether or not to accept ~snapshot
267  * as an alternative name for .snapshot directories.
268  */
269 void onefs_sys_config_tilde(struct onefs_vfs_global_config *global_config)
270 {
271         int ret;
272
273         ret = ifs_tilde_snapshot(global_config->dot_snap_tilde);
274         if (ret) {
275                 DEBUG(0, ("Setting snapshot tilde failed: %s\n",
276                         strerror(errno)));
277         }
278 }