2 * Samba Unix/Linux SMB client library
3 * Distributed SMB/CIFS Server Management Utility
4 * Local configuration interface
5 * Copyright (C) Vicentiu Ciorbaru 2011
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.
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.
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/>.
22 * This is an interface to Samba's configuration.
24 * This tool supports local as well as remote interaction via rpc
25 * with the configuration stored in the registry.
30 #include "utils/net.h"
31 #include "rpc_client/cli_pipe.h"
32 #include "../librpc/gen_ndr/ndr_samr_c.h"
33 #include "rpc_client/init_samr.h"
34 #include "../librpc/gen_ndr/ndr_winreg_c.h"
35 #include "../libcli/registry/util_reg.h"
36 #include "rpc_client/cli_winreg.h"
37 #include "../lib/smbconf/smbconf.h"
39 /* internal functions */
40 /**********************************************************
44 **********************************************************/
45 const char confpath[100] = "Software\\Samba\\smbconf";
47 static int rpc_conf_list_usage(struct net_context *c, int argc,
50 d_printf("%s net rpc conf list\n", _("Usage:"));
54 static NTSTATUS rpc_conf_get_share(TALLOC_CTX *mem_ctx,
55 struct dcerpc_binding_handle *b,
56 struct policy_handle *parent_hnd,
57 const char *share_name,
58 struct smbconf_service *share,
61 TALLOC_CTX *frame = talloc_stackframe();
63 NTSTATUS status = NT_STATUS_OK;
64 WERROR result = WERR_OK;
66 struct policy_handle child_hnd;
67 int32_t includes_cnt, includes_idx = -1;
68 uint32_t num_vals, i, param_cnt = 0;
69 const char **val_names;
70 enum winreg_Type *types;
72 struct winreg_String key;
73 const char **multi_s = NULL;
75 struct smbconf_service tmp_share;
77 ZERO_STRUCT(tmp_share);
79 key.name = share_name;
80 status = dcerpc_winreg_OpenKey(b, frame, parent_hnd, key, 0,
81 REG_KEY_READ, &child_hnd, &result);
83 if (!(NT_STATUS_IS_OK(status))) {
84 d_fprintf(stderr, _("Failed to open subkey: %s\n"),
88 if (!(W_ERROR_IS_OK(result))) {
89 d_fprintf(stderr, _("Failed to open subkey: %s\n"),
93 /* get all the info from the share key */
94 status = dcerpc_winreg_enumvals(frame,
103 if (!(NT_STATUS_IS_OK(status))) {
104 d_fprintf(stderr, _("Failed to enumerate values: %s\n"),
108 if (!(W_ERROR_IS_OK(result))) {
109 d_fprintf(stderr, _("Failed to enumerate values: %s\n"),
113 /* check for includes */
114 for (i = 0; i < num_vals; i++) {
115 if (strcmp(val_names[i], "includes") == 0){
116 if (!pull_reg_multi_sz(frame,
122 _("Failed to enumerate values: %s\n"),
129 /* count the number of includes */
131 if (includes_idx != -1) {
132 for (includes_cnt = 0;
133 multi_s[includes_cnt] != NULL;
136 /* place the name of the share in the smbconf_service struct */
137 tmp_share.name = talloc_strdup(frame, share_name);
138 if (tmp_share.name == NULL) {
140 d_fprintf(stderr, _("Failed to create share: %s\n"),
144 /* place the number of parameters in the smbconf_service struct */
145 tmp_share.num_params = num_vals;
146 if (includes_idx != -1) {
147 tmp_share.num_params = num_vals + includes_cnt - 1;
149 /* allocate memory for the param_names and param_values lists */
150 tmp_share.param_names = talloc_zero_array(frame, char *, tmp_share.num_params);
151 if (tmp_share.param_names == NULL) {
153 d_fprintf(stderr, _("Failed to create share: %s\n"),
157 tmp_share.param_values = talloc_zero_array(frame, char *, tmp_share.num_params);
158 if (tmp_share.param_values == NULL) {
160 d_fprintf(stderr, _("Failed to create share: %s\n"),
164 /* place all params except includes */
165 for (i = 0; i < num_vals; i++) {
166 if (strcmp(val_names[i], "includes") != 0) {
167 if (!pull_reg_sz(frame, &data[i], &s)) {
170 _("Failed to enumerate values: %s\n"),
174 /* place param_names */
175 tmp_share.param_names[param_cnt] = talloc_strdup(frame, val_names[i]);
176 if (tmp_share.param_names[param_cnt] == NULL) {
178 d_fprintf(stderr, _("Failed to create share: %s\n"),
183 /* place param_values */
184 tmp_share.param_values[param_cnt++] = talloc_strdup(frame, s);
185 if (tmp_share.param_values[param_cnt - 1] == NULL) {
187 d_fprintf(stderr, _("Failed to create share: %s\n"),
193 /* place the includes last */
194 for (i = 0; i < includes_cnt; i++) {
195 tmp_share.param_names[param_cnt] = talloc_strdup(frame, "include");
196 if (tmp_share.param_names[param_cnt] == NULL) {
198 d_fprintf(stderr, _("Failed to create share: %s\n"),
203 tmp_share.param_values[param_cnt++] = talloc_strdup(frame, multi_s[i]);
204 if (tmp_share.param_values[param_cnt - 1] == NULL) {
206 d_fprintf(stderr, _("Failed to create share: %s\n"),
212 /* move everything to the main memory ctx */
213 for (i = 0; i < param_cnt; i++) {
214 tmp_share.param_names[i] = talloc_move(mem_ctx, &tmp_share.param_names[i]);
215 tmp_share.param_values[i] = talloc_move(mem_ctx, &tmp_share.param_values[i]);
218 tmp_share.name = talloc_move(mem_ctx, &tmp_share.name);
219 tmp_share.param_names = talloc_move(mem_ctx, &tmp_share.param_names);
220 tmp_share.param_values = talloc_move(mem_ctx, &tmp_share.param_values);
225 dcerpc_winreg_CloseKey(b, frame, &child_hnd, &_werr);
231 static int rpc_conf_print_shares(uint32_t num_shares,
232 struct smbconf_service *shares)
235 uint32_t share_count, param_count;
236 const char *indent = "\t";
238 if (num_shares == 0) {
242 for (share_count = 0; share_count < num_shares; share_count++) {
244 if (shares[share_count].name != NULL) {
245 d_printf("[%s]\n", shares[share_count].name);
248 for (param_count = 0;
249 param_count < shares[share_count].num_params;
252 d_printf("%s%s = %s\n",
254 shares[share_count].param_names[param_count],
255 shares[share_count].param_values[param_count]);
263 static NTSTATUS rpc_conf_open_conf(TALLOC_CTX *mem_ctx,
264 struct dcerpc_binding_handle *b,
265 uint32_t access_mask,
266 struct policy_handle *hive_hnd,
267 struct policy_handle *key_hnd,
270 TALLOC_CTX *frame = talloc_stackframe();
271 NTSTATUS status = NT_STATUS_OK;
272 WERROR result = WERR_OK;
274 struct policy_handle tmp_hive_hnd, tmp_key_hnd;
275 struct winreg_String key;
279 status = dcerpc_winreg_OpenHKLM(b, frame, NULL,
280 access_mask, &tmp_hive_hnd, &result);
283 * print no error messages if it is a read only open
284 * and key does not exist
285 * error still gets returned
288 if (access_mask == REG_KEY_READ &&
289 W_ERROR_EQUAL(result, WERR_BADFILE))
294 if (!(NT_STATUS_IS_OK(status))) {
295 d_fprintf(stderr, _("Failed to open hive: %s\n"),
299 if (!W_ERROR_IS_OK(result)) {
300 d_fprintf(stderr, _("Failed to open hive: %s\n"),
306 status = dcerpc_winreg_OpenKey(b, frame, &tmp_hive_hnd, key, 0,
307 access_mask, &tmp_key_hnd, &result);
310 * print no error messages if it is a read only open
311 * and key does not exist
312 * error still gets returned
315 if (access_mask == REG_KEY_READ &&
316 W_ERROR_EQUAL(result, WERR_BADFILE))
321 if (!(NT_STATUS_IS_OK(status))) {
322 d_fprintf(stderr, _("Failed to open smbconf key: %s\n"),
324 dcerpc_winreg_CloseKey(b, frame, &tmp_hive_hnd, &_werr);
327 if (!(W_ERROR_IS_OK(result))) {
328 d_fprintf(stderr, _("Failed to open smbconf key: %s\n"),
330 dcerpc_winreg_CloseKey(b, frame, &tmp_hive_hnd, &_werr);
334 *hive_hnd = tmp_hive_hnd;
335 *key_hnd = tmp_key_hnd;
344 static NTSTATUS rpc_conf_list_internal(struct net_context *c,
345 const struct dom_sid *domain_sid,
346 const char *domain_name,
347 struct cli_state *cli,
348 struct rpc_pipe_client *pipe_hnd,
354 TALLOC_CTX *frame = talloc_stackframe();
355 NTSTATUS status = NT_STATUS_OK;
356 WERROR werr = WERR_OK;
358 struct winreg_String key;
360 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
363 struct policy_handle hive_hnd, key_hnd;
364 uint32_t num_subkeys;
366 struct smbconf_service *shares;
367 const char **subkeys = NULL;
371 ZERO_STRUCT(hive_hnd);
372 ZERO_STRUCT(key_hnd);
375 if (argc != 0 || c->display_usage) {
376 rpc_conf_list_usage(c, argc, argv);
377 status = NT_STATUS_INVALID_PARAMETER;
381 status = dcerpc_winreg_OpenHKLM(b, frame, NULL,
382 REG_KEY_READ, &hive_hnd, &werr);
384 if (!(NT_STATUS_IS_OK(status))) {
385 d_fprintf(stderr, _("Failed to open hive: %s\n"),
389 if (!W_ERROR_IS_OK(werr)) {
390 d_fprintf(stderr, _("Failed to open hive: %s\n"),
396 status = dcerpc_winreg_OpenKey(b, frame, &hive_hnd, key, 0,
397 REG_KEY_READ, &key_hnd, &werr);
399 if (!(NT_STATUS_IS_OK(status))) {
400 d_fprintf(stderr, _("Failed to open smbconf key: %s\n"),
402 dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
405 if (!(W_ERROR_IS_OK(werr))) {
406 d_fprintf(stderr, _("Failed to open smbconf key: %s\n"),
408 dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
412 status = dcerpc_winreg_enum_keys(frame,
419 if (!(NT_STATUS_IS_OK(status))) {
420 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
425 if (!(W_ERROR_IS_OK(werr))) {
426 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
431 if (num_subkeys == 0) {
432 dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
433 dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
438 /* get info from each subkey */
439 shares = talloc_zero_array(frame, struct smbconf_service, num_subkeys);
440 if (shares == NULL) {
442 d_fprintf(stderr, _("Failed to create shares: %s\n"),
448 for (i = 0; i < num_subkeys; i++) {
449 /* get each share and place it in the shares array */
450 status = rpc_conf_get_share(frame,
456 if (!(NT_STATUS_IS_OK(status))) {
459 if (!(W_ERROR_IS_OK(werr))) {
464 /* print the shares array */
465 rpc_conf_print_shares(num_subkeys, shares);
468 if (!(W_ERROR_IS_OK(werr))) {
469 status = werror_to_ntstatus(werr);
472 dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
473 dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
481 static int rpc_conf_list(struct net_context *c, int argc,
484 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
485 rpc_conf_list_internal, argc, argv );
489 int net_rpc_conf(struct net_context *c, int argc,
492 struct functable func_table[] = {
497 N_("Dump the complete remote configuration in smb.conf like "
499 N_("net rpc conf list\n"
500 " Dump the complete remote configuration in smb.conf "
504 {NULL, NULL, 0, NULL, NULL}
507 return net_run_function(c, argc, argv, "net rpc conf", func_table);