~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/utils/net_conf.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

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