2 * Samba Unix/Linux SMB client library
3 * Distributed SMB/CIFS Server Management Utility
4 * Local configuration interface
5 * Copyright (C) Michael Adam 2007-2008
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 as made available
23 * by the libsmbconf interface (source/lib/smbconf/smbconf.c).
25 * This currently supports local interaction with the configuration
26 * stored in the registry. But other backends and remote access via
27 * rpc might get implemented in the future.
31 #include "utils/net.h"
33 /**********************************************************************
37 **********************************************************************/
39 static int net_conf_list_usage(int argc
, const char **argv
)
41 d_printf("USAGE: net conf list\n");
45 static int net_conf_import_usage(int argc
, const char**argv
)
47 d_printf("USAGE: net conf import [--test|-T] <filename> "
49 "\t[--test|-T] testmode - do not act, just print "
50 "what would be done\n"
51 "\t<servicename> only import service <servicename>, "
56 static int net_conf_listshares_usage(int argc
, const char **argv
)
58 d_printf("USAGE: net conf listshares\n");
62 static int net_conf_drop_usage(int argc
, const char **argv
)
64 d_printf("USAGE: net conf drop\n");
68 static int net_conf_showshare_usage(int argc
, const char **argv
)
70 d_printf("USAGE: net conf showshare <sharename>\n");
74 static int net_conf_addshare_usage(int argc
, const char **argv
)
76 d_printf("USAGE: net conf addshare <sharename> <path> "
77 "[writeable={y|N} [guest_ok={y|N} [<comment>]]\n"
78 "\t<sharename> the new share name.\n"
79 "\t<path> the path on the filesystem to export.\n"
80 "\twriteable={y|N} set \"writeable to \"yes\" or "
81 "\"no\" (default) on this share.\n"
82 "\tguest_ok={y|N} set \"guest ok\" to \"yes\" or "
83 "\"no\" (default) on this share.\n"
84 "\t<comment> optional comment for the new share.\n");
88 static int net_conf_delshare_usage(int argc
, const char **argv
)
90 d_printf("USAGE: net conf delshare <sharename>\n");
94 static int net_conf_setparm_usage(int argc
, const char **argv
)
96 d_printf("USAGE: net conf setparm <section> <param> <value>\n");
100 static int net_conf_getparm_usage(int argc
, const char **argv
)
102 d_printf("USAGE: net conf getparm <section> <param>\n");
106 static int net_conf_delparm_usage(int argc
, const char **argv
)
108 d_printf("USAGE: net conf delparm <section> <param>\n");
113 /**********************************************************************
117 **********************************************************************/
120 * This functions process a service previously loaded with libsmbconf.
122 static WERROR
import_process_service(struct smbconf_ctx
*conf_ctx
,
123 const char *servicename
,
124 const uint32_t num_params
,
125 const char **param_names
,
126 const char **param_values
)
129 WERROR werr
= WERR_OK
;
130 uint32_t num_includes
= 0;
131 char **includes
= NULL
;
132 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
135 d_printf("[%s]\n", servicename
);
137 if (smbconf_share_exists(conf_ctx
, servicename
)) {
138 werr
= smbconf_delete_share(conf_ctx
, servicename
);
139 if (!W_ERROR_IS_OK(werr
)) {
143 werr
= smbconf_create_share(conf_ctx
, servicename
);
144 if (!W_ERROR_IS_OK(werr
)) {
149 for (idx
= 0; idx
< num_params
; idx
++) {
151 d_printf("\t%s = %s\n", param_names
[idx
],
154 if (strequal(param_names
[idx
], "include")) {
155 includes
= TALLOC_REALLOC_ARRAY(mem_ctx
,
159 if (includes
== NULL
) {
163 includes
[num_includes
] =
164 talloc_strdup(includes
,
166 if (includes
[num_includes
] == NULL
) {
172 werr
= smbconf_set_parameter(conf_ctx
,
176 if (!W_ERROR_IS_OK(werr
)) {
184 werr
= smbconf_set_includes(conf_ctx
, servicename
, num_includes
,
185 (const char **)includes
);
189 TALLOC_FREE(mem_ctx
);
194 /**********************************************************************
196 * the main conf functions
198 **********************************************************************/
200 static int net_conf_list(struct smbconf_ctx
*conf_ctx
,
201 int argc
, const char **argv
)
203 WERROR werr
= WERR_OK
;
208 uint32_t *num_params
;
210 char ***param_values
;
211 uint32_t share_count
, param_count
;
213 mem_ctx
= talloc_stackframe();
216 net_conf_list_usage(argc
, argv
);
220 werr
= smbconf_get_config(conf_ctx
, mem_ctx
, &num_shares
, &share_names
,
221 &num_params
, ¶m_names
, ¶m_values
);
222 if (!W_ERROR_IS_OK(werr
)) {
223 d_fprintf(stderr
, "Error getting config: %s\n",
228 for (share_count
= 0; share_count
< num_shares
; share_count
++) {
229 d_printf("[%s]\n", share_names
[share_count
]);
230 for (param_count
= 0; param_count
< num_params
[share_count
];
233 d_printf("\t%s = %s\n",
234 param_names
[share_count
][param_count
],
235 param_values
[share_count
][param_count
]);
243 TALLOC_FREE(mem_ctx
);
247 static int net_conf_import(struct smbconf_ctx
*conf_ctx
,
248 int argc
, const char **argv
)
251 const char *filename
= NULL
;
252 const char *servicename
= NULL
;
254 struct smbconf_ctx
*txt_ctx
;
257 mem_ctx
= talloc_stackframe();
262 net_conf_import_usage(argc
, argv
);
265 servicename
= argv
[1];
271 DEBUG(3,("net_conf_import: reading configuration from file %s.\n",
274 werr
= smbconf_init_txt_simple(mem_ctx
, &txt_ctx
, filename
, true);
275 if (!W_ERROR_IS_OK(werr
)) {
280 d_printf("\nTEST MODE - "
281 "would import the following configuration:\n\n");
284 if (servicename
!= NULL
) {
285 char **param_names
, **param_values
;
288 werr
= smbconf_get_share(txt_ctx
, mem_ctx
,
293 if (!W_ERROR_IS_OK(werr
)) {
296 werr
= import_process_service(conf_ctx
,
299 (const char **)param_names
,
300 (const char **)param_values
);
301 if (!W_ERROR_IS_OK(werr
)) {
305 char **share_names
, ***param_names
, ***param_values
;
306 uint32_t num_shares
, *num_params
, sidx
;
308 werr
= smbconf_get_config(txt_ctx
, mem_ctx
,
314 if (!W_ERROR_IS_OK(werr
)) {
317 werr
= smbconf_drop(conf_ctx
);
318 if (!W_ERROR_IS_OK(werr
)) {
321 for (sidx
= 0; sidx
< num_shares
; sidx
++) {
322 werr
= import_process_service(conf_ctx
,
325 (const char **)param_names
[sidx
],
326 (const char **)param_values
[sidx
]);
327 if (!W_ERROR_IS_OK(werr
)) {
336 TALLOC_FREE(mem_ctx
);
340 static int net_conf_listshares(struct smbconf_ctx
*conf_ctx
,
341 int argc
, const char **argv
)
343 WERROR werr
= WERR_OK
;
345 uint32_t count
, num_shares
= 0;
346 char **share_names
= NULL
;
349 mem_ctx
= talloc_stackframe();
352 net_conf_listshares_usage(argc
, argv
);
356 werr
= smbconf_get_share_names(conf_ctx
, mem_ctx
, &num_shares
,
358 if (!W_ERROR_IS_OK(werr
)) {
362 for (count
= 0; count
< num_shares
; count
++)
364 d_printf("%s\n", share_names
[count
]);
370 TALLOC_FREE(mem_ctx
);
374 static int net_conf_drop(struct smbconf_ctx
*conf_ctx
,
375 int argc
, const char **argv
)
381 net_conf_drop_usage(argc
, argv
);
385 werr
= smbconf_drop(conf_ctx
);
386 if (!W_ERROR_IS_OK(werr
)) {
387 d_fprintf(stderr
, "Error deleting configuration: %s\n",
398 static int net_conf_showshare(struct smbconf_ctx
*conf_ctx
,
399 int argc
, const char **argv
)
402 WERROR werr
= WERR_OK
;
403 const char *sharename
= NULL
;
410 mem_ctx
= talloc_stackframe();
413 net_conf_showshare_usage(argc
, argv
);
419 werr
= smbconf_get_share(conf_ctx
, mem_ctx
, sharename
, &num_params
,
420 ¶m_names
, ¶m_values
);
421 if (!W_ERROR_IS_OK(werr
)) {
422 d_printf("error getting share parameters: %s\n",
427 d_printf("[%s]\n", sharename
);
429 for (count
= 0; count
< num_params
; count
++) {
430 d_printf("\t%s = %s\n", param_names
[count
],
431 param_values
[count
]);
437 TALLOC_FREE(mem_ctx
);
442 * Add a share, with a couple of standard parameters, partly optional.
444 * This is a high level utility function of the net conf utility,
445 * not a direct frontend to the smbconf API.
447 static int net_conf_addshare(struct smbconf_ctx
*conf_ctx
,
448 int argc
, const char **argv
)
451 WERROR werr
= WERR_OK
;
452 char *sharename
= NULL
;
453 const char *path
= NULL
;
454 const char *comment
= NULL
;
455 const char *guest_ok
= "no";
456 const char *writeable
= "no";
457 SMB_STRUCT_STAT sbuf
;
463 net_conf_addshare_usage(argc
, argv
);
468 if (!strnequal(argv
[3], "guest_ok=", 9)) {
469 net_conf_addshare_usage(argc
, argv
);
472 switch (argv
[3][9]) {
482 net_conf_addshare_usage(argc
, argv
);
486 if (!strnequal(argv
[2], "writeable=", 10)) {
487 net_conf_addshare_usage(argc
, argv
);
490 switch (argv
[2][10]) {
500 net_conf_addshare_usage(argc
, argv
);
505 sharename
= strdup_lower(argv
[0]);
513 /* validate share name */
515 if (!validate_net_name(sharename
, INVALID_SHARENAME_CHARS
,
518 d_fprintf(stderr
, "ERROR: share name %s contains "
519 "invalid characters (any of %s)\n",
520 sharename
, INVALID_SHARENAME_CHARS
);
524 if (getpwnam(sharename
)) {
525 d_fprintf(stderr
, "ERROR: share name %s is already a valid "
526 "system user name.\n", sharename
);
530 if (strequal(sharename
, GLOBAL_NAME
)) {
532 "ERROR: 'global' is not a valid share name.\n");
536 if (smbconf_share_exists(conf_ctx
, sharename
)) {
537 d_fprintf(stderr
, "ERROR: share %s already exists.\n",
544 if (path
[0] != '/') {
546 "Error: path '%s' is not an absolute path.\n",
551 if (sys_stat(path
, &sbuf
) != 0) {
553 "ERROR: cannot stat path '%s' to ensure "
554 "this is a directory.\n"
556 path
, strerror(errno
));
560 if (!S_ISDIR(sbuf
.st_mode
)) {
562 "ERROR: path '%s' is not a directory.\n",
571 werr
= smbconf_create_share(conf_ctx
, sharename
);
572 if (!W_ERROR_IS_OK(werr
)) {
573 d_fprintf(stderr
, "Error creating share %s: %s\n",
574 sharename
, dos_errstr(werr
));
579 * fill the share with parameters
582 werr
= smbconf_set_parameter(conf_ctx
, sharename
, "path", path
);
583 if (!W_ERROR_IS_OK(werr
)) {
584 d_fprintf(stderr
, "Error setting parameter %s: %s\n",
585 "path", dos_errstr(werr
));
589 if (comment
!= NULL
) {
590 werr
= smbconf_set_parameter(conf_ctx
, sharename
, "comment",
592 if (!W_ERROR_IS_OK(werr
)) {
593 d_fprintf(stderr
, "Error setting parameter %s: %s\n",
594 "comment", dos_errstr(werr
));
599 werr
= smbconf_set_parameter(conf_ctx
, sharename
, "guest ok", guest_ok
);
600 if (!W_ERROR_IS_OK(werr
)) {
601 d_fprintf(stderr
, "Error setting parameter %s: %s\n",
602 "'guest ok'", dos_errstr(werr
));
606 werr
= smbconf_set_parameter(conf_ctx
, sharename
, "writeable",
608 if (!W_ERROR_IS_OK(werr
)) {
609 d_fprintf(stderr
, "Error setting parameter %s: %s\n",
610 "writeable", dos_errstr(werr
));
617 SAFE_FREE(sharename
);
621 static int net_conf_delshare(struct smbconf_ctx
*conf_ctx
,
622 int argc
, const char **argv
)
625 const char *sharename
= NULL
;
626 WERROR werr
= WERR_OK
;
629 net_conf_delshare_usage(argc
, argv
);
634 werr
= smbconf_delete_share(conf_ctx
, sharename
);
635 if (!W_ERROR_IS_OK(werr
)) {
636 d_fprintf(stderr
, "Error deleting share %s: %s\n",
637 sharename
, dos_errstr(werr
));
646 static int net_conf_setparm(struct smbconf_ctx
*conf_ctx
,
647 int argc
, const char **argv
)
650 WERROR werr
= WERR_OK
;
651 char *service
= NULL
;
653 const char *value_str
= NULL
;
656 net_conf_setparm_usage(argc
, argv
);
659 service
= strdup_lower(argv
[0]);
660 param
= strdup_lower(argv
[1]);
663 if (!smbconf_share_exists(conf_ctx
, service
)) {
664 werr
= smbconf_create_share(conf_ctx
, service
);
665 if (!W_ERROR_IS_OK(werr
)) {
666 d_fprintf(stderr
, "Error creating share '%s': %s\n",
667 service
, dos_errstr(werr
));
672 werr
= smbconf_set_parameter(conf_ctx
, service
, param
, value_str
);
674 if (!W_ERROR_IS_OK(werr
)) {
675 d_fprintf(stderr
, "Error setting value '%s': %s\n",
676 param
, dos_errstr(werr
));
688 static int net_conf_getparm(struct smbconf_ctx
*conf_ctx
,
689 int argc
, const char **argv
)
692 WERROR werr
= WERR_OK
;
693 char *service
= NULL
;
698 mem_ctx
= talloc_stackframe();
701 net_conf_getparm_usage(argc
, argv
);
704 service
= strdup_lower(argv
[0]);
705 param
= strdup_lower(argv
[1]);
707 werr
= smbconf_get_parameter(conf_ctx
, mem_ctx
, service
, param
, &valstr
);
709 if (W_ERROR_EQUAL(werr
, WERR_NO_SUCH_SERVICE
)) {
711 "Error: given service '%s' does not exist.\n",
714 } else if (W_ERROR_EQUAL(werr
, WERR_INVALID_PARAM
)) {
716 "Error: given parameter '%s' is not set.\n",
719 } else if (!W_ERROR_IS_OK(werr
)) {
720 d_fprintf(stderr
, "Error getting value '%s': %s.\n",
721 param
, dos_errstr(werr
));
725 d_printf("%s\n", valstr
);
731 TALLOC_FREE(mem_ctx
);
735 static int net_conf_delparm(struct smbconf_ctx
*conf_ctx
,
736 int argc
, const char **argv
)
739 WERROR werr
= WERR_OK
;
740 char *service
= NULL
;
744 net_conf_delparm_usage(argc
, argv
);
747 service
= strdup_lower(argv
[0]);
748 param
= strdup_lower(argv
[1]);
750 werr
= smbconf_delete_parameter(conf_ctx
, service
, param
);
752 if (W_ERROR_EQUAL(werr
, WERR_NO_SUCH_SERVICE
)) {
754 "Error: given service '%s' does not exist.\n",
757 } else if (W_ERROR_EQUAL(werr
, WERR_INVALID_PARAM
)) {
759 "Error: given parameter '%s' is not set.\n",
762 } else if (!W_ERROR_IS_OK(werr
)) {
763 d_fprintf(stderr
, "Error deleting value '%s': %s.\n",
764 param
, dos_errstr(werr
));
777 /**********************************************************************
779 * Wrapper and net_conf_run_function mechanism.
781 **********************************************************************/
784 * Wrapper function to call the main conf functions.
785 * The wrapper calls handles opening and closing of the
788 static int net_conf_wrap_function(int (*fn
)(struct smbconf_ctx
*,
790 int argc
, const char **argv
)
793 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
794 struct smbconf_ctx
*conf_ctx
;
797 werr
= smbconf_init_reg(mem_ctx
, &conf_ctx
, NULL
);
799 if (!W_ERROR_IS_OK(werr
)) {
803 ret
= fn(conf_ctx
, argc
, argv
);
805 smbconf_shutdown(conf_ctx
);
811 * We need a functable struct of our own, because the
812 * functions are called through a wrapper that handles
813 * the opening and closing of the configuration, and so on.
815 struct conf_functable
{
816 const char *funcname
;
817 int (*fn
)(struct smbconf_ctx
*ctx
, int argc
, const char **argv
);
818 const char *helptext
;
822 * This imitates net_run_function2 but calls the main functions
823 * through the wrapper net_conf_wrap_function().
825 static int net_conf_run_function(int argc
, const char **argv
,
827 struct conf_functable
*table
)
832 for (i
=0; table
[i
].funcname
; i
++) {
833 if (StrCaseCmp(argv
[0], table
[i
].funcname
) == 0)
834 return net_conf_wrap_function(table
[i
].fn
,
840 for (i
=0; table
[i
].funcname
; i
++) {
841 d_printf("%s %-15s %s\n", whoami
, table
[i
].funcname
,
849 * Entry-point for all the CONF functions.
852 int net_conf(int argc
, const char **argv
)
855 struct conf_functable func_table
[] = {
856 {"list", net_conf_list
,
857 "Dump the complete configuration in smb.conf like format."},
858 {"import", net_conf_import
,
859 "Import configuration from file in smb.conf format."},
860 {"listshares", net_conf_listshares
,
861 "List the share names."},
862 {"drop", net_conf_drop
,
863 "Delete the complete configuration."},
864 {"showshare", net_conf_showshare
,
865 "Show the definition of a share."},
866 {"addshare", net_conf_addshare
,
867 "Create a new share."},
868 {"delshare", net_conf_delshare
,
870 {"setparm", net_conf_setparm
,
871 "Store a parameter."},
872 {"getparm", net_conf_getparm
,
873 "Retrieve the value of a parameter."},
874 {"delparm", net_conf_delparm
,
875 "Delete a parameter."},
879 ret
= net_conf_run_function(argc
, argv
, "net conf", func_table
);