root/source3/utils/net_conf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. net_conf_list_usage
  2. net_conf_import_usage
  3. net_conf_listshares_usage
  4. net_conf_drop_usage
  5. net_conf_showshare_usage
  6. net_conf_addshare_usage
  7. net_conf_delshare_usage
  8. net_conf_setparm_usage
  9. net_conf_getparm_usage
  10. net_conf_delparm_usage
  11. net_conf_getincludes_usage
  12. net_conf_setincludes_usage
  13. net_conf_delincludes_usage
  14. import_process_service
  15. net_conf_list
  16. net_conf_import
  17. net_conf_listshares
  18. net_conf_drop
  19. net_conf_showshare
  20. net_conf_addshare
  21. net_conf_delshare
  22. net_conf_setparm
  23. net_conf_getparm
  24. net_conf_delparm
  25. net_conf_getincludes
  26. net_conf_setincludes
  27. net_conf_delincludes
  28. net_conf_wrap_function
  29. net_conf_run_function
  30. net_conf

   1 /*
   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
   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 /*
  22  * This is an interface to Samba's configuration as made available
  23  * by the libsmbconf interface (source/lib/smbconf/smbconf.c).
  24  *
  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.
  28  */
  29 
  30 #include "includes.h"
  31 #include "utils/net.h"
  32 
  33 /**********************************************************************
  34  *
  35  * usage functions
  36  *
  37  **********************************************************************/
  38 
  39 static int net_conf_list_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
  40                                const char **argv)
  41 {
  42         d_printf("USAGE: net conf list\n");
  43         return -1;
  44 }
  45 
  46 static int net_conf_import_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
  47                                  const char**argv)
  48 {
  49         d_printf("USAGE: net conf import [--test|-T] <filename> "
  50                  "[<servicename>]\n"
  51                  "\t[--test|-T]    testmode - do not act, just print "
  52                         "what would be done\n"
  53                  "\t<servicename>  only import service <servicename>, "
  54                         "ignore the rest\n");
  55         return -1;
  56 }
  57 
  58 static int net_conf_listshares_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
  59                                      const char **argv)
  60 {
  61         d_printf("USAGE: net conf listshares\n");
  62         return -1;
  63 }
  64 
  65 static int net_conf_drop_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
  66                                const char **argv)
  67 {
  68         d_printf("USAGE: net conf drop\n");
  69         return -1;
  70 }
  71 
  72 static int net_conf_showshare_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
  73                                     const char **argv)
  74 {
  75         d_printf("USAGE: net conf showshare <sharename>\n");
  76         return -1;
  77 }
  78 
  79 static int net_conf_addshare_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
  80                                    const char **argv)
  81 {
  82         d_printf("USAGE: net conf addshare <sharename> <path> "
  83                  "[writeable={y|N} [guest_ok={y|N} [<comment>]]\n"
  84                  "\t<sharename>      the new share name.\n"
  85                  "\t<path>           the path on the filesystem to export.\n"
  86                  "\twriteable={y|N}  set \"writeable to \"yes\" or "
  87                  "\"no\" (default) on this share.\n"
  88                  "\tguest_ok={y|N}   set \"guest ok\" to \"yes\" or "
  89                  "\"no\" (default)   on this share.\n"
  90                  "\t<comment>        optional comment for the new share.\n");
  91         return -1;
  92 }
  93 
  94 static int net_conf_delshare_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
  95                                    const char **argv)
  96 {
  97         d_printf("USAGE: net conf delshare <sharename>\n");
  98         return -1;
  99 }
 100 
 101 static int net_conf_setparm_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
 102                                   const char **argv)
 103 {
 104         d_printf("USAGE: net conf setparm <section> <param> <value>\n");
 105         return -1;
 106 }
 107 
 108 static int net_conf_getparm_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
 109                                   const char **argv)
 110 {
 111         d_printf("USAGE: net conf getparm <section> <param>\n");
 112         return -1;
 113 }
 114 
 115 static int net_conf_delparm_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
 116                                   const char **argv)
 117 {
 118         d_printf("USAGE: net conf delparm <section> <param>\n");
 119         return -1;
 120 }
 121 
 122 static int net_conf_getincludes_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
 123                                       const char **argv)
 124 {
 125         d_printf("USAGE: net conf getincludes <section>\n");
 126         return -1;
 127 }
 128 
 129 static int net_conf_setincludes_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
 130                                       const char **argv)
 131 {
 132         d_printf("USAGE: net conf setincludes <section> [<filename>]*\n");
 133         return -1;
 134 }
 135 
 136 static int net_conf_delincludes_usage(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
 137                                       const char **argv)
 138 {
 139         d_printf("USAGE: net conf delincludes <section>\n");
 140         return -1;
 141 }
 142 
 143 
 144 /**********************************************************************
 145  *
 146  * Helper functions
 147  *
 148  **********************************************************************/
 149 
 150 /**
 151  * This functions process a service previously loaded with libsmbconf.
 152  */
 153 static WERROR import_process_service(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 154                                      struct smbconf_ctx *conf_ctx,
 155                                      struct smbconf_service *service)
 156 {
 157         uint32_t idx;
 158         WERROR werr = WERR_OK;
 159         uint32_t num_includes = 0;
 160         char **includes = NULL;
 161         TALLOC_CTX *mem_ctx = talloc_stackframe();
 162 
 163         if (c->opt_testmode) {
 164                 const char *indent = "";
 165                 if (service->name != NULL) {
 166                         d_printf("[%s]\n", service->name);
 167                         indent = "\t";
 168                 }
 169                 for (idx = 0; idx < service->num_params; idx++) {
 170                         d_printf("%s%s = %s\n", indent,
 171                                  service->param_names[idx],
 172                                  service->param_values[idx]);
 173                 }
 174                 d_printf("\n");
 175                 goto done;
 176         }
 177 
 178         if (smbconf_share_exists(conf_ctx, service->name)) {
 179                 werr = smbconf_delete_share(conf_ctx, service->name);
 180                 if (!W_ERROR_IS_OK(werr)) {
 181                         goto done;
 182                 }
 183         }
 184         werr = smbconf_create_share(conf_ctx, service->name);
 185         if (!W_ERROR_IS_OK(werr)) {
 186                 goto done;
 187         }
 188 
 189         for (idx = 0; idx < service->num_params; idx ++) {
 190                 if (strequal(service->param_names[idx], "include")) {
 191                         includes = TALLOC_REALLOC_ARRAY(mem_ctx,
 192                                                         includes,
 193                                                         char *,
 194                                                         num_includes+1);
 195                         if (includes == NULL) {
 196                                 werr = WERR_NOMEM;
 197                                 goto done;
 198                         }
 199                         includes[num_includes] = talloc_strdup(includes,
 200                                                 service->param_values[idx]);
 201                         if (includes[num_includes] == NULL) {
 202                                 werr = WERR_NOMEM;
 203                                 goto done;
 204                         }
 205                         num_includes++;
 206                 } else {
 207                         werr = smbconf_set_parameter(conf_ctx,
 208                                                      service->name,
 209                                                      service->param_names[idx],
 210                                                      service->param_values[idx]);
 211                         if (!W_ERROR_IS_OK(werr)) {
 212                                 goto done;
 213                         }
 214                 }
 215         }
 216 
 217         werr = smbconf_set_includes(conf_ctx, service->name, num_includes,
 218                                     (const char **)includes);
 219 
 220 done:
 221         TALLOC_FREE(mem_ctx);
 222         return werr;
 223 }
 224 
 225 
 226 /**********************************************************************
 227  *
 228  * the main conf functions
 229  *
 230  **********************************************************************/
 231 
 232 static int net_conf_list(struct net_context *c, struct smbconf_ctx *conf_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 233                          int argc, const char **argv)
 234 {
 235         WERROR werr = WERR_OK;
 236         int ret = -1;
 237         TALLOC_CTX *mem_ctx;
 238         uint32_t num_shares;
 239         uint32_t share_count, param_count;
 240         struct smbconf_service **shares = NULL;
 241 
 242         mem_ctx = talloc_stackframe();
 243 
 244         if (argc != 0 || c->display_usage) {
 245                 net_conf_list_usage(c, argc, argv);
 246                 goto done;
 247         }
 248 
 249         werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &shares);
 250         if (!W_ERROR_IS_OK(werr)) {
 251                 d_fprintf(stderr, "Error getting config: %s\n",
 252                           win_errstr(werr));
 253                 goto done;
 254         }
 255 
 256         for (share_count = 0; share_count < num_shares; share_count++) {
 257                 const char *indent = "";
 258                 if (shares[share_count]->name != NULL) {
 259                         d_printf("[%s]\n", shares[share_count]->name);
 260                         indent = "\t";
 261                 }
 262                 for (param_count = 0;
 263                      param_count < shares[share_count]->num_params;
 264                      param_count++)
 265                 {
 266                         d_printf("%s%s = %s\n",
 267                                  indent,
 268                                  shares[share_count]->param_names[param_count],
 269                                  shares[share_count]->param_values[param_count]);
 270                 }
 271                 d_printf("\n");
 272         }
 273 
 274         ret = 0;
 275 
 276 done:
 277         TALLOC_FREE(mem_ctx);
 278         return ret;
 279 }
 280 
 281 static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 282                            int argc, const char **argv)
 283 {
 284         int ret = -1;
 285         const char *filename = NULL;
 286         const char *servicename = NULL;
 287         char *conf_source = NULL;
 288         TALLOC_CTX *mem_ctx;
 289         struct smbconf_ctx *txt_ctx;
 290         WERROR werr;
 291 
 292         if (c->display_usage)
 293                 return net_conf_import_usage(c, argc, argv);
 294 
 295         mem_ctx = talloc_stackframe();
 296 
 297         switch (argc) {
 298                 case 0:
 299                 default:
 300                         net_conf_import_usage(c, argc, argv);
 301                         goto done;
 302                 case 2:
 303                         servicename = talloc_strdup(mem_ctx, argv[1]);
 304                         if (servicename == NULL) {
 305                                 d_printf("error: out of memory!\n");
 306                                 goto done;
 307                         }
 308                 case 1:
 309                         filename = argv[0];
 310                         break;
 311         }
 312 
 313         DEBUG(3,("net_conf_import: reading configuration from file %s.\n",
 314                 filename));
 315 
 316         conf_source = talloc_asprintf(mem_ctx, "file:%s", filename);
 317         if (conf_source == NULL) {
 318                 d_printf("error: out of memory!\n");
 319                 goto done;
 320         }
 321 
 322         werr = smbconf_init(mem_ctx, &txt_ctx, conf_source);
 323         if (!W_ERROR_IS_OK(werr)) {
 324                 d_printf("error loading file '%s': %s\n", filename,
 325                          win_errstr(werr));
 326                 goto done;
 327         }
 328 
 329         if (c->opt_testmode) {
 330                 d_printf("\nTEST MODE - "
 331                          "would import the following configuration:\n\n");
 332         }
 333 
 334         if (servicename != NULL) {
 335                 struct smbconf_service *service = NULL;
 336 
 337                 werr = smbconf_get_share(txt_ctx, mem_ctx,
 338                                          servicename,
 339                                          &service);
 340                 if (!W_ERROR_IS_OK(werr)) {
 341                         goto cancel;
 342                 }
 343 
 344                 werr = smbconf_transaction_start(conf_ctx);
 345                 if (!W_ERROR_IS_OK(werr)) {
 346                         d_printf("error starting transaction: %s\n",
 347                                  win_errstr(werr));
 348                         goto done;
 349                 }
 350 
 351                 werr = import_process_service(c, conf_ctx, service);
 352                 if (!W_ERROR_IS_OK(werr)) {
 353                         goto cancel;
 354                 }
 355         } else {
 356                 struct smbconf_service **services = NULL;
 357                 uint32_t num_shares, sidx;
 358 
 359                 werr = smbconf_get_config(txt_ctx, mem_ctx,
 360                                           &num_shares,
 361                                           &services);
 362                 if (!W_ERROR_IS_OK(werr)) {
 363                         goto cancel;
 364                 }
 365                 if (!c->opt_testmode) {
 366                         werr = smbconf_drop(conf_ctx);
 367                         if (!W_ERROR_IS_OK(werr)) {
 368                                 goto cancel;
 369                         }
 370                 }
 371 
 372                 /*
 373                  * Wrap the importing of shares into a transaction,
 374                  * but only 100 at a time, in order to serve memory.
 375                  * The allocated memory accumulates across the actions
 376                  * within the transaction, and for me, some 1500
 377                  * imported shares, the MAX_TALLOC_SIZE of 256 MB
 378                  * was exceeded.
 379                  */
 380                 werr = smbconf_transaction_start(conf_ctx);
 381                 if (!W_ERROR_IS_OK(werr)) {
 382                         d_printf("error starting transaction: %s\n",
 383                                  win_errstr(werr));
 384                         goto done;
 385                 }
 386 
 387                 for (sidx = 0; sidx < num_shares; sidx++) {
 388                         werr = import_process_service(c, conf_ctx,
 389                                                       services[sidx]);
 390                         if (!W_ERROR_IS_OK(werr)) {
 391                                 goto cancel;
 392                         }
 393 
 394                         if (sidx % 100) {
 395                                 continue;
 396                         }
 397 
 398                         werr = smbconf_transaction_commit(conf_ctx);
 399                         if (!W_ERROR_IS_OK(werr)) {
 400                                 d_printf("error committing transaction: %s\n",
 401                                          win_errstr(werr));
 402                                 goto done;
 403                         }
 404                         werr = smbconf_transaction_start(conf_ctx);
 405                         if (!W_ERROR_IS_OK(werr)) {
 406                                 d_printf("error starting transaction: %s\n",
 407                                          win_errstr(werr));
 408                                 goto done;
 409                         }
 410                 }
 411         }
 412 
 413         werr = smbconf_transaction_commit(conf_ctx);
 414         if (!W_ERROR_IS_OK(werr)) {
 415                 d_printf("error committing transaction: %s\n",
 416                          win_errstr(werr));
 417         } else {
 418                 ret = 0;
 419         }
 420 
 421         goto done;
 422 
 423 cancel:
 424         werr = smbconf_transaction_cancel(conf_ctx);
 425         if (!W_ERROR_IS_OK(werr)) {
 426                 d_printf("error cancelling transaction: %s\n",
 427                          win_errstr(werr));
 428         }
 429 
 430 done:
 431         TALLOC_FREE(mem_ctx);
 432         return ret;
 433 }
 434 
 435 static int net_conf_listshares(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 436                                struct smbconf_ctx *conf_ctx, int argc,
 437                                const char **argv)
 438 {
 439         WERROR werr = WERR_OK;
 440         int ret = -1;
 441         uint32_t count, num_shares = 0;
 442         char **share_names = NULL;
 443         TALLOC_CTX *mem_ctx;
 444 
 445         mem_ctx = talloc_stackframe();
 446 
 447         if (argc != 0 || c->display_usage) {
 448                 net_conf_listshares_usage(c, argc, argv);
 449                 goto done;
 450         }
 451 
 452         werr = smbconf_get_share_names(conf_ctx, mem_ctx, &num_shares,
 453                                        &share_names);
 454         if (!W_ERROR_IS_OK(werr)) {
 455                 goto done;
 456         }
 457 
 458         for (count = 0; count < num_shares; count++)
 459         {
 460                 d_printf("%s\n", share_names[count]);
 461         }
 462 
 463         ret = 0;
 464 
 465 done:
 466         TALLOC_FREE(mem_ctx);
 467         return ret;
 468 }
 469 
 470 static int net_conf_drop(struct net_context *c, struct smbconf_ctx *conf_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 471                          int argc, const char **argv)
 472 {
 473         int ret = -1;
 474         WERROR werr;
 475 
 476         if (argc != 0 || c->display_usage) {
 477                 net_conf_drop_usage(c, argc, argv);
 478                 goto done;
 479         }
 480 
 481         werr = smbconf_drop(conf_ctx);
 482         if (!W_ERROR_IS_OK(werr)) {
 483                 d_fprintf(stderr, "Error deleting configuration: %s\n",
 484                           win_errstr(werr));
 485                 goto done;
 486         }
 487 
 488         ret = 0;
 489 
 490 done:
 491         return ret;
 492 }
 493 
 494 static int net_conf_showshare(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 495                               struct smbconf_ctx *conf_ctx, int argc,
 496                               const char **argv)
 497 {
 498         int ret = -1;
 499         WERROR werr = WERR_OK;
 500         const char *sharename = NULL;
 501         TALLOC_CTX *mem_ctx;
 502         uint32_t count;
 503         struct smbconf_service *service = NULL;
 504 
 505         mem_ctx = talloc_stackframe();
 506 
 507         if (argc != 1 || c->display_usage) {
 508                 net_conf_showshare_usage(c, argc, argv);
 509                 goto done;
 510         }
 511 
 512         sharename = talloc_strdup(mem_ctx, argv[0]);
 513         if (sharename == NULL) {
 514                 d_printf("error: out of memory!\n");
 515                 goto done;
 516         }
 517 
 518         werr = smbconf_get_share(conf_ctx, mem_ctx, sharename, &service);
 519         if (!W_ERROR_IS_OK(werr)) {
 520                 d_printf("error getting share parameters: %s\n",
 521                          win_errstr(werr));
 522                 goto done;
 523         }
 524 
 525         d_printf("[%s]\n", service->name);
 526 
 527         for (count = 0; count < service->num_params; count++) {
 528                 d_printf("\t%s = %s\n", service->param_names[count],
 529                          service->param_values[count]);
 530         }
 531 
 532         ret = 0;
 533 
 534 done:
 535         TALLOC_FREE(mem_ctx);
 536         return ret;
 537 }
 538 
 539 /**
 540  * Add a share, with a couple of standard parameters, partly optional.
 541  *
 542  * This is a high level utility function of the net conf utility,
 543  * not a direct frontend to the smbconf API.
 544  */
 545 static int net_conf_addshare(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 546                              struct smbconf_ctx *conf_ctx, int argc,
 547                              const char **argv)
 548 {
 549         int ret = -1;
 550         WERROR werr = WERR_OK;
 551         char *sharename = NULL;
 552         const char *path = NULL;
 553         const char *comment = NULL;
 554         const char *guest_ok = "no";
 555         const char *writeable = "no";
 556         SMB_STRUCT_STAT sbuf;
 557         TALLOC_CTX *mem_ctx = talloc_stackframe();
 558 
 559         if (c->display_usage) {
 560                 net_conf_addshare_usage(c, argc, argv);
 561                 ret = 0;
 562                 goto done;
 563         }
 564 
 565         switch (argc) {
 566                 case 0:
 567                 case 1:
 568                 default:
 569                         net_conf_addshare_usage(c, argc, argv);
 570                         goto done;
 571                 case 5:
 572                         comment = argv[4];
 573                 case 4:
 574                         if (!strnequal(argv[3], "guest_ok=", 9)) {
 575                                 net_conf_addshare_usage(c, argc, argv);
 576                                 goto done;
 577                         }
 578                         switch (argv[3][9]) {
 579                                 case 'y':
 580                                 case 'Y':
 581                                         guest_ok = "yes";
 582                                         break;
 583                                 case 'n':
 584                                 case 'N':
 585                                         guest_ok = "no";
 586                                         break;
 587                                 default:
 588                                         net_conf_addshare_usage(c, argc, argv);
 589                                         goto done;
 590                         }
 591                 case 3:
 592                         if (!strnequal(argv[2], "writeable=", 10)) {
 593                                 net_conf_addshare_usage(c, argc, argv);
 594                                 goto done;
 595                         }
 596                         switch (argv[2][10]) {
 597                                 case 'y':
 598                                 case 'Y':
 599                                         writeable = "yes";
 600                                         break;
 601                                 case 'n':
 602                                 case 'N':
 603                                         writeable = "no";
 604                                         break;
 605                                 default:
 606                                         net_conf_addshare_usage(c, argc, argv);
 607                                         goto done;
 608                         }
 609                 case 2:
 610                         path = argv[1];
 611                         sharename = talloc_strdup(mem_ctx, argv[0]);
 612                         if (sharename == NULL) {
 613                                 d_printf("error: out of memory!\n");
 614                                 goto done;
 615                         }
 616 
 617                         break;
 618         }
 619 
 620         /*
 621          * validate arguments
 622          */
 623 
 624         /* validate share name */
 625 
 626         if (!validate_net_name(sharename, INVALID_SHARENAME_CHARS,
 627                                strlen(sharename)))
 628         {
 629                 d_fprintf(stderr, "ERROR: share name %s contains "
 630                         "invalid characters (any of %s)\n",
 631                         sharename, INVALID_SHARENAME_CHARS);
 632                 goto done;
 633         }
 634 
 635         if (strequal(sharename, GLOBAL_NAME)) {
 636                 d_fprintf(stderr,
 637                           "ERROR: 'global' is not a valid share name.\n");
 638                 goto done;
 639         }
 640 
 641         if (smbconf_share_exists(conf_ctx, sharename)) {
 642                 d_fprintf(stderr, "ERROR: share %s already exists.\n",
 643                           sharename);
 644                 goto done;
 645         }
 646 
 647         /* validate path */
 648 
 649         if (path[0] != '/') {
 650                 d_fprintf(stderr,
 651                           "Error: path '%s' is not an absolute path.\n",
 652                           path);
 653                 goto done;
 654         }
 655 
 656         if (sys_stat(path, &sbuf) != 0) {
 657                 d_fprintf(stderr,
 658                           "ERROR: cannot stat path '%s' to ensure "
 659                           "this is a directory.\n"
 660                           "Error was '%s'.\n",
 661                           path, strerror(errno));
 662                 goto done;
 663         }
 664 
 665         if (!S_ISDIR(sbuf.st_mode)) {
 666                 d_fprintf(stderr,
 667                           "ERROR: path '%s' is not a directory.\n",
 668                           path);
 669                 goto done;
 670         }
 671 
 672         /*
 673          * create the share
 674          */
 675 
 676         werr = smbconf_create_share(conf_ctx, sharename);
 677         if (!W_ERROR_IS_OK(werr)) {
 678                 d_fprintf(stderr, "Error creating share %s: %s\n",
 679                           sharename, win_errstr(werr));
 680                 goto done;
 681         }
 682 
 683         /*
 684          * fill the share with parameters
 685          */
 686 
 687         werr = smbconf_set_parameter(conf_ctx, sharename, "path", path);
 688         if (!W_ERROR_IS_OK(werr)) {
 689                 d_fprintf(stderr, "Error setting parameter %s: %s\n",
 690                           "path", win_errstr(werr));
 691                 goto done;
 692         }
 693 
 694         if (comment != NULL) {
 695                 werr = smbconf_set_parameter(conf_ctx, sharename, "comment",
 696                                              comment);
 697                 if (!W_ERROR_IS_OK(werr)) {
 698                         d_fprintf(stderr, "Error setting parameter %s: %s\n",
 699                                   "comment", win_errstr(werr));
 700                         goto done;
 701                 }
 702         }
 703 
 704         werr = smbconf_set_parameter(conf_ctx, sharename, "guest ok", guest_ok);
 705         if (!W_ERROR_IS_OK(werr)) {
 706                 d_fprintf(stderr, "Error setting parameter %s: %s\n",
 707                           "'guest ok'", win_errstr(werr));
 708                 goto done;
 709         }
 710 
 711         werr = smbconf_set_parameter(conf_ctx, sharename, "writeable",
 712                                      writeable);
 713         if (!W_ERROR_IS_OK(werr)) {
 714                 d_fprintf(stderr, "Error setting parameter %s: %s\n",
 715                           "writeable", win_errstr(werr));
 716                 goto done;
 717         }
 718 
 719         ret = 0;
 720 
 721 done:
 722         TALLOC_FREE(mem_ctx);
 723         return ret;
 724 }
 725 
 726 static int net_conf_delshare(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 727                              struct smbconf_ctx *conf_ctx, int argc,
 728                              const char **argv)
 729 {
 730         int ret = -1;
 731         const char *sharename = NULL;
 732         WERROR werr = WERR_OK;
 733         TALLOC_CTX *mem_ctx = talloc_stackframe();
 734 
 735         if (argc != 1 || c->display_usage) {
 736                 net_conf_delshare_usage(c, argc, argv);
 737                 goto done;
 738         }
 739         sharename = talloc_strdup(mem_ctx, argv[0]);
 740         if (sharename == NULL) {
 741                 d_printf("error: out of memory!\n");
 742                 goto done;
 743         }
 744 
 745         werr = smbconf_delete_share(conf_ctx, sharename);
 746         if (!W_ERROR_IS_OK(werr)) {
 747                 d_fprintf(stderr, "Error deleting share %s: %s\n",
 748                           sharename, win_errstr(werr));
 749                 goto done;
 750         }
 751 
 752         ret = 0;
 753 done:
 754         TALLOC_FREE(mem_ctx);
 755         return ret;
 756 }
 757 
 758 static int net_conf_setparm(struct net_context *c, struct smbconf_ctx *conf_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 759                             int argc, const char **argv)
 760 {
 761         int ret = -1;
 762         WERROR werr = WERR_OK;
 763         char *service = NULL;
 764         char *param = NULL;
 765         const char *value_str = NULL;
 766         TALLOC_CTX *mem_ctx = talloc_stackframe();
 767 
 768         if (argc != 3 || c->display_usage) {
 769                 net_conf_setparm_usage(c, argc, argv);
 770                 goto done;
 771         }
 772         service = talloc_strdup(mem_ctx, argv[0]);
 773         if (service == NULL) {
 774                 d_printf("error: out of memory!\n");
 775                 goto done;
 776         }
 777         param = talloc_strdup_lower(mem_ctx, argv[1]);
 778         if (param == NULL) {
 779                 d_printf("error: out of memory!\n");
 780                 goto done;
 781         }
 782         value_str = argv[2];
 783 
 784         werr = smbconf_transaction_start(conf_ctx);
 785         if (!W_ERROR_IS_OK(werr)) {
 786                 d_printf("error starting transaction: %s\n",
 787                          win_errstr(werr));
 788                 goto done;
 789         }
 790 
 791         if (!smbconf_share_exists(conf_ctx, service)) {
 792                 werr = smbconf_create_share(conf_ctx, service);
 793                 if (!W_ERROR_IS_OK(werr)) {
 794                         d_fprintf(stderr, "Error creating share '%s': %s\n",
 795                                   service, win_errstr(werr));
 796                         goto cancel;
 797                 }
 798         }
 799 
 800         werr = smbconf_set_parameter(conf_ctx, service, param, value_str);
 801 
 802         if (!W_ERROR_IS_OK(werr)) {
 803                 d_fprintf(stderr, "Error setting value '%s': %s\n",
 804                           param, win_errstr(werr));
 805                 goto cancel;
 806         }
 807 
 808         werr = smbconf_transaction_commit(conf_ctx);
 809         if (!W_ERROR_IS_OK(werr)) {
 810                 d_printf("error committing transaction: %s\n",
 811                          win_errstr(werr));
 812         } else {
 813                 ret = 0;
 814         }
 815 
 816         goto done;
 817 
 818 cancel:
 819         werr = smbconf_transaction_cancel(conf_ctx);
 820         if (!W_ERROR_IS_OK(werr)) {
 821                 d_printf("error cancelling transaction: %s\n",
 822                          win_errstr(werr));
 823         }
 824 
 825 done:
 826         TALLOC_FREE(mem_ctx);
 827         return ret;
 828 }
 829 
 830 static int net_conf_getparm(struct net_context *c, struct smbconf_ctx *conf_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 831                             int argc, const char **argv)
 832 {
 833         int ret = -1;
 834         WERROR werr = WERR_OK;
 835         char *service = NULL;
 836         char *param = NULL;
 837         char *valstr = NULL;
 838         TALLOC_CTX *mem_ctx;
 839 
 840         mem_ctx = talloc_stackframe();
 841 
 842         if (argc != 2 || c->display_usage) {
 843                 net_conf_getparm_usage(c, argc, argv);
 844                 goto done;
 845         }
 846         service = talloc_strdup(mem_ctx, argv[0]);
 847         if (service == NULL) {
 848                 d_printf("error: out of memory!\n");
 849                 goto done;
 850         }
 851         param = talloc_strdup_lower(mem_ctx, argv[1]);
 852         if (param == NULL) {
 853                 d_printf("error: out of memory!\n");
 854                 goto done;
 855         }
 856 
 857         werr = smbconf_get_parameter(conf_ctx, mem_ctx, service, param, &valstr);
 858 
 859         if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
 860                 d_fprintf(stderr,
 861                           "Error: given service '%s' does not exist.\n",
 862                           service);
 863                 goto done;
 864         } else if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
 865                 d_fprintf(stderr,
 866                           "Error: given parameter '%s' is not set.\n",
 867                           param);
 868                 goto done;
 869         } else if (!W_ERROR_IS_OK(werr)) {
 870                 d_fprintf(stderr, "Error getting value '%s': %s.\n",
 871                           param, win_errstr(werr));
 872                 goto done;
 873         }
 874 
 875         d_printf("%s\n", valstr);
 876 
 877         ret = 0;
 878 done:
 879         TALLOC_FREE(mem_ctx);
 880         return ret;
 881 }
 882 
 883 static int net_conf_delparm(struct net_context *c, struct smbconf_ctx *conf_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 884                             int argc, const char **argv)
 885 {
 886         int ret = -1;
 887         WERROR werr = WERR_OK;
 888         char *service = NULL;
 889         char *param = NULL;
 890         TALLOC_CTX *mem_ctx = talloc_stackframe();
 891 
 892         if (argc != 2 || c->display_usage) {
 893                 net_conf_delparm_usage(c, argc, argv);
 894                 goto done;
 895         }
 896         service = talloc_strdup(mem_ctx, argv[0]);
 897         if (service == NULL) {
 898                 d_printf("error: out of memory!\n");
 899                 goto done;
 900         }
 901         param = talloc_strdup_lower(mem_ctx, argv[1]);
 902         if (param == NULL) {
 903                 d_printf("error: out of memory!\n");
 904                 goto done;
 905         }
 906 
 907         werr = smbconf_delete_parameter(conf_ctx, service, param);
 908 
 909         if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
 910                 d_fprintf(stderr,
 911                           "Error: given service '%s' does not exist.\n",
 912                           service);
 913                 goto done;
 914         } else if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
 915                 d_fprintf(stderr,
 916                           "Error: given parameter '%s' is not set.\n",
 917                           param);
 918                 goto done;
 919         } else if (!W_ERROR_IS_OK(werr)) {
 920                 d_fprintf(stderr, "Error deleting value '%s': %s.\n",
 921                           param, win_errstr(werr));
 922                 goto done;
 923         }
 924 
 925         ret = 0;
 926 
 927 done:
 928         TALLOC_FREE(mem_ctx);
 929         return ret;
 930 }
 931 
 932 static int net_conf_getincludes(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 933                                 struct smbconf_ctx *conf_ctx,
 934                                 int argc, const char **argv)
 935 {
 936         WERROR werr;
 937         uint32_t num_includes;
 938         uint32_t count;
 939         char *service;
 940         char **includes = NULL;
 941         int ret = -1;
 942         TALLOC_CTX *mem_ctx = talloc_stackframe();
 943 
 944         if (argc != 1 || c->display_usage) {
 945                 net_conf_getincludes_usage(c, argc, argv);
 946                 goto done;
 947         }
 948 
 949         service = talloc_strdup(mem_ctx, argv[0]);
 950         if (service == NULL) {
 951                 d_printf("error: out of memory!\n");
 952                 goto done;
 953         }
 954 
 955         werr = smbconf_get_includes(conf_ctx, mem_ctx, service,
 956                                     &num_includes, &includes);
 957         if (!W_ERROR_IS_OK(werr)) {
 958                 d_printf("error getting includes: %s\n", win_errstr(werr));
 959                 goto done;
 960         }
 961 
 962         for (count = 0; count < num_includes; count++) {
 963                 d_printf("include = %s\n", includes[count]);
 964         }
 965 
 966         ret = 0;
 967 
 968 done:
 969         TALLOC_FREE(mem_ctx);
 970         return ret;
 971 }
 972 
 973 static int net_conf_setincludes(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 974                                 struct smbconf_ctx *conf_ctx,
 975                                 int argc, const char **argv)
 976 {
 977         WERROR werr;
 978         char *service;
 979         uint32_t num_includes;
 980         const char **includes;
 981         int ret = -1;
 982         TALLOC_CTX *mem_ctx = talloc_stackframe();
 983 
 984         if (argc < 1 || c->display_usage) {
 985                 net_conf_setincludes_usage(c, argc, argv);
 986                 goto done;
 987         }
 988 
 989         service = talloc_strdup(mem_ctx, argv[0]);
 990         if (service == NULL) {
 991                 d_printf("error: out of memory!\n");
 992                 goto done;
 993         }
 994 
 995         num_includes = argc - 1;
 996         if (num_includes == 0) {
 997                 includes = NULL;
 998         } else {
 999                 includes = argv + 1;
1000         }
1001 
1002         werr = smbconf_set_includes(conf_ctx, service, num_includes, includes);
1003         if (!W_ERROR_IS_OK(werr)) {
1004                 d_printf("error setting includes: %s\n", win_errstr(werr));
1005                 goto done;
1006         }
1007 
1008         ret = 0;
1009 
1010 done:
1011         TALLOC_FREE(mem_ctx);
1012         return ret;
1013 }
1014 
1015 static int net_conf_delincludes(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1016                                 struct smbconf_ctx *conf_ctx,
1017                                 int argc, const char **argv)
1018 {
1019         WERROR werr;
1020         char *service;
1021         int ret = -1;
1022         TALLOC_CTX *mem_ctx = talloc_stackframe();
1023 
1024         if (argc != 1 || c->display_usage) {
1025                 net_conf_delincludes_usage(c, argc, argv);
1026                 goto done;
1027         }
1028 
1029         service = talloc_strdup(mem_ctx, argv[0]);
1030         if (service == NULL) {
1031                 d_printf("error: out of memory!\n");
1032                 goto done;
1033         }
1034 
1035         werr = smbconf_delete_includes(conf_ctx, service);
1036         if (!W_ERROR_IS_OK(werr)) {
1037                 d_printf("error deleting includes: %s\n", win_errstr(werr));
1038                 goto done;
1039         }
1040 
1041         ret = 0;
1042 
1043 done:
1044         TALLOC_FREE(mem_ctx);
1045         return ret;
1046 }
1047 
1048 
1049 /**********************************************************************
1050  *
1051  * Wrapper and net_conf_run_function mechanism.
1052  *
1053  **********************************************************************/
1054 
1055 /**
1056  * Wrapper function to call the main conf functions.
1057  * The wrapper calls handles opening and closing of the
1058  * configuration.
1059  */
1060 static int net_conf_wrap_function(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1061                                   int (*fn)(struct net_context *,
1062                                             struct smbconf_ctx *,
1063                                             int, const char **),
1064                                   int argc, const char **argv)
1065 {
1066         WERROR werr;
1067         TALLOC_CTX *mem_ctx = talloc_stackframe();
1068         struct smbconf_ctx *conf_ctx;
1069         int ret = -1;
1070 
1071         werr = smbconf_init(mem_ctx, &conf_ctx, "registry:");
1072 
1073         if (!W_ERROR_IS_OK(werr)) {
1074                 return -1;
1075         }
1076 
1077         ret = fn(c, conf_ctx, argc, argv);
1078 
1079         smbconf_shutdown(conf_ctx);
1080 
1081         return ret;
1082 }
1083 
1084 /*
1085  * We need a functable struct of our own, because the
1086  * functions are called through a wrapper that handles
1087  * the opening and closing of the configuration, and so on.
1088  */
1089 struct conf_functable {
1090         const char *funcname;
1091         int (*fn)(struct net_context *c, struct smbconf_ctx *ctx, int argc,
1092                   const char **argv);
1093         int valid_transports;
1094         const char *description;
1095         const char *usage;
1096 };
1097 
1098 /**
1099  * This imitates net_run_function but calls the main functions
1100  * through the wrapper net_conf_wrap_function().
1101  */
1102 static int net_conf_run_function(struct net_context *c, int argc,
     /* [<][>][^][v][top][bottom][index][help] */
1103                                  const char **argv, const char *whoami,
1104                                  struct conf_functable *table)
1105 {
1106         int i;
1107 
1108         if (argc != 0) {
1109                 for (i=0; table[i].funcname; i++) {
1110                         if (StrCaseCmp(argv[0], table[i].funcname) == 0)
1111                                 return net_conf_wrap_function(c, table[i].fn,
1112                                                               argc-1,
1113                                                               argv+1);
1114                 }
1115         }
1116 
1117         d_printf("Usage:\n");
1118         for (i=0; table[i].funcname; i++) {
1119                 if (c->display_usage == false)
1120                         d_printf("%s %-15s %s\n", whoami, table[i].funcname,
1121                                  table[i].description);
1122                 else
1123                         d_printf("%s\n", table[i].usage);
1124         }
1125 
1126         return c->display_usage?0:-1;
1127 }
1128 
1129 /*
1130  * Entry-point for all the CONF functions.
1131  */
1132 
1133 int net_conf(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
1134 {
1135         int ret = -1;
1136         struct conf_functable func_table[] = {
1137                 {
1138                         "list",
1139                         net_conf_list,
1140                         NET_TRANSPORT_LOCAL,
1141                         "Dump the complete configuration in smb.conf like "
1142                         "format.",
1143                         "net conf list\n"
1144                         "    Dump the complete configuration in smb.conf like "
1145                         "format."
1146 
1147                 },
1148                 {
1149                         "import",
1150                         net_conf_import,
1151                         NET_TRANSPORT_LOCAL,
1152                         "Import configuration from file in smb.conf format.",
1153                         "net conf import\n"
1154                         "    Import configuration from file in smb.conf format."
1155                 },
1156                 {
1157                         "listshares",
1158                         net_conf_listshares,
1159                         NET_TRANSPORT_LOCAL,
1160                         "List the share names.",
1161                         "net conf listshares\n"
1162                         "    List the share names."
1163                 },
1164                 {
1165                         "drop",
1166                         net_conf_drop,
1167                         NET_TRANSPORT_LOCAL,
1168                         "Delete the complete configuration.",
1169                         "net conf drop\n"
1170                         "    Delete the complete configuration."
1171                 },
1172                 {
1173                         "showshare",
1174                         net_conf_showshare,
1175                         NET_TRANSPORT_LOCAL,
1176                         "Show the definition of a share.",
1177                         "net conf showshare\n"
1178                         "    Show the definition of a share."
1179                 },
1180                 {
1181                         "addshare",
1182                         net_conf_addshare,
1183                         NET_TRANSPORT_LOCAL,
1184                         "Create a new share.",
1185                         "net conf addshare\n"
1186                         "    Create a new share."
1187                 },
1188                 {
1189                         "delshare",
1190                         net_conf_delshare,
1191                         NET_TRANSPORT_LOCAL,
1192                         "Delete a share.",
1193                         "net conf delshare\n"
1194                         "    Delete a share."
1195                 },
1196                 {
1197                         "setparm",
1198                         net_conf_setparm,
1199                         NET_TRANSPORT_LOCAL,
1200                         "Store a parameter.",
1201                         "net conf setparm\n"
1202                         "    Store a parameter."
1203                 },
1204                 {
1205                         "getparm",
1206                         net_conf_getparm,
1207                         NET_TRANSPORT_LOCAL,
1208                         "Retrieve the value of a parameter.",
1209                         "net conf getparm\n"
1210                         "    Retrieve the value of a parameter."
1211                 },
1212                 {
1213                         "delparm",
1214                         net_conf_delparm,
1215                         NET_TRANSPORT_LOCAL,
1216                         "Delete a parameter.",
1217                         "net conf delparm\n"
1218                         "    Delete a parameter."
1219                 },
1220                 {
1221                         "getincludes",
1222                         net_conf_getincludes,
1223                         NET_TRANSPORT_LOCAL,
1224                         "Show the includes of a share definition.",
1225                         "net conf getincludes\n"
1226                         "    Show the includes of a share definition."
1227                 },
1228                 {
1229                         "setincludes",
1230                         net_conf_setincludes,
1231                         NET_TRANSPORT_LOCAL,
1232                         "Set includes for a share.",
1233                         "net conf setincludes\n"
1234                         "    Set includes for a share."
1235                 },
1236                 {
1237                         "delincludes",
1238                         net_conf_delincludes,
1239                         NET_TRANSPORT_LOCAL,
1240                         "Delete includes from a share definition.",
1241                         "net conf setincludes\n"
1242                         "    Delete includes from a share definition."
1243                 },
1244                 {NULL, NULL, 0, NULL, NULL}
1245         };
1246 
1247         ret = net_conf_run_function(c, argc, argv, "net conf", func_table);
1248 
1249         return ret;
1250 }
1251 

/* [<][>][^][v][top][bottom][index][help] */