LCOV - code coverage report
Current view: top level - source3/lib - util_sd.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 317 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Security Descriptor (SD) helper functions
       4             : 
       5             :    Copyright (C) Andrew Tridgell 2000
       6             :    Copyright (C) Tim Potter      2000
       7             :    Copyright (C) Jeremy Allison  2000
       8             :    Copyright (C) Jelmer Vernooij 2003
       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             : #include "includes.h"
      25             : #include "libsmb/libsmb.h"
      26             : #include "util_sd.h"
      27             : #include "librpc/gen_ndr/ndr_lsa.h"
      28             : #include "../libcli/security/security.h"
      29             : #include "rpc_client/cli_pipe.h"
      30             : #include "rpc_client/cli_lsarpc.h"
      31             : #include "lib/util/string_wrappers.h"
      32             : 
      33             : /* These values discovered by inspection */
      34             : 
      35             : struct perm_value {
      36             :         const char *perm;
      37             :         uint32_t mask;
      38             : };
      39             : 
      40             : static const struct perm_value special_values[] = {
      41             :         { "R", SEC_RIGHTS_FILE_READ },
      42             :         { "W", SEC_RIGHTS_FILE_WRITE },
      43             :         { "X", SEC_RIGHTS_FILE_EXECUTE },
      44             :         { "D", SEC_STD_DELETE },
      45             :         { "P", SEC_STD_WRITE_DAC },
      46             :         { "O", SEC_STD_WRITE_OWNER },
      47             :         { NULL, 0 },
      48             : };
      49             : 
      50             : static const struct perm_value standard_values[] = {
      51             :         { "READ",   SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE },
      52             :         { "CHANGE", SEC_RIGHTS_DIR_READ|SEC_STD_DELETE|\
      53             :           SEC_DIR_DELETE_CHILD|\
      54             :           SEC_RIGHTS_DIR_WRITE|SEC_DIR_TRAVERSE },
      55             :         { "FULL",   SEC_RIGHTS_DIR_ALL },
      56             :         { NULL, 0 },
      57             : };
      58             : 
      59             : static const struct {
      60             :         uint16_t mask;
      61             :         const char *str;
      62             :         const char *desc;
      63             : } sec_desc_ctrl_bits[] = {
      64             :         {SEC_DESC_OWNER_DEFAULTED,       "OD", "Owner Defaulted"},
      65             :         {SEC_DESC_GROUP_DEFAULTED,       "GD", "Group Defaulted"},
      66             :         {SEC_DESC_DACL_PRESENT,          "DP", "DACL Present"},
      67             :         {SEC_DESC_DACL_DEFAULTED,        "DD", "DACL Defaulted"},
      68             :         {SEC_DESC_SACL_PRESENT,          "SP", "SACL Present"},
      69             :         {SEC_DESC_SACL_DEFAULTED,        "SD", "SACL Defaulted"},
      70             :         {SEC_DESC_DACL_TRUSTED,          "DT", "DACL Trusted"},
      71             :         {SEC_DESC_SERVER_SECURITY,       "SS", "Server Security"},
      72             :         {SEC_DESC_DACL_AUTO_INHERIT_REQ, "DR", "DACL Inheritance Required"},
      73             :         {SEC_DESC_SACL_AUTO_INHERIT_REQ, "SR", "SACL Inheritance Required"},
      74             :         {SEC_DESC_DACL_AUTO_INHERITED,   "DI", "DACL Auto Inherited"},
      75             :         {SEC_DESC_SACL_AUTO_INHERITED,   "SI", "SACL Auto Inherited"},
      76             :         {SEC_DESC_DACL_PROTECTED,        "PD", "DACL Protected"},
      77             :         {SEC_DESC_SACL_PROTECTED,        "PS", "SACL Protected"},
      78             :         {SEC_DESC_RM_CONTROL_VALID,      "RM", "RM Control Valid"},
      79             :         {SEC_DESC_SELF_RELATIVE ,        "SR", "Self Relative"},
      80             : };
      81             : 
      82             : /* Open cli connection and policy handle */
      83           0 : static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
      84             :                                    const struct dom_sid *sid,
      85             :                                    TALLOC_CTX *mem_ctx,
      86             :                                    enum lsa_SidType *type,
      87             :                                    char **domain, char **name)
      88             : {
      89           0 :         struct smbXcli_tcon *orig_tcon = NULL;
      90           0 :         struct rpc_pipe_client *p = NULL;
      91             :         struct policy_handle handle;
      92             :         NTSTATUS status;
      93           0 :         TALLOC_CTX *frame = talloc_stackframe();
      94             :         enum lsa_SidType *types;
      95             :         char **domains;
      96             :         char **names;
      97             : 
      98           0 :         if (cli_state_has_tcon(cli)) {
      99           0 :                 orig_tcon = cli_state_save_tcon(cli);
     100           0 :                 if (orig_tcon == NULL) {
     101           0 :                         status = NT_STATUS_NO_MEMORY;
     102           0 :                         goto tcon_fail;
     103             :                 }
     104             :         }
     105             : 
     106           0 :         status = cli_tree_connect(cli, "IPC$", "?????", NULL);
     107           0 :         if (!NT_STATUS_IS_OK(status)) {
     108           0 :                 goto tcon_fail;
     109             :         }
     110             : 
     111           0 :         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
     112             :                                           &p);
     113           0 :         if (!NT_STATUS_IS_OK(status)) {
     114           0 :                 goto fail;
     115             :         }
     116             : 
     117           0 :         status = rpccli_lsa_open_policy(p, talloc_tos(), True,
     118             :                                         GENERIC_EXECUTE_ACCESS, &handle);
     119           0 :         if (!NT_STATUS_IS_OK(status)) {
     120           0 :                 goto fail;
     121             :         }
     122             : 
     123           0 :         status = rpccli_lsa_lookup_sids(p, talloc_tos(), &handle, 1, sid,
     124             :                                         &domains, &names, &types);
     125           0 :         if (!NT_STATUS_IS_OK(status)) {
     126           0 :                 goto fail;
     127             :         }
     128             : 
     129           0 :         *type = types[0];
     130           0 :         *domain = talloc_move(mem_ctx, &domains[0]);
     131           0 :         *name = talloc_move(mem_ctx, &names[0]);
     132             : 
     133           0 :         status = NT_STATUS_OK;
     134           0 :  fail:
     135           0 :         TALLOC_FREE(p);
     136           0 :         cli_tdis(cli);
     137           0 :  tcon_fail:
     138           0 :         cli_state_restore_tcon(cli, orig_tcon);
     139           0 :         TALLOC_FREE(frame);
     140           0 :         return status;
     141             : }
     142             : 
     143             : /* convert a SID to a string, either numeric or username/group */
     144           0 : void SidToString(struct cli_state *cli, fstring str, const struct dom_sid *sid,
     145             :                  bool numeric)
     146             : {
     147           0 :         char *domain = NULL;
     148           0 :         char *name = NULL;
     149             :         enum lsa_SidType type;
     150             :         NTSTATUS status;
     151             : 
     152           0 :         sid_to_fstring(str, sid);
     153             : 
     154           0 :         if (numeric || cli == NULL) {
     155           0 :                 return;
     156             :         }
     157             : 
     158           0 :         status = cli_lsa_lookup_sid(cli, sid, talloc_tos(), &type,
     159             :                                     &domain, &name);
     160             : 
     161           0 :         if (!NT_STATUS_IS_OK(status)) {
     162           0 :                 return;
     163             :         }
     164             : 
     165           0 :         if (*domain) {
     166           0 :                 slprintf(str, sizeof(fstring) - 1, "%s%s%s",
     167             :                         domain, lp_winbind_separator(), name);
     168             :         } else {
     169           0 :                 fstrcpy(str, name);
     170             :         }
     171             : }
     172             : 
     173           0 : static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
     174             :                                     const char *name,
     175             :                                     enum lsa_SidType *type,
     176             :                                     struct dom_sid *sid)
     177             : {
     178           0 :         struct smbXcli_tcon *orig_tcon = NULL;
     179           0 :         struct rpc_pipe_client *p = NULL;
     180             :         struct policy_handle handle;
     181             :         NTSTATUS status;
     182           0 :         TALLOC_CTX *frame = talloc_stackframe();
     183             :         struct dom_sid *sids;
     184             :         enum lsa_SidType *types;
     185             : 
     186           0 :         if (cli_state_has_tcon(cli)) {
     187           0 :                 orig_tcon = cli_state_save_tcon(cli);
     188           0 :                 if (orig_tcon == NULL) {
     189           0 :                         status = NT_STATUS_NO_MEMORY;
     190           0 :                         goto tcon_fail;
     191             :                 }
     192             :         }
     193             : 
     194           0 :         status = cli_tree_connect(cli, "IPC$", "?????", NULL);
     195           0 :         if (!NT_STATUS_IS_OK(status)) {
     196           0 :                 goto tcon_fail;
     197             :         }
     198             : 
     199           0 :         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
     200             :                                           &p);
     201           0 :         if (!NT_STATUS_IS_OK(status)) {
     202           0 :                 goto fail;
     203             :         }
     204             : 
     205           0 :         status = rpccli_lsa_open_policy(p, talloc_tos(), True,
     206             :                                         GENERIC_EXECUTE_ACCESS, &handle);
     207           0 :         if (!NT_STATUS_IS_OK(status)) {
     208           0 :                 goto fail;
     209             :         }
     210             : 
     211           0 :         status = rpccli_lsa_lookup_names(p, talloc_tos(), &handle, 1, &name,
     212             :                                          NULL, 1, &sids, &types);
     213           0 :         if (!NT_STATUS_IS_OK(status)) {
     214           0 :                 goto fail;
     215             :         }
     216             : 
     217           0 :         *type = types[0];
     218           0 :         *sid = sids[0];
     219             : 
     220           0 :         status = NT_STATUS_OK;
     221           0 :  fail:
     222           0 :         TALLOC_FREE(p);
     223           0 :         cli_tdis(cli);
     224           0 :  tcon_fail:
     225           0 :         cli_state_restore_tcon(cli, orig_tcon);
     226           0 :         TALLOC_FREE(frame);
     227           0 :         return status;
     228             : }
     229             : 
     230             : /* convert a string to a SID, either numeric or username/group */
     231           0 : bool StringToSid(struct cli_state *cli, struct dom_sid *sid, const char *str)
     232             : {
     233             :         enum lsa_SidType type;
     234             : 
     235           0 :         if (string_to_sid(sid, str)) {
     236           0 :                 return true;
     237             :         }
     238             : 
     239           0 :         if (cli == NULL) {
     240           0 :                 return false;
     241             :         }
     242             : 
     243           0 :         return NT_STATUS_IS_OK(cli_lsa_lookup_name(cli, str, &type, sid));
     244             : }
     245             : 
     246           0 : static void print_ace_flags(FILE *f, uint8_t flags)
     247             : {
     248           0 :         char *str = talloc_strdup(NULL, "");
     249             : 
     250           0 :         if (!str) {
     251           0 :                 goto out;
     252             :         }
     253             : 
     254           0 :         if (flags & SEC_ACE_FLAG_OBJECT_INHERIT) {
     255           0 :                 str = talloc_asprintf(str, "%s%s",
     256             :                                 str, "OI|");
     257           0 :                 if (!str) {
     258           0 :                         goto out;
     259             :                 }
     260             :         }
     261           0 :         if (flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
     262           0 :                 str = talloc_asprintf(str, "%s%s",
     263             :                                 str, "CI|");
     264           0 :                 if (!str) {
     265           0 :                         goto out;
     266             :                 }
     267             :         }
     268           0 :         if (flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
     269           0 :                 str = talloc_asprintf(str, "%s%s",
     270             :                                 str, "NP|");
     271           0 :                 if (!str) {
     272           0 :                         goto out;
     273             :                 }
     274             :         }
     275           0 :         if (flags & SEC_ACE_FLAG_INHERIT_ONLY) {
     276           0 :                 str = talloc_asprintf(str, "%s%s",
     277             :                                 str, "IO|");
     278           0 :                 if (!str) {
     279           0 :                         goto out;
     280             :                 }
     281             :         }
     282           0 :         if (flags & SEC_ACE_FLAG_INHERITED_ACE) {
     283           0 :                 str = talloc_asprintf(str, "%s%s",
     284             :                                 str, "I|");
     285           0 :                 if (!str) {
     286           0 :                         goto out;
     287             :                 }
     288             :         }
     289             :         /* Ignore define SEC_ACE_FLAG_SUCCESSFUL_ACCESS ( 0x40 )
     290             :            and SEC_ACE_FLAG_FAILED_ACCESS ( 0x80 ) as they're
     291             :            audit ace flags. */
     292             : 
     293           0 :         if (str[strlen(str)-1] == '|') {
     294           0 :                 str[strlen(str)-1] = '\0';
     295           0 :                 fprintf(f, "/%s/", str);
     296             :         } else {
     297           0 :                 fprintf(f, "/0x%x/", flags);
     298             :         }
     299           0 :         TALLOC_FREE(str);
     300           0 :         return;
     301             : 
     302           0 :   out:
     303           0 :         fprintf(f, "/0x%x/", flags);
     304             : }
     305             : 
     306             : /* print an ACE on a FILE, using either numeric or ascii representation */
     307           0 : void print_ace(struct cli_state *cli, FILE *f, struct security_ace *ace,
     308             :                bool numeric)
     309             : {
     310             :         const struct perm_value *v;
     311             :         fstring sidstr;
     312           0 :         int do_print = 0;
     313             :         uint32_t got_mask;
     314             : 
     315           0 :         SidToString(cli, sidstr, &ace->trustee, numeric);
     316             : 
     317           0 :         fprintf(f, "%s:", sidstr);
     318             : 
     319           0 :         if (numeric) {
     320           0 :                 fprintf(f, "%d/0x%x/0x%08x",
     321           0 :                         ace->type, ace->flags, ace->access_mask);
     322           0 :                 return;
     323             :         }
     324             : 
     325             :         /* Ace type */
     326             : 
     327           0 :         if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {
     328           0 :                 fprintf(f, "ALLOWED");
     329           0 :         } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {
     330           0 :                 fprintf(f, "DENIED");
     331             :         } else {
     332           0 :                 fprintf(f, "%d", ace->type);
     333             :         }
     334             : 
     335           0 :         print_ace_flags(f, ace->flags);
     336             : 
     337             :         /* Standard permissions */
     338             : 
     339           0 :         for (v = standard_values; v->perm; v++) {
     340           0 :                 if (ace->access_mask == v->mask) {
     341           0 :                         fprintf(f, "%s", v->perm);
     342           0 :                         return;
     343             :                 }
     344             :         }
     345             : 
     346             :         /* Special permissions.  Print out a hex value if we have
     347             :            leftover bits in the mask. */
     348             : 
     349           0 :         got_mask = ace->access_mask;
     350             : 
     351           0 :  again:
     352           0 :         for (v = special_values; v->perm; v++) {
     353           0 :                 if ((ace->access_mask & v->mask) == v->mask) {
     354           0 :                         if (do_print) {
     355           0 :                                 fprintf(f, "%s", v->perm);
     356             :                         }
     357           0 :                         got_mask &= ~v->mask;
     358             :                 }
     359             :         }
     360             : 
     361           0 :         if (!do_print) {
     362           0 :                 if (got_mask != 0) {
     363           0 :                         fprintf(f, "0x%08x", ace->access_mask);
     364             :                 } else {
     365           0 :                         do_print = 1;
     366           0 :                         goto again;
     367             :                 }
     368             :         }
     369             : }
     370             : 
     371           0 : static bool parse_ace_flags(const char *str, unsigned int *pflags)
     372             : {
     373           0 :         const char *p = str;
     374           0 :         *pflags = 0;
     375             : 
     376           0 :         while (*p) {
     377           0 :                 if (strnequal(p, "OI", 2)) {
     378           0 :                         *pflags |= SEC_ACE_FLAG_OBJECT_INHERIT;
     379           0 :                         p += 2;
     380           0 :                 } else if (strnequal(p, "CI", 2)) {
     381           0 :                         *pflags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
     382           0 :                         p += 2;
     383           0 :                 } else if (strnequal(p, "NP", 2)) {
     384           0 :                         *pflags |= SEC_ACE_FLAG_NO_PROPAGATE_INHERIT;
     385           0 :                         p += 2;
     386           0 :                 } else if (strnequal(p, "IO", 2)) {
     387           0 :                         *pflags |= SEC_ACE_FLAG_INHERIT_ONLY;
     388           0 :                         p += 2;
     389           0 :                 } else if (*p == 'I') {
     390           0 :                         *pflags |= SEC_ACE_FLAG_INHERITED_ACE;
     391           0 :                         p += 1;
     392           0 :                 } else if (*p) {
     393           0 :                         return false;
     394             :                 }
     395             : 
     396           0 :                 switch (*p) {
     397           0 :                 case '|':
     398           0 :                         p++;
     399             : 
     400             :                         FALL_THROUGH;
     401           0 :                 case '\0':
     402           0 :                         continue;
     403           0 :                 default:
     404           0 :                         return false;
     405             :                 }
     406             :         }
     407           0 :         return true;
     408             : }
     409             : 
     410             : /* parse an ACE in the same format as print_ace() */
     411           0 : bool parse_ace(struct cli_state *cli, struct security_ace *ace,
     412             :                const char *orig_str)
     413             : {
     414             :         char *p;
     415             :         const char *cp;
     416             :         char *tok;
     417           0 :         unsigned int atype = 0;
     418           0 :         unsigned int aflags = 0;
     419           0 :         unsigned int amask = 0;
     420             :         struct dom_sid sid;
     421             :         uint32_t mask;
     422             :         const struct perm_value *v;
     423           0 :         char *str = SMB_STRDUP(orig_str);
     424           0 :         TALLOC_CTX *frame = talloc_stackframe();
     425             : 
     426           0 :         if (!str) {
     427           0 :                 TALLOC_FREE(frame);
     428           0 :                 return False;
     429             :         }
     430             : 
     431           0 :         ZERO_STRUCTP(ace);
     432           0 :         p = strchr_m(str,':');
     433           0 :         if (!p) {
     434           0 :                 printf("ACE '%s': missing ':'.\n", orig_str);
     435           0 :                 SAFE_FREE(str);
     436           0 :                 TALLOC_FREE(frame);
     437           0 :                 return False;
     438             :         }
     439           0 :         *p = '\0';
     440           0 :         p++;
     441             : 
     442           0 :         if (!StringToSid(cli, &sid, str)) {
     443           0 :                 printf("ACE '%s': failed to convert '%s' to SID\n",
     444             :                         orig_str, str);
     445           0 :                 SAFE_FREE(str);
     446           0 :                 TALLOC_FREE(frame);
     447           0 :                 return False;
     448             :         }
     449             : 
     450           0 :         cp = p;
     451           0 :         if (!next_token_talloc(frame, &cp, &tok, "/")) {
     452           0 :                 printf("ACE '%s': failed to find '/' character.\n",
     453             :                         orig_str);
     454           0 :                 SAFE_FREE(str);
     455           0 :                 TALLOC_FREE(frame);
     456           0 :                 return False;
     457             :         }
     458             : 
     459           0 :         if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
     460           0 :                 atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
     461           0 :         } else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) {
     462           0 :                 atype = SEC_ACE_TYPE_ACCESS_DENIED;
     463             : 
     464           0 :         } else if (strnequal(tok, "0x", 2)) {
     465             :                 int result;
     466             : 
     467           0 :                 result = sscanf(tok, "%x", &atype);
     468           0 :                 if (result == 0 ||
     469           0 :                     (atype != SEC_ACE_TYPE_ACCESS_ALLOWED &&
     470           0 :                      atype != SEC_ACE_TYPE_ACCESS_DENIED)) {
     471           0 :                         printf("ACE '%s': bad hex value for type at '%s'\n",
     472             :                                orig_str, tok);
     473           0 :                         SAFE_FREE(str);
     474           0 :                         TALLOC_FREE(frame);
     475           0 :                         return false;
     476             :                 }
     477           0 :         } else if(tok[0] >= '0' && tok[0] <= '9') {
     478             :                 int result;
     479             : 
     480           0 :                 result = sscanf(tok, "%u", &atype);
     481           0 :                 if (result == 0 ||
     482           0 :                     (atype != SEC_ACE_TYPE_ACCESS_ALLOWED &&
     483           0 :                      atype != SEC_ACE_TYPE_ACCESS_DENIED)) {
     484           0 :                         printf("ACE '%s': bad integer value for type at '%s'\n",
     485             :                                orig_str, tok);
     486           0 :                         SAFE_FREE(str);
     487           0 :                         TALLOC_FREE(frame);
     488           0 :                         return false;
     489             :                 }
     490             :         } else {
     491           0 :                 printf("ACE '%s': missing 'ALLOWED' or 'DENIED' entry at '%s'\n",
     492             :                         orig_str, tok);
     493           0 :                 SAFE_FREE(str);
     494           0 :                 TALLOC_FREE(frame);
     495           0 :                 return False;
     496             :         }
     497             : 
     498           0 :         if (!next_token_talloc(frame, &cp, &tok, "/")) {
     499           0 :                 printf("ACE '%s': bad flags entry at '%s'\n",
     500             :                         orig_str, tok);
     501           0 :                 SAFE_FREE(str);
     502           0 :                 TALLOC_FREE(frame);
     503           0 :                 return False;
     504             :         }
     505             : 
     506           0 :         if (tok[0] < '0' || tok[0] > '9') {
     507           0 :                 if (!parse_ace_flags(tok, &aflags)) {
     508           0 :                         printf("ACE '%s': bad named flags entry at '%s'\n",
     509             :                                 orig_str, tok);
     510           0 :                         SAFE_FREE(str);
     511           0 :                         TALLOC_FREE(frame);
     512           0 :                         return False;
     513             :                 }
     514           0 :         } else if (strnequal(tok, "0x", 2)) {
     515           0 :                 if (!sscanf(tok, "%x", &aflags)) {
     516           0 :                         printf("ACE '%s': bad hex flags entry at '%s'\n",
     517             :                                 orig_str, tok);
     518           0 :                         SAFE_FREE(str);
     519           0 :                         TALLOC_FREE(frame);
     520           0 :                         return False;
     521             :                 }
     522             :         } else {
     523           0 :                 if (!sscanf(tok, "%u", &aflags)) {
     524           0 :                         printf("ACE '%s': bad integer flags entry at '%s'\n",
     525             :                                 orig_str, tok);
     526           0 :                         SAFE_FREE(str);
     527           0 :                         TALLOC_FREE(frame);
     528           0 :                         return False;
     529             :                 }
     530             :         }
     531             : 
     532           0 :         if (!next_token_talloc(frame, &cp, &tok, "/")) {
     533           0 :                 printf("ACE '%s': missing / at '%s'\n",
     534             :                         orig_str, tok);
     535           0 :                 SAFE_FREE(str);
     536           0 :                 TALLOC_FREE(frame);
     537           0 :                 return False;
     538             :         }
     539             : 
     540           0 :         if (strncmp(tok, "0x", 2) == 0) {
     541           0 :                 if (sscanf(tok, "%x", &amask) != 1) {
     542           0 :                         printf("ACE '%s': bad hex number at '%s'\n",
     543             :                                 orig_str, tok);
     544           0 :                         SAFE_FREE(str);
     545           0 :                         TALLOC_FREE(frame);
     546           0 :                         return False;
     547             :                 }
     548           0 :                 goto done;
     549             :         }
     550             : 
     551           0 :         for (v = standard_values; v->perm; v++) {
     552           0 :                 if (strcmp(tok, v->perm) == 0) {
     553           0 :                         amask = v->mask;
     554           0 :                         goto done;
     555             :                 }
     556             :         }
     557             : 
     558           0 :         p = tok;
     559             : 
     560           0 :         while(*p) {
     561           0 :                 bool found = False;
     562             : 
     563           0 :                 for (v = special_values; v->perm; v++) {
     564           0 :                         if (v->perm[0] == *p) {
     565           0 :                                 amask |= v->mask;
     566           0 :                                 found = True;
     567             :                         }
     568             :                 }
     569             : 
     570           0 :                 if (!found) {
     571           0 :                         printf("ACE '%s': bad permission value at '%s'\n",
     572             :                                 orig_str, p);
     573           0 :                         SAFE_FREE(str);
     574           0 :                         TALLOC_FREE(frame);
     575           0 :                         return False;
     576             :                 }
     577           0 :                 p++;
     578             :         }
     579             : 
     580           0 :         if (*p) {
     581           0 :                 TALLOC_FREE(frame);
     582           0 :                 SAFE_FREE(str);
     583           0 :                 return False;
     584             :         }
     585             : 
     586           0 :  done:
     587           0 :         mask = amask;
     588           0 :         init_sec_ace(ace, &sid, atype, mask, aflags);
     589           0 :         TALLOC_FREE(frame);
     590           0 :         SAFE_FREE(str);
     591           0 :         return True;
     592             : }
     593             : 
     594           0 : static void print_acl_ctrl(FILE *file, uint16_t ctrl, bool numeric)
     595             : {
     596             :         int i;
     597           0 :         const char* separator = "";
     598             : 
     599           0 :         fprintf(file, "CONTROL:");
     600           0 :         if (numeric) {
     601           0 :                 fprintf(file, "0x%x\n", ctrl);
     602           0 :                 return;
     603             :         }
     604             : 
     605           0 :         for (i = ARRAY_SIZE(sec_desc_ctrl_bits) - 1; i >= 0; i--) {
     606           0 :                 if (ctrl & sec_desc_ctrl_bits[i].mask) {
     607           0 :                         fprintf(file, "%s%s",
     608           0 :                                 separator, sec_desc_ctrl_bits[i].str);
     609           0 :                         separator = "|";
     610             :                 }
     611             :         }
     612           0 :         fputc('\n', file);
     613             : }
     614             : 
     615             : /* print a ascii version of a security descriptor on a FILE handle */
     616           0 : void sec_desc_print(struct cli_state *cli, FILE *f,
     617             :                     struct security_descriptor *sd, bool numeric)
     618             : {
     619             :         fstring sidstr;
     620             :         uint32_t i;
     621             : 
     622           0 :         fprintf(f, "REVISION:%d\n", sd->revision);
     623           0 :         print_acl_ctrl(f, sd->type, numeric);
     624             : 
     625             :         /* Print owner and group sid */
     626             : 
     627           0 :         if (sd->owner_sid) {
     628           0 :                 SidToString(cli, sidstr, sd->owner_sid, numeric);
     629             :         } else {
     630           0 :                 fstrcpy(sidstr, "");
     631             :         }
     632             : 
     633           0 :         fprintf(f, "OWNER:%s\n", sidstr);
     634             : 
     635           0 :         if (sd->group_sid) {
     636           0 :                 SidToString(cli, sidstr, sd->group_sid, numeric);
     637             :         } else {
     638           0 :                 fstrcpy(sidstr, "");
     639             :         }
     640             : 
     641           0 :         fprintf(f, "GROUP:%s\n", sidstr);
     642             : 
     643             :         /* Print aces */
     644           0 :         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
     645           0 :                 struct security_ace *ace = &sd->dacl->aces[i];
     646           0 :                 fprintf(f, "ACL:");
     647           0 :                 print_ace(cli, f, ace, numeric);
     648           0 :                 fprintf(f, "\n");
     649             :         }
     650             : 
     651           0 : }

Generated by: LCOV version 1.13