f095b7da337155f8ca244d53bd9d60de397ef0c0
[samba.git] / examples / fuse / smb2mount.c
1 /*
2  * Unix SMB/CIFS implementation.
3  * fusermount smb2 client
4  *
5  * Copyright (C) Volker Lendecke 2016
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "source3/include/includes.h"
22 #include "popt.h"
23 #include "popt_common_cmdline.h"
24 #include "client.h"
25 #include "libsmb/proto.h"
26 #include "clifuse.h"
27
28 static struct cli_state *connect_one(const struct user_auth_info *auth_info,
29                                      const char *server, int port,
30                                      const char *share)
31 {
32         struct cli_state *c = NULL;
33         NTSTATUS nt_status;
34         uint32_t flags = 0;
35
36         if (get_cmdline_auth_info_use_kerberos(auth_info)) {
37                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
38                          CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
39         }
40
41         nt_status = cli_full_connection_creds(&c, lp_netbios_name(), server,
42                                 NULL, port,
43                                 share, "?????",
44                                 get_cmdline_auth_info_creds(auth_info),
45                                 flags,
46                                 get_cmdline_auth_info_signing_state(auth_info));
47         if (!NT_STATUS_IS_OK(nt_status)) {
48                 DBG_ERR("cli_full_connection failed! (%s)\n",
49                         nt_errstr(nt_status));
50                 return NULL;
51         }
52
53         if (get_cmdline_auth_info_smb_encrypt(auth_info)) {
54                 nt_status = cli_cm_force_encryption_creds(
55                         c,
56                         get_cmdline_auth_info_creds(auth_info),
57                         share);
58                 if (!NT_STATUS_IS_OK(nt_status)) {
59                         cli_shutdown(c);
60                         c = NULL;
61                 }
62         }
63
64         return c;
65 }
66
67 int main(int argc, char *argv[])
68 {
69         const char **argv_const = discard_const_p(const char *, argv);
70         TALLOC_CTX *frame = talloc_stackframe();
71         poptContext pc;
72         int opt, ret;
73         int port = 0;
74         char *unc, *mountpoint, *server, *share;
75         struct cli_state *cli;
76
77         struct poptOption long_options[] = {
78                 POPT_AUTOHELP
79                 POPT_COMMON_SAMBA
80                 POPT_COMMON_CREDENTIALS
81                 { "port", 'p', POPT_ARG_INT, &port, 'p', "Port to connect to",
82                   "PORT" },
83                 POPT_TABLEEND
84         };
85
86         smb_init_locale();
87         setup_logging(argv[0], DEBUG_STDERR);
88         lp_set_cmdline("client min protocol", "SMB2");
89         lp_set_cmdline("client max protocol", "SMB3_11");
90
91         lp_load_global(get_dyn_CONFIGFILE());
92         load_interfaces();
93
94         pc = poptGetContext("smb2mount", argc, argv_const, long_options, 0);
95         poptSetOtherOptionHelp(pc, "//server1/share1 mountpoint");
96
97         while ((opt = poptGetNextOpt(pc)) != -1) {
98                 switch(opt) {
99                     case 'p':
100                             break;
101                     default:
102                             fprintf(stderr, "Unknown Option: %c\n", opt);
103                             exit(1);
104                 }
105         }
106
107         if (!poptPeekArg(pc)) {
108                 poptPrintUsage(pc, stderr, 0);
109                 return -1;
110         }
111         unc = talloc_strdup(frame, poptGetArg(pc));
112         if (unc == NULL) {
113                 return -1;
114         }
115         string_replace(unc,'/','\\');
116
117         if (!poptPeekArg(pc)) {
118                 poptPrintUsage(pc, stderr, 0);
119                 return -1;
120         }
121         mountpoint = talloc_strdup(frame, poptGetArg(pc));
122         if (mountpoint == NULL) {
123                 return -1;
124         }
125
126         poptFreeContext(pc);
127         popt_burn_cmdline_password(argc, argv);
128
129         server = talloc_strdup(frame, unc+2);
130         if (!server) {
131                 return -1;
132         }
133         share = strchr_m(server,'\\');
134         if (!share) {
135                 fprintf(stderr, "Invalid argument: %s\n", share);
136                 return -1;
137         }
138
139         *share = 0;
140         share++;
141
142         cli = connect_one(popt_get_cmdline_auth_info(), server, port, share);
143         if (cli == NULL) {
144                 return -1;
145         }
146
147         ret = do_mount(cli, mountpoint);
148         if (ret != 0) {
149                 fprintf(stderr, "mount failed\n");
150                 return -1;
151         }
152
153         popt_free_cmdline_auth_info();
154         TALLOC_FREE(frame);
155         return 0;
156 }