nfs4acls: Introduce a helper variable
[Samba.git] / source3 / modules / vfs_shell_snap.c
bloba8c292544194fa6cb98a2a0b3d36ec19262e7a73
1 /*
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/>.
20 #include "includes.h"
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,
30 TALLOC_CTX *mem_ctx,
31 const char *service_path,
32 char **base_volume)
34 NTSTATUS status;
35 const char *cmd;
36 char *cmd_run;
37 int ret;
38 TALLOC_CTX *tmp_ctx;
40 cmd = lp_parm_const_string(handle->conn->params->service,
41 "shell_snap", "check path command", "");
42 if ((cmd == NULL) || (strlen(cmd) == 0)) {
43 DEBUG(0,
44 ("\"shell_snap:check path command\" not configured\n"));
45 status = NT_STATUS_NOT_SUPPORTED;
46 goto err_out;
49 tmp_ctx = talloc_new(mem_ctx);
50 if (tmp_ctx == NULL) {
51 status = NT_STATUS_NO_MEMORY;
52 goto err_out;
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;
59 goto err_tmp_free;
62 ret = smbrun(cmd_run, NULL);
63 if (ret != 0) {
64 DEBUG(0, ("%s failed with %d\n", cmd_run, ret));
65 status = NT_STATUS_NOT_SUPPORTED;
66 goto err_tmp_free;
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;
73 goto err_tmp_free;
75 status = NT_STATUS_OK;
76 err_tmp_free:
77 talloc_free(tmp_ctx);
78 err_out:
79 return status;
82 static NTSTATUS shell_snap_create(struct vfs_handle_struct *handle,
83 TALLOC_CTX *mem_ctx,
84 const char *base_volume,
85 time_t *tstamp,
86 bool rw,
87 char **base_path,
88 char **snap_path)
90 const char *cmd;
91 char *cmd_run;
92 char **qlines;
93 int numlines, ret;
94 int fd = -1;
95 TALLOC_CTX *tmp_ctx;
96 NTSTATUS status;
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;
103 goto err_out;
106 tmp_ctx = talloc_new(mem_ctx);
107 if (tmp_ctx == NULL) {
108 status = NT_STATUS_NO_MEMORY;
109 goto err_out;
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;
116 goto err_tmp_free;
119 ret = smbrun(cmd_run, &fd);
120 talloc_free(cmd_run);
121 if (ret != 0) {
122 if (fd != -1) {
123 close(fd);
125 status = NT_STATUS_UNSUCCESSFUL;
126 goto err_tmp_free;
129 numlines = 0;
130 qlines = fd_lines_load(fd, &numlines, PATH_MAX + 1, tmp_ctx);
131 close(fd);
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;
136 goto err_tmp_free;
139 *base_path = talloc_strdup(mem_ctx, base_volume);
140 if (*base_path == NULL) {
141 status = NT_STATUS_NO_MEMORY;
142 goto err_tmp_free;
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);
148 goto err_tmp_free;
151 status = NT_STATUS_OK;
152 err_tmp_free:
153 talloc_free(tmp_ctx);
154 err_out:
155 return status;
158 static NTSTATUS shell_snap_delete(struct vfs_handle_struct *handle,
159 TALLOC_CTX *mem_ctx,
160 char *base_path,
161 char *snap_path)
163 const char *cmd;
164 char *cmd_run;
165 int ret;
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);
183 if (ret != 0) {
184 return NT_STATUS_UNSUCCESSFUL;
187 return NT_STATUS_OK;
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);