2 * Module for snapshot management using shell callouts
4 * Copyright (C) David Disseldorp 2013-2015
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/>.
21 #include "include/ntioctl.h"
22 #include "system/filesys.h"
23 #include "smbd/smbd.h"
26 * Check whether a path can be shadow copied. Return the base volume, allowing
27 * the caller to determine if multiple paths lie on the same base volume.
29 static NTSTATUS
shell_snap_check_path(struct vfs_handle_struct
*handle
,
31 const char *service_path
,
40 cmd
= lp_parm_const_string(handle
->conn
->params
->service
,
41 "shell_snap", "check path command", "");
42 if ((cmd
== NULL
) || (strlen(cmd
) == 0)) {
44 ("\"shell_snap:check path command\" not configured\n"));
45 status
= NT_STATUS_NOT_SUPPORTED
;
49 tmp_ctx
= talloc_new(mem_ctx
);
50 if (tmp_ctx
== NULL
) {
51 status
= NT_STATUS_NO_MEMORY
;
55 /* add service path argument */
56 cmd_run
= talloc_asprintf(tmp_ctx
, "%s %s", cmd
, service_path
);
57 if (cmd_run
== NULL
) {
58 status
= NT_STATUS_NO_MEMORY
;
62 ret
= smbrun(cmd_run
, NULL
);
64 DEBUG(0, ("%s failed with %d\n", cmd_run
, ret
));
65 status
= NT_STATUS_NOT_SUPPORTED
;
69 /* assume the service path is the base volume */
70 *base_volume
= talloc_strdup(mem_ctx
, service_path
);
71 if (*base_volume
== NULL
) {
72 status
= NT_STATUS_NO_MEMORY
;
75 status
= NT_STATUS_OK
;
82 static NTSTATUS
shell_snap_create(struct vfs_handle_struct
*handle
,
84 const char *base_volume
,
98 cmd
= lp_parm_const_string(handle
->conn
->params
->service
,
99 "shell_snap", "create command", "");
100 if ((cmd
== NULL
) || (strlen(cmd
) == 0)) {
101 DEBUG(1, ("\"shell_snap:create command\" not configured\n"));
102 status
= NT_STATUS_NOT_SUPPORTED
;
106 tmp_ctx
= talloc_new(mem_ctx
);
107 if (tmp_ctx
== NULL
) {
108 status
= NT_STATUS_NO_MEMORY
;
112 /* add base vol argument */
113 cmd_run
= talloc_asprintf(tmp_ctx
, "%s %s", cmd
, base_volume
);
114 if (cmd_run
== NULL
) {
115 status
= NT_STATUS_NO_MEMORY
;
119 ret
= smbrun(cmd_run
, &fd
);
120 talloc_free(cmd_run
);
125 status
= NT_STATUS_UNSUCCESSFUL
;
130 qlines
= fd_lines_load(fd
, &numlines
, PATH_MAX
+ 1, tmp_ctx
);
133 /* script must return the snapshot path as a single line */
134 if ((numlines
== 0) || (qlines
== NULL
) || (qlines
[0] == NULL
)) {
135 status
= NT_STATUS_UNSUCCESSFUL
;
139 *base_path
= talloc_strdup(mem_ctx
, base_volume
);
140 if (*base_path
== NULL
) {
141 status
= NT_STATUS_NO_MEMORY
;
144 *snap_path
= talloc_strdup(mem_ctx
, qlines
[0]);
145 if (*snap_path
== NULL
) {
146 status
= NT_STATUS_NO_MEMORY
;
147 talloc_free(*base_path
);
151 status
= NT_STATUS_OK
;
153 talloc_free(tmp_ctx
);
158 static NTSTATUS
shell_snap_delete(struct vfs_handle_struct
*handle
,
167 cmd
= lp_parm_const_string(handle
->conn
->params
->service
,
168 "shell_snap", "delete command", "");
169 if ((cmd
== NULL
) || (strlen(cmd
) == 0)) {
170 DEBUG(1, ("\"shell_snap:delete command\" not configured\n"));
171 return NT_STATUS_NOT_SUPPORTED
;
174 /* add base path and snap path arguments */
175 cmd_run
= talloc_asprintf(mem_ctx
, "%s %s %s",
176 cmd
, base_path
, snap_path
);
177 if (cmd_run
== NULL
) {
178 return NT_STATUS_NO_MEMORY
;
181 ret
= smbrun(cmd_run
, NULL
);
182 talloc_free(cmd_run
);
184 return NT_STATUS_UNSUCCESSFUL
;
190 static struct vfs_fn_pointers shell_snap_fns
= {
191 .snap_check_path_fn
= shell_snap_check_path
,
192 .snap_create_fn
= shell_snap_create
,
193 .snap_delete_fn
= shell_snap_delete
,
196 NTSTATUS
vfs_shell_snap_init(void);
197 NTSTATUS
vfs_shell_snap_init(void)
199 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION
,
200 "shell_snap", &shell_snap_fns
);