~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/utils/sharesec.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
 *  Unix SMB/Netbios implementation.
 
3
 *  Utility for managing share permissions
 
4
 *
 
5
 *  Copyright (C) Tim Potter                    2000
 
6
 *  Copyright (C) Jeremy Allison                2000
 
7
 *  Copyright (C) Jelmer Vernooij               2003
 
8
 *  Copyright (C) Gerald (Jerry) Carter         2005.
 
9
 *
 
10
 *  This program is free software; you can redistribute it and/or modify
 
11
 *  it under the terms of the GNU General Public License as published by
 
12
 *  the Free Software Foundation; either version 3 of the License, or
 
13
 *  (at your option) any later version.
 
14
 *
 
15
 *  This program is distributed in the hope that it will be useful,
 
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 *  GNU General Public License for more details.
 
19
 *
 
20
 *  You should have received a copy of the GNU General Public License
 
21
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 
22
 */
 
23
 
 
24
 
 
25
#include "includes.h"
 
26
 
 
27
static TALLOC_CTX *ctx;
 
28
 
 
29
enum acl_mode { SMB_ACL_DELETE,
 
30
                SMB_ACL_MODIFY,
 
31
                SMB_ACL_ADD,
 
32
                SMB_ACL_SET,
 
33
                SMB_SD_DELETE,
 
34
                SMB_ACL_VIEW };
 
35
 
 
36
struct perm_value {
 
37
        const char *perm;
 
38
        uint32 mask;
 
39
};
 
40
 
 
41
/* These values discovered by inspection */
 
42
 
 
43
static const struct perm_value special_values[] = {
 
44
        { "R", SEC_RIGHTS_FILE_READ },
 
45
        { "W", SEC_RIGHTS_FILE_WRITE },
 
46
        { "X", SEC_RIGHTS_FILE_EXECUTE },
 
47
        { "D", SEC_STD_DELETE },
 
48
        { "P", SEC_STD_WRITE_DAC },
 
49
        { "O", SEC_STD_WRITE_OWNER },
 
50
        { NULL, 0 },
 
51
};
 
52
 
 
53
#define SEC_RIGHTS_DIR_CHANGE ( SEC_RIGHTS_DIR_READ|SEC_STD_DELETE|\
 
54
                                SEC_RIGHTS_DIR_WRITE|SEC_DIR_TRAVERSE )
 
55
 
 
56
static const struct perm_value standard_values[] = {
 
57
        { "READ",   SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE },
 
58
        { "CHANGE", SEC_RIGHTS_DIR_CHANGE },
 
59
        { "FULL",   SEC_RIGHTS_DIR_ALL },
 
60
        { NULL, 0 },
 
61
};
 
62
 
 
63
/********************************************************************
 
64
 print an ACE on a FILE
 
65
********************************************************************/
 
66
 
 
67
static void print_ace(FILE *f, SEC_ACE *ace)
 
68
{
 
69
        const struct perm_value *v;
 
70
        int do_print = 0;
 
71
        uint32 got_mask;
 
72
 
 
73
        fprintf(f, "%s:", sid_string_tos(&ace->trustee));
 
74
 
 
75
        /* Ace type */
 
76
 
 
77
        if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {
 
78
                fprintf(f, "ALLOWED");
 
79
        } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {
 
80
                fprintf(f, "DENIED");
 
81
        } else {
 
82
                fprintf(f, "%d", ace->type);
 
83
        }
 
84
 
 
85
        /* Not sure what flags can be set in a file ACL */
 
86
 
 
87
        fprintf(f, "/%d/", ace->flags);
 
88
 
 
89
        /* Standard permissions */
 
90
 
 
91
        for (v = standard_values; v->perm; v++) {
 
92
                if (ace->access_mask == v->mask) {
 
93
                        fprintf(f, "%s", v->perm);
 
94
                        return;
 
95
                }
 
96
        }
 
97
 
 
98
        /* Special permissions.  Print out a hex value if we have
 
99
           leftover bits in the mask. */
 
100
 
 
101
        got_mask = ace->access_mask;
 
102
 
 
103
 again:
 
104
        for (v = special_values; v->perm; v++) {
 
105
                if ((ace->access_mask & v->mask) == v->mask) {
 
106
                        if (do_print) {
 
107
                                fprintf(f, "%s", v->perm);
 
108
                        }
 
109
                        got_mask &= ~v->mask;
 
110
                }
 
111
        }
 
112
 
 
113
        if (!do_print) {
 
114
                if (got_mask != 0) {
 
115
                        fprintf(f, "0x%08x", ace->access_mask);
 
116
                } else {
 
117
                        do_print = 1;
 
118
                        goto again;
 
119
                }
 
120
        }
 
121
}
 
122
 
 
123
/********************************************************************
 
124
 print an ascii version of a security descriptor on a FILE handle
 
125
********************************************************************/
 
126
 
 
127
static void sec_desc_print(FILE *f, SEC_DESC *sd)
 
128
{
 
129
        uint32 i;
 
130
 
 
131
        fprintf(f, "REVISION:%d\n", sd->revision);
 
132
 
 
133
        /* Print owner and group sid */
 
134
 
 
135
        fprintf(f, "OWNER:%s\n", sid_string_tos(sd->owner_sid));
 
136
 
 
137
        fprintf(f, "GROUP:%s\n", sid_string_tos(sd->group_sid));
 
138
 
 
139
        /* Print aces */
 
140
        for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
 
141
                SEC_ACE *ace = &sd->dacl->aces[i];
 
142
                fprintf(f, "ACL:");
 
143
                print_ace(f, ace);
 
144
                fprintf(f, "\n");
 
145
        }
 
146
}
 
147
 
 
148
/********************************************************************
 
149
 parse an ACE in the same format as print_ace()
 
150
********************************************************************/
 
151
 
 
152
static bool parse_ace(SEC_ACE *ace, const char *orig_str)
 
153
{
 
154
        char *p;
 
155
        const char *cp;
 
156
        char *tok;
 
157
        unsigned int atype = 0;
 
158
        unsigned int aflags = 0;
 
159
        unsigned int amask = 0;
 
160
        DOM_SID sid;
 
161
        uint32_t mask;
 
162
        const struct perm_value *v;
 
163
        char *str = SMB_STRDUP(orig_str);
 
164
        TALLOC_CTX *frame = talloc_stackframe();
 
165
 
 
166
        if (!str) {
 
167
                TALLOC_FREE(frame);
 
168
                return False;
 
169
        }
 
170
 
 
171
        ZERO_STRUCTP(ace);
 
172
        p = strchr_m(str,':');
 
173
        if (!p) {
 
174
                fprintf(stderr, "ACE '%s': missing ':'.\n", orig_str);
 
175
                SAFE_FREE(str);
 
176
                TALLOC_FREE(frame);
 
177
                return False;
 
178
        }
 
179
        *p = '\0';
 
180
        p++;
 
181
        /* Try to parse numeric form */
 
182
 
 
183
        if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 &&
 
184
            string_to_sid(&sid, str)) {
 
185
                goto done;
 
186
        }
 
187
 
 
188
        /* Try to parse text form */
 
189
 
 
190
        if (!string_to_sid(&sid, str)) {
 
191
                fprintf(stderr, "ACE '%s': failed to convert '%s' to SID\n",
 
192
                        orig_str, str);
 
193
                SAFE_FREE(str);
 
194
                TALLOC_FREE(frame);
 
195
                return False;
 
196
        }
 
197
 
 
198
        cp = p;
 
199
        if (!next_token_talloc(frame, &cp, &tok, "/")) {
 
200
                fprintf(stderr, "ACE '%s': failed to find '/' character.\n",
 
201
                        orig_str);
 
202
                SAFE_FREE(str);
 
203
                TALLOC_FREE(frame);
 
204
                return False;
 
205
        }
 
206
 
 
207
        if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
 
208
                atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
 
209
        } else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) {
 
210
                atype = SEC_ACE_TYPE_ACCESS_DENIED;
 
211
        } else {
 
212
                fprintf(stderr, "ACE '%s': missing 'ALLOWED' or 'DENIED' "
 
213
                        "entry at '%s'\n", orig_str, tok);
 
214
                SAFE_FREE(str);
 
215
                TALLOC_FREE(frame);
 
216
                return False;
 
217
        }
 
218
 
 
219
        /* Only numeric form accepted for flags at present */
 
220
        /* no flags on share permissions */
 
221
 
 
222
        if (!(next_token_talloc(frame, &cp, &tok, "/") &&
 
223
              sscanf(tok, "%i", &aflags) && aflags == 0)) {
 
224
                fprintf(stderr, "ACE '%s': bad integer flags entry at '%s'\n",
 
225
                        orig_str, tok);
 
226
                SAFE_FREE(str);
 
227
                TALLOC_FREE(frame);
 
228
                return False;
 
229
        }
 
230
 
 
231
        if (!next_token_talloc(frame, &cp, &tok, "/")) {
 
232
                fprintf(stderr, "ACE '%s': missing / at '%s'\n",
 
233
                        orig_str, tok);
 
234
                SAFE_FREE(str);
 
235
                TALLOC_FREE(frame);
 
236
                return False;
 
237
        }
 
238
 
 
239
        if (strncmp(tok, "0x", 2) == 0) {
 
240
                if (sscanf(tok, "%i", &amask) != 1) {
 
241
                        fprintf(stderr, "ACE '%s': bad hex number at '%s'\n",
 
242
                                orig_str, tok);
 
243
                        TALLOC_FREE(frame);
 
244
                        SAFE_FREE(str);
 
245
                        return False;
 
246
                }
 
247
                goto done;
 
248
        }
 
249
 
 
250
        for (v = standard_values; v->perm; v++) {
 
251
                if (strcmp(tok, v->perm) == 0) {
 
252
                        amask = v->mask;
 
253
                        goto done;
 
254
                }
 
255
        }
 
256
 
 
257
        p = tok;
 
258
 
 
259
        while(*p) {
 
260
                bool found = False;
 
261
 
 
262
                for (v = special_values; v->perm; v++) {
 
263
                        if (v->perm[0] == *p) {
 
264
                                amask |= v->mask;
 
265
                                found = True;
 
266
                        }
 
267
                }
 
268
 
 
269
                if (!found) {
 
270
                        fprintf(stderr, "ACE '%s': bad permission value at "
 
271
                                "'%s'\n", orig_str, p);
 
272
                        TALLOC_FREE(frame);
 
273
                        SAFE_FREE(str);
 
274
                        return False;
 
275
                }
 
276
                p++;
 
277
        }
 
278
 
 
279
        if (*p) {
 
280
                TALLOC_FREE(frame);
 
281
                SAFE_FREE(str);
 
282
                return False;
 
283
        }
 
284
 
 
285
 done:
 
286
        mask = amask;
 
287
        init_sec_ace(ace, &sid, atype, mask, aflags);
 
288
        SAFE_FREE(str);
 
289
        TALLOC_FREE(frame);
 
290
        return True;
 
291
}
 
292
 
 
293
 
 
294
/********************************************************************
 
295
********************************************************************/
 
296
 
 
297
static SEC_DESC* parse_acl_string(TALLOC_CTX *mem_ctx, const char *szACL, size_t *sd_size )
 
298
{
 
299
        SEC_DESC *sd = NULL;
 
300
        SEC_ACE *ace;
 
301
        SEC_ACL *theacl;
 
302
        int num_ace;
 
303
        const char *pacl;
 
304
        int i;
 
305
 
 
306
        if ( !szACL )
 
307
                return NULL;
 
308
 
 
309
        pacl = szACL;
 
310
        num_ace = count_chars( pacl, ',' ) + 1;
 
311
 
 
312
        if ( !(ace = TALLOC_ZERO_ARRAY( mem_ctx, SEC_ACE, num_ace )) )
 
313
                return NULL;
 
314
 
 
315
        for ( i=0; i<num_ace; i++ ) {
 
316
                char *end_acl = strchr_m( pacl, ',' );
 
317
                fstring acl_string;
 
318
 
 
319
                strncpy( acl_string, pacl, MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1) );
 
320
                acl_string[MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1)] = '\0';
 
321
 
 
322
                if ( !parse_ace( &ace[i], acl_string ) )
 
323
                        return NULL;
 
324
 
 
325
                pacl = end_acl;
 
326
                pacl++;
 
327
        }
 
328
 
 
329
        if ( !(theacl = make_sec_acl( mem_ctx, NT4_ACL_REVISION, num_ace, ace )) )
 
330
                return NULL;
 
331
 
 
332
        sd = make_sec_desc( mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
 
333
                NULL, NULL, NULL, theacl, sd_size);
 
334
 
 
335
        return sd;
 
336
}
 
337
 
 
338
/* add an ACE to a list of ACEs in a SEC_ACL */
 
339
static bool add_ace(TALLOC_CTX *mem_ctx, SEC_ACL **the_acl, SEC_ACE *ace)
 
340
{
 
341
        SEC_ACL *new_ace;
 
342
        SEC_ACE *aces;
 
343
        if (! *the_acl) {
 
344
                return (((*the_acl) = make_sec_acl(mem_ctx, 3, 1, ace)) != NULL);
 
345
        }
 
346
 
 
347
        if (!(aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces))) {
 
348
                return False;
 
349
        }
 
350
        memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE));
 
351
        memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));
 
352
        new_ace = make_sec_acl(mem_ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces);
 
353
        SAFE_FREE(aces);
 
354
        (*the_acl) = new_ace;
 
355
        return True;
 
356
}
 
357
 
 
358
/* The MSDN is contradictory over the ordering of ACE entries in an ACL.
 
359
   However NT4 gives a "The information may have been modified by a
 
360
   computer running Windows NT 5.0" if denied ACEs do not appear before
 
361
   allowed ACEs. */
 
362
 
 
363
static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2)
 
364
{
 
365
        if (sec_ace_equal(ace1, ace2))
 
366
                return 0;
 
367
 
 
368
        if (ace1->type != ace2->type)
 
369
                return ace2->type - ace1->type;
 
370
 
 
371
        if (sid_compare(&ace1->trustee, &ace2->trustee))
 
372
                return sid_compare(&ace1->trustee, &ace2->trustee);
 
373
 
 
374
        if (ace1->flags != ace2->flags)
 
375
                return ace1->flags - ace2->flags;
 
376
 
 
377
        if (ace1->access_mask != ace2->access_mask)
 
378
                return ace1->access_mask - ace2->access_mask;
 
379
 
 
380
        if (ace1->size != ace2->size)
 
381
                return ace1->size - ace2->size;
 
382
 
 
383
        return memcmp(ace1, ace2, sizeof(SEC_ACE));
 
384
}
 
385
 
 
386
static void sort_acl(SEC_ACL *the_acl)
 
387
{
 
388
        uint32 i;
 
389
        if (!the_acl) return;
 
390
 
 
391
        qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), QSORT_CAST ace_compare);
 
392
 
 
393
        for (i=1;i<the_acl->num_aces;) {
 
394
                if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) {
 
395
                        int j;
 
396
                        for (j=i; j<the_acl->num_aces-1; j++) {
 
397
                                the_acl->aces[j] = the_acl->aces[j+1];
 
398
                        }
 
399
                        the_acl->num_aces--;
 
400
                } else {
 
401
                        i++;
 
402
                }
 
403
        }
 
404
}
 
405
 
 
406
 
 
407
static int change_share_sec(TALLOC_CTX *mem_ctx, const char *sharename, char *the_acl, enum acl_mode mode)
 
408
{
 
409
        SEC_DESC *sd = NULL;
 
410
        SEC_DESC *old = NULL;
 
411
        size_t sd_size = 0;
 
412
        uint32 i, j;
 
413
 
 
414
        if (mode != SMB_ACL_SET && mode != SMB_SD_DELETE) {
 
415
            if (!(old = get_share_security( mem_ctx, sharename, &sd_size )) ) {
 
416
                fprintf(stderr, "Unable to retrieve permissions for share "
 
417
                        "[%s]\n", sharename);
 
418
                return -1;
 
419
            }
 
420
        }
 
421
 
 
422
        if ( (mode != SMB_ACL_VIEW && mode != SMB_SD_DELETE) &&
 
423
            !(sd = parse_acl_string(mem_ctx, the_acl, &sd_size )) ) {
 
424
                fprintf( stderr, "Failed to parse acl\n");
 
425
                return -1;
 
426
        }
 
427
 
 
428
        switch (mode) {
 
429
        case SMB_ACL_VIEW:
 
430
                sec_desc_print( stdout, old);
 
431
                return 0;
 
432
        case SMB_ACL_DELETE:
 
433
            for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
 
434
                bool found = False;
 
435
 
 
436
                for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
 
437
                    if (sec_ace_equal(&sd->dacl->aces[i], &old->dacl->aces[j])) {
 
438
                        uint32 k;
 
439
                        for (k=j; k<old->dacl->num_aces-1;k++) {
 
440
                            old->dacl->aces[k] = old->dacl->aces[k+1];
 
441
                        }
 
442
                        old->dacl->num_aces--;
 
443
                        found = True;
 
444
                        break;
 
445
                    }
 
446
                }
 
447
 
 
448
                if (!found) {
 
449
                printf("ACL for ACE:");
 
450
                print_ace(stdout, &sd->dacl->aces[i]);
 
451
                printf(" not found\n");
 
452
                }
 
453
            }
 
454
            break;
 
455
        case SMB_ACL_MODIFY:
 
456
            for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
 
457
                bool found = False;
 
458
 
 
459
                for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
 
460
                    if (sid_equal(&sd->dacl->aces[i].trustee,
 
461
                        &old->dacl->aces[j].trustee)) {
 
462
                        old->dacl->aces[j] = sd->dacl->aces[i];
 
463
                        found = True;
 
464
                    }
 
465
                }
 
466
 
 
467
                if (!found) {
 
468
                    printf("ACL for SID %s not found\n",
 
469
                           sid_string_tos(&sd->dacl->aces[i].trustee));
 
470
                }
 
471
            }
 
472
 
 
473
            if (sd->owner_sid) {
 
474
                old->owner_sid = sd->owner_sid;
 
475
            }
 
476
 
 
477
            if (sd->group_sid) {
 
478
                old->group_sid = sd->group_sid;
 
479
            }
 
480
            break;
 
481
        case SMB_ACL_ADD:
 
482
            for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
 
483
                add_ace(mem_ctx, &old->dacl, &sd->dacl->aces[i]);
 
484
            }
 
485
            break;
 
486
        case SMB_ACL_SET:
 
487
            old = sd;
 
488
            break;
 
489
        case SMB_SD_DELETE:
 
490
            if (!delete_share_security(sharename)) {
 
491
                fprintf( stderr, "Failed to delete security descriptor for "
 
492
                         "share [%s]\n", sharename );
 
493
                return -1;
 
494
            }
 
495
            return 0;
 
496
        }
 
497
 
 
498
        /* Denied ACE entries must come before allowed ones */
 
499
        sort_acl(old->dacl);
 
500
 
 
501
        if ( !set_share_security( sharename, old ) ) {
 
502
            fprintf( stderr, "Failed to store acl for share [%s]\n", sharename );
 
503
            return 2;
 
504
        }
 
505
        return 0;
 
506
}
 
507
 
 
508
/********************************************************************
 
509
  main program
 
510
********************************************************************/
 
511
 
 
512
int main(int argc, const char *argv[])
 
513
{
 
514
        int opt;
 
515
        int retval = 0;
 
516
        enum acl_mode mode = SMB_ACL_SET;
 
517
        static char *the_acl = NULL;
 
518
        fstring sharename;
 
519
        bool force_acl = False;
 
520
        int snum;
 
521
        poptContext pc;
 
522
        bool initialize_sid = False;
 
523
        struct poptOption long_options[] = {
 
524
                POPT_AUTOHELP
 
525
                { "remove", 'r', POPT_ARG_STRING, &the_acl, 'r', "Remove ACEs", "ACL" },
 
526
                { "modify", 'm', POPT_ARG_STRING, &the_acl, 'm', "Modify existing ACEs", "ACL" },
 
527
                { "add", 'a', POPT_ARG_STRING, &the_acl, 'a', "Add ACEs", "ACL" },
 
528
                { "replace", 'R', POPT_ARG_STRING, &the_acl, 'R', "Overwrite share permission ACL", "ACLS" },
 
529
                { "delete", 'D', POPT_ARG_NONE, NULL, 'D', "Delete the entire security descriptor" },
 
530
                { "view", 'v', POPT_ARG_NONE, NULL, 'v', "View current share permissions" },
 
531
                { "machine-sid", 'M', POPT_ARG_NONE, NULL, 'M', "Initialize the machine SID" },
 
532
                { "force", 'F', POPT_ARG_NONE, NULL, 'F', "Force storing the ACL", "ACLS" },
 
533
                POPT_COMMON_SAMBA
 
534
                { NULL }
 
535
        };
 
536
 
 
537
        if ( !(ctx = talloc_stackframe()) ) {
 
538
                fprintf( stderr, "Failed to initialize talloc context!\n");
 
539
                return -1;
 
540
        }
 
541
 
 
542
        /* set default debug level to 1 regardless of what smb.conf sets */
 
543
        setup_logging( "sharesec", True );
 
544
        DEBUGLEVEL_CLASS[DBGC_ALL] = 1;
 
545
        dbf = x_stderr;
 
546
        x_setbuf( x_stderr, NULL );
 
547
 
 
548
        pc = poptGetContext("sharesec", argc, argv, long_options, 0);
 
549
 
 
550
        poptSetOtherOptionHelp(pc, "sharename\n");
 
551
 
 
552
        while ((opt = poptGetNextOpt(pc)) != -1) {
 
553
                switch (opt) {
 
554
                case 'r':
 
555
                        the_acl = smb_xstrdup(poptGetOptArg(pc));
 
556
                        mode = SMB_ACL_DELETE;
 
557
                        break;
 
558
 
 
559
                case 'm':
 
560
                        the_acl = smb_xstrdup(poptGetOptArg(pc));
 
561
                        mode = SMB_ACL_MODIFY;
 
562
                        break;
 
563
 
 
564
                case 'a':
 
565
                        the_acl = smb_xstrdup(poptGetOptArg(pc));
 
566
                        mode = SMB_ACL_ADD;
 
567
                        break;
 
568
 
 
569
                case 'R':
 
570
                        the_acl = smb_xstrdup(poptGetOptArg(pc));
 
571
                        mode = SMB_ACL_SET;
 
572
                        break;
 
573
 
 
574
                case 'D':
 
575
                        mode = SMB_SD_DELETE;
 
576
                        break;
 
577
 
 
578
                case 'v':
 
579
                        mode = SMB_ACL_VIEW;
 
580
                        break;
 
581
 
 
582
                case 'F':
 
583
                        force_acl = True;
 
584
                        break;
 
585
 
 
586
                case 'M':
 
587
                        initialize_sid = True;
 
588
                        break;
 
589
                }
 
590
        }
 
591
 
 
592
        setlinebuf(stdout);
 
593
 
 
594
        load_case_tables();
 
595
 
 
596
        lp_load( get_dyn_CONFIGFILE(), False, False, False, True );
 
597
 
 
598
        /* check for initializing secrets.tdb first */
 
599
 
 
600
        if ( initialize_sid ) {
 
601
                DOM_SID *sid = get_global_sam_sid();
 
602
 
 
603
                if ( !sid ) {
 
604
                        fprintf( stderr, "Failed to retrieve Machine SID!\n");
 
605
                        return 3;
 
606
                }
 
607
 
 
608
                printf ("%s\n", sid_string_tos( sid ) );
 
609
                return 0;
 
610
        }
 
611
 
 
612
        if ( mode == SMB_ACL_VIEW && force_acl ) {
 
613
                fprintf( stderr, "Invalid combination of -F and -v\n");
 
614
                return -1;
 
615
        }
 
616
 
 
617
        /* get the sharename */
 
618
 
 
619
        if(!poptPeekArg(pc)) {
 
620
                poptPrintUsage(pc, stderr, 0);
 
621
                return -1;
 
622
        }
 
623
 
 
624
        fstrcpy(sharename, poptGetArg(pc));
 
625
 
 
626
        snum = lp_servicenumber( sharename );
 
627
 
 
628
        if ( snum == -1 && !force_acl ) {
 
629
                fprintf( stderr, "Invalid sharename: %s\n", sharename);
 
630
                return -1;
 
631
        }
 
632
 
 
633
        retval = change_share_sec(ctx, sharename, the_acl, mode);
 
634
 
 
635
        talloc_destroy(ctx);
 
636
 
 
637
        return retval;
 
638
}