Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/utils/sharesec.c

    r740 r988  
    2222 */
    2323
     24struct cli_state;
    2425
    2526#include "includes.h"
     
    2728#include "../libcli/security/security.h"
    2829#include "passdb/machine_sid.h"
     30#include "util_sd.h"
    2931
    3032static TALLOC_CTX *ctx;
     
    3537                SMB_ACL_SET,
    3638                SMB_SD_DELETE,
    37                 SMB_ACL_VIEW };
    38 
    39 struct perm_value {
    40         const char *perm;
    41         uint32 mask;
    42 };
    43 
    44 /* These values discovered by inspection */
    45 
    46 static const struct perm_value special_values[] = {
    47         { "R", SEC_RIGHTS_FILE_READ },
    48         { "W", SEC_RIGHTS_FILE_WRITE },
    49         { "X", SEC_RIGHTS_FILE_EXECUTE },
    50         { "D", SEC_STD_DELETE },
    51         { "P", SEC_STD_WRITE_DAC },
    52         { "O", SEC_STD_WRITE_OWNER },
    53         { NULL, 0 },
    54 };
    55 
    56 #define SEC_RIGHTS_DIR_CHANGE ( SEC_RIGHTS_DIR_READ|SEC_STD_DELETE|\
    57                                 SEC_RIGHTS_DIR_WRITE|SEC_DIR_TRAVERSE )
    58 
    59 static const struct perm_value standard_values[] = {
    60         { "READ",   SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE },
    61         { "CHANGE", SEC_RIGHTS_DIR_CHANGE },
    62         { "FULL",   SEC_RIGHTS_DIR_ALL },
    63         { NULL, 0 },
    64 };
    65 
    66 /********************************************************************
    67  print an ACE on a FILE
    68 ********************************************************************/
    69 
    70 static void print_ace(FILE *f, struct security_ace *ace)
    71 {
    72         const struct perm_value *v;
    73         int do_print = 0;
    74         uint32 got_mask;
    75 
    76         fprintf(f, "%s:", sid_string_tos(&ace->trustee));
    77 
    78         /* Ace type */
    79 
    80         if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {
    81                 fprintf(f, "ALLOWED");
    82         } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {
    83                 fprintf(f, "DENIED");
    84         } else {
    85                 fprintf(f, "%d", ace->type);
    86         }
    87 
    88         /* Not sure what flags can be set in a file ACL */
    89 
    90         fprintf(f, "/%d/", ace->flags);
    91 
    92         /* Standard permissions */
    93 
    94         for (v = standard_values; v->perm; v++) {
    95                 if (ace->access_mask == v->mask) {
    96                         fprintf(f, "%s", v->perm);
    97                         return;
    98                 }
    99         }
    100 
    101         /* Special permissions.  Print out a hex value if we have
    102            leftover bits in the mask. */
    103 
    104         got_mask = ace->access_mask;
    105 
    106  again:
    107         for (v = special_values; v->perm; v++) {
    108                 if ((ace->access_mask & v->mask) == v->mask) {
    109                         if (do_print) {
    110                                 fprintf(f, "%s", v->perm);
    111                         }
    112                         got_mask &= ~v->mask;
    113                 }
    114         }
    115 
    116         if (!do_print) {
    117                 if (got_mask != 0) {
    118                         fprintf(f, "0x%08x", ace->access_mask);
    119                 } else {
    120                         do_print = 1;
    121                         goto again;
    122                 }
    123         }
    124 }
    125 
    126 /********************************************************************
    127  print an ascii version of a security descriptor on a FILE handle
    128 ********************************************************************/
    129 
    130 static void sec_desc_print(FILE *f, struct security_descriptor *sd)
    131 {
    132         uint32 i;
    133 
    134         fprintf(f, "REVISION:%d\n", sd->revision);
    135 
    136         /* Print owner and group sid */
    137 
    138         fprintf(f, "OWNER:%s\n", sid_string_tos(sd->owner_sid));
    139 
    140         fprintf(f, "GROUP:%s\n", sid_string_tos(sd->group_sid));
    141 
    142         /* Print aces */
    143         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
    144                 struct security_ace *ace = &sd->dacl->aces[i];
    145                 fprintf(f, "ACL:");
    146                 print_ace(f, ace);
    147                 fprintf(f, "\n");
    148         }
    149 }
    150 
    151 /********************************************************************
    152  parse an ACE in the same format as print_ace()
    153 ********************************************************************/
    154 
    155 static bool parse_ace(struct security_ace *ace, const char *orig_str)
    156 {
    157         char *p;
    158         const char *cp;
    159         char *tok;
    160         unsigned int atype = 0;
    161         unsigned int aflags = 0;
    162         unsigned int amask = 0;
    163         struct dom_sid sid;
    164         uint32_t mask;
    165         const struct perm_value *v;
    166         char *str = SMB_STRDUP(orig_str);
    167         TALLOC_CTX *frame = talloc_stackframe();
    168 
    169         if (!str) {
    170                 TALLOC_FREE(frame);
    171                 return False;
    172         }
    173 
    174         ZERO_STRUCTP(ace);
    175         p = strchr_m(str,':');
    176         if (!p) {
    177                 fprintf(stderr, "ACE '%s': missing ':'.\n", orig_str);
    178                 SAFE_FREE(str);
    179                 TALLOC_FREE(frame);
    180                 return False;
    181         }
    182         *p = '\0';
    183         p++;
    184         /* Try to parse numeric form */
    185 
    186         if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 &&
    187             string_to_sid(&sid, str)) {
    188                 goto done;
    189         }
    190 
    191         /* Try to parse text form */
    192 
    193         if (!string_to_sid(&sid, str)) {
    194                 fprintf(stderr, "ACE '%s': failed to convert '%s' to SID\n",
    195                         orig_str, str);
    196                 SAFE_FREE(str);
    197                 TALLOC_FREE(frame);
    198                 return False;
    199         }
    200 
    201         cp = p;
    202         if (!next_token_talloc(frame, &cp, &tok, "/")) {
    203                 fprintf(stderr, "ACE '%s': failed to find '/' character.\n",
    204                         orig_str);
    205                 SAFE_FREE(str);
    206                 TALLOC_FREE(frame);
    207                 return False;
    208         }
    209 
    210         if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
    211                 atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
    212         } else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) {
    213                 atype = SEC_ACE_TYPE_ACCESS_DENIED;
    214         } else {
    215                 fprintf(stderr, "ACE '%s': missing 'ALLOWED' or 'DENIED' "
    216                         "entry at '%s'\n", orig_str, tok);
    217                 SAFE_FREE(str);
    218                 TALLOC_FREE(frame);
    219                 return False;
    220         }
    221 
    222         /* Only numeric form accepted for flags at present */
    223         /* no flags on share permissions */
    224 
    225         if (!(next_token_talloc(frame, &cp, &tok, "/") &&
    226               sscanf(tok, "%i", &aflags) && aflags == 0)) {
    227                 fprintf(stderr, "ACE '%s': bad integer flags entry at '%s'\n",
    228                         orig_str, tok);
    229                 SAFE_FREE(str);
    230                 TALLOC_FREE(frame);
    231                 return False;
    232         }
    233 
    234         if (!next_token_talloc(frame, &cp, &tok, "/")) {
    235                 fprintf(stderr, "ACE '%s': missing / at '%s'\n",
    236                         orig_str, tok);
    237                 SAFE_FREE(str);
    238                 TALLOC_FREE(frame);
    239                 return False;
    240         }
    241 
    242         if (strncmp(tok, "0x", 2) == 0) {
    243                 if (sscanf(tok, "%i", &amask) != 1) {
    244                         fprintf(stderr, "ACE '%s': bad hex number at '%s'\n",
    245                                 orig_str, tok);
    246                         TALLOC_FREE(frame);
    247                         SAFE_FREE(str);
    248                         return False;
    249                 }
    250                 goto done;
    251         }
    252 
    253         for (v = standard_values; v->perm; v++) {
    254                 if (strcmp(tok, v->perm) == 0) {
    255                         amask = v->mask;
    256                         goto done;
    257                 }
    258         }
    259 
    260         p = tok;
    261 
    262         while(*p) {
    263                 bool found = False;
    264 
    265                 for (v = special_values; v->perm; v++) {
    266                         if (v->perm[0] == *p) {
    267                                 amask |= v->mask;
    268                                 found = True;
    269                         }
    270                 }
    271 
    272                 if (!found) {
    273                         fprintf(stderr, "ACE '%s': bad permission value at "
    274                                 "'%s'\n", orig_str, p);
    275                         TALLOC_FREE(frame);
    276                         SAFE_FREE(str);
    277                         return False;
    278                 }
    279                 p++;
    280         }
    281 
    282         if (*p) {
    283                 TALLOC_FREE(frame);
    284                 SAFE_FREE(str);
    285                 return False;
    286         }
    287 
    288  done:
    289         mask = amask;
    290         init_sec_ace(ace, &sid, atype, mask, aflags);
    291         SAFE_FREE(str);
    292         TALLOC_FREE(frame);
    293         return True;
    294 }
    295 
     39                SMB_SD_SETSDDL,
     40                SMB_SD_VIEWSDDL,
     41                SMB_ACL_VIEW,
     42                SMB_ACL_VIEW_ALL };
    29643
    29744/********************************************************************
     
    31360        num_ace = count_chars( pacl, ',' ) + 1;
    31461
    315         if ( !(ace = TALLOC_ZERO_ARRAY( mem_ctx, struct security_ace, num_ace )) )
     62        if ( !(ace = talloc_zero_array( mem_ctx, struct security_ace, num_ace )) )
    31663                return NULL;
    31764
     
    32370                acl_string[MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1)] = '\0';
    32471
    325                 if ( !parse_ace( &ace[i], acl_string ) )
     72                if ( !parse_ace(NULL, &ace[i], acl_string ) )
    32673                        return NULL;
    32774
     
    367114static int ace_compare(struct security_ace *ace1, struct security_ace *ace2)
    368115{
    369         if (sec_ace_equal(ace1, ace2))
     116        if (security_ace_equal(ace1, ace2))
    370117                return 0;
    371118
     
    390137static void sort_acl(struct security_acl *the_acl)
    391138{
    392         uint32 i;
     139        uint32_t i;
    393140        if (!the_acl) return;
    394141
     
    396143
    397144        for (i=1;i<the_acl->num_aces;) {
    398                 if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) {
     145                if (security_ace_equal(&the_acl->aces[i-1],
     146                                       &the_acl->aces[i])) {
    399147                        int j;
    400148                        for (j=i; j<the_acl->num_aces-1; j++) {
     
    414162        struct security_descriptor *old = NULL;
    415163        size_t sd_size = 0;
    416         uint32 i, j;
     164        uint32_t i, j;
    417165
    418166        if (mode != SMB_ACL_SET && mode != SMB_SD_DELETE) {
     
    431179
    432180        switch (mode) {
     181        case SMB_ACL_VIEW_ALL:
     182                /* should not happen */
     183                return 0;
    433184        case SMB_ACL_VIEW:
    434                 sec_desc_print( stdout, old);
     185                sec_desc_print(NULL, stdout, old, false);
    435186                return 0;
    436187        case SMB_ACL_DELETE:
     
    439190
    440191                for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
    441                     if (sec_ace_equal(&sd->dacl->aces[i], &old->dacl->aces[j])) {
    442                         uint32 k;
     192                    if (security_ace_equal(&sd->dacl->aces[i],
     193                                           &old->dacl->aces[j])) {
     194                        uint32_t k;
    443195                        for (k=j; k<old->dacl->num_aces-1;k++) {
    444196                            old->dacl->aces[k] = old->dacl->aces[k+1];
     
    451203
    452204                if (!found) {
    453                 printf("ACL for ACE:");
    454                 print_ace(stdout, &sd->dacl->aces[i]);
    455                 printf(" not found\n");
     205                        printf("ACL for ACE:");
     206                        print_ace(NULL, stdout, &sd->dacl->aces[i], false);
     207                        printf(" not found\n");
    456208                }
    457209            }
     
    498250            }
    499251            return 0;
     252        default:
     253                fprintf(stderr, "invalid command\n");
     254                return -1;
    500255        }
    501256
     
    510265}
    511266
     267static int set_sharesec_sddl(const char *sharename, const char *sddl)
     268{
     269        struct security_descriptor *sd;
     270        bool ret;
     271
     272        sd = sddl_decode(talloc_tos(), sddl, get_global_sam_sid());
     273        if (sd == NULL) {
     274                fprintf(stderr, "Failed to parse acl\n");
     275                return -1;
     276        }
     277
     278        ret = set_share_security(sharename, sd);
     279        TALLOC_FREE(sd);
     280        if (!ret) {
     281                fprintf(stderr, "Failed to store acl for share [%s]\n",
     282                        sharename);
     283                return -1;
     284        }
     285
     286        return 0;
     287}
     288
     289static int view_sharesec_sddl(const char *sharename)
     290{
     291        struct security_descriptor *sd;
     292        size_t sd_size;
     293        char *acl;
     294
     295        sd = get_share_security(talloc_tos(), sharename, &sd_size);
     296        if (sd == NULL) {
     297                fprintf(stderr, "Unable to retrieve permissions for share "
     298                        "[%s]\n", sharename);
     299                return -1;
     300        }
     301
     302        acl = sddl_encode(talloc_tos(), sd, get_global_sam_sid());
     303        TALLOC_FREE(sd);
     304        if (acl == NULL) {
     305                fprintf(stderr, "Unable to sddl-encode permissions for share "
     306                        "[%s]\n", sharename);
     307                return -1;
     308        }
     309        printf("%s\n", acl);
     310        TALLOC_FREE(acl);
     311        return 0;
     312}
     313
    512314/********************************************************************
    513315  main program
    514316********************************************************************/
     317
     318enum {
     319        OPT_VIEW_ALL = 1000,
     320};
    515321
    516322int main(int argc, const char *argv[])
     
    532338                { "replace", 'R', POPT_ARG_STRING, &the_acl, 'R', "Overwrite share permission ACL", "ACLS" },
    533339                { "delete", 'D', POPT_ARG_NONE, NULL, 'D', "Delete the entire security descriptor" },
     340                { "setsddl", 'S', POPT_ARG_STRING, the_acl, 'S',
     341                  "Set the SD in sddl format" },
     342                { "viewsddl", 'V', POPT_ARG_NONE, the_acl, 'V',
     343                  "View the SD in sddl format" },
    534344                { "view", 'v', POPT_ARG_NONE, NULL, 'v', "View current share permissions" },
     345                { "view-all", 0, POPT_ARG_NONE, NULL, OPT_VIEW_ALL,
     346                  "View all current share permissions" },
    535347                { "machine-sid", 'M', POPT_ARG_NONE, NULL, 'M', "Initialize the machine SID" },
    536348                { "force", 'F', POPT_ARG_NONE, NULL, 'F', "Force storing the ACL", "ACLS" },
     
    547359        setup_logging( "sharesec", DEBUG_STDERR);
    548360
    549         load_case_tables();
     361        smb_init_locale();
    550362
    551363        lp_set_cmdline("log level", "1");
     
    581393                        break;
    582394
     395                case 'S':
     396                        mode = SMB_SD_SETSDDL;
     397                        the_acl = smb_xstrdup(poptGetOptArg(pc));
     398                        break;
     399
     400                case 'V':
     401                        mode = SMB_SD_VIEWSDDL;
     402                        break;
     403
    583404                case 'v':
    584405                        mode = SMB_ACL_VIEW;
     
    592413                        initialize_sid = True;
    593414                        break;
     415                case OPT_VIEW_ALL:
     416                        mode = SMB_ACL_VIEW_ALL;
     417                        break;
    594418                }
    595419        }
     
    597421        setlinebuf(stdout);
    598422
    599         lp_load_with_registry_shares( get_dyn_CONFIGFILE(), False, False, False,
    600                                       True );
     423        lp_load_with_registry_shares(get_dyn_CONFIGFILE());
    601424
    602425        /* check for initializing secrets.tdb first */
     
    619442        }
    620443
     444        if (mode == SMB_ACL_VIEW_ALL) {
     445                int i;
     446
     447                for (i=0; i<lp_numservices(); i++) {
     448                        TALLOC_CTX *frame = talloc_stackframe();
     449                        const char *service = lp_servicename(frame, i);
     450
     451                        if (service == NULL) {
     452                                continue;
     453                        }
     454
     455                        printf("[%s]\n", service);
     456                        change_share_sec(frame, service, NULL, SMB_ACL_VIEW);
     457                        printf("\n");
     458                        TALLOC_FREE(frame);
     459                }
     460                goto done;
     461        }
     462
    621463        /* get the sharename */
    622464
     
    635477        }
    636478
    637         retval = change_share_sec(ctx, sharename, the_acl, mode);
    638 
     479        switch (mode) {
     480        case SMB_SD_SETSDDL:
     481                retval = set_sharesec_sddl(sharename, the_acl);
     482                break;
     483        case SMB_SD_VIEWSDDL:
     484                retval = view_sharesec_sddl(sharename);
     485                break;
     486        default:
     487                retval = change_share_sec(ctx, sharename, the_acl, mode);
     488                break;
     489        }
     490
     491done:
    639492        talloc_destroy(ctx);
    640493
Note: See TracChangeset for help on using the changeset viewer.