s4:dsdb: Fix stack use after scope in gkdi_create_root_key()
[samba.git] / source3 / lib / util_sd.c
index 9a7b34fa5d79d1ccf1ea1047f50913db995a5287..23f37b7e7347315a2066ab39816ae23891a8cec0 100644 (file)
@@ -28,6 +28,7 @@
 #include "../libcli/security/security.h"
 #include "rpc_client/cli_pipe.h"
 #include "rpc_client/cli_lsarpc.h"
+#include "lib/util/string_wrappers.h"
 
 /* These values discovered by inspection */
 
@@ -49,6 +50,7 @@ static const struct perm_value special_values[] = {
 static const struct perm_value standard_values[] = {
        { "READ",   SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE },
        { "CHANGE", SEC_RIGHTS_DIR_READ|SEC_STD_DELETE|\
+         SEC_DIR_DELETE_CHILD|\
          SEC_RIGHTS_DIR_WRITE|SEC_DIR_TRAVERSE },
        { "FULL",   SEC_RIGHTS_DIR_ALL },
        { NULL, 0 },
@@ -84,7 +86,8 @@ static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
                                   enum lsa_SidType *type,
                                   char **domain, char **name)
 {
-       uint16_t orig_cnum = cli_state_get_tid(cli);
+       struct smbXcli_tcon *orig_tcon = NULL;
+       char *orig_share = NULL;
        struct rpc_pipe_client *p = NULL;
        struct policy_handle handle;
        NTSTATUS status;
@@ -93,7 +96,11 @@ static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
        char **domains;
        char **names;
 
-       status = cli_tree_connect(cli, "IPC$", "?????", "", 0);
+       if (cli_state_has_tcon(cli)) {
+               cli_state_save_tcon_share(cli, &orig_tcon, &orig_share);
+       }
+
+       status = cli_tree_connect(cli, "IPC$", "?????", NULL);
        if (!NT_STATUS_IS_OK(status)) {
                goto tcon_fail;
        }
@@ -125,7 +132,7 @@ static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
        TALLOC_FREE(p);
        cli_tdis(cli);
  tcon_fail:
-       cli_state_set_tid(cli, orig_cnum);
+       cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
        TALLOC_FREE(frame);
        return status;
 }
@@ -165,15 +172,20 @@ static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
                                    enum lsa_SidType *type,
                                    struct dom_sid *sid)
 {
-       uint16_t orig_cnum = cli_state_get_tid(cli);
-       struct rpc_pipe_client *p;
+       struct smbXcli_tcon *orig_tcon = NULL;
+       char *orig_share = NULL;
+       struct rpc_pipe_client *p = NULL;
        struct policy_handle handle;
        NTSTATUS status;
        TALLOC_CTX *frame = talloc_stackframe();
        struct dom_sid *sids;
        enum lsa_SidType *types;
 
-       status = cli_tree_connect(cli, "IPC$", "?????", "", 0);
+       if (cli_state_has_tcon(cli)) {
+               cli_state_save_tcon_share(cli, &orig_tcon, &orig_share);
+       }
+
+       status = cli_tree_connect(cli, "IPC$", "?????", NULL);
        if (!NT_STATUS_IS_OK(status)) {
                goto tcon_fail;
        }
@@ -204,7 +216,7 @@ static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
        TALLOC_FREE(p);
        cli_tdis(cli);
  tcon_fail:
-       cli_state_set_tid(cli, orig_cnum);
+       cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
        TALLOC_FREE(frame);
        return status;
 }
@@ -228,53 +240,34 @@ bool StringToSid(struct cli_state *cli, struct dom_sid *sid, const char *str)
 static void print_ace_flags(FILE *f, uint8_t flags)
 {
        char *str = talloc_strdup(NULL, "");
-
-       if (!str) {
-               goto out;
-       }
+       size_t len;
 
        if (flags & SEC_ACE_FLAG_OBJECT_INHERIT) {
-               str = talloc_asprintf(str, "%s%s",
-                               str, "OI|");
-               if (!str) {
-                       goto out;
-               }
+               talloc_asprintf_addbuf(&str, "OI|");
        }
        if (flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
-               str = talloc_asprintf(str, "%s%s",
-                               str, "CI|");
-               if (!str) {
-                       goto out;
-               }
+               talloc_asprintf_addbuf(&str, "CI|");
        }
        if (flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
-               str = talloc_asprintf(str, "%s%s",
-                               str, "NP|");
-               if (!str) {
-                       goto out;
-               }
+               talloc_asprintf_addbuf(&str, "NP|");
        }
        if (flags & SEC_ACE_FLAG_INHERIT_ONLY) {
-               str = talloc_asprintf(str, "%s%s",
-                               str, "IO|");
-               if (!str) {
-                       goto out;
-               }
+               talloc_asprintf_addbuf(&str, "IO|");
        }
        if (flags & SEC_ACE_FLAG_INHERITED_ACE) {
-               str = talloc_asprintf(str, "%s%s",
-                               str, "I|");
-               if (!str) {
-                       goto out;
-               }
+               talloc_asprintf_addbuf(&str, "I|");
        }
+       if (str == NULL) {
+               goto out;
+       }
+
        /* Ignore define SEC_ACE_FLAG_SUCCESSFUL_ACCESS ( 0x40 )
           and SEC_ACE_FLAG_FAILED_ACCESS ( 0x80 ) as they're
           audit ace flags. */
 
-       if (str[strlen(str)-1] == '|') {
-               str[strlen(str)-1] = '\0';
-               fprintf(f, "/%s/", str);
+       len = strlen(str);
+       if (len > 0) {
+               fprintf(f, "/%.*s/", (int)len-1, str);
        } else {
                fprintf(f, "/0x%x/", flags);
        }
@@ -378,6 +371,8 @@ static bool parse_ace_flags(const char *str, unsigned int *pflags)
                switch (*p) {
                case '|':
                        p++;
+
+                       FALL_THROUGH;
                case '\0':
                        continue;
                default: