s3-rpc_cli: pass down ndr_interface_table to cli_rpc_pipe_open_noauth().
[metze/samba/wip.git] / source3 / utils / smbcacls.c
index 50cc9a6a0c83dd1e4bfb418b23d829f067978996..d3d60bc8eaf21a60038f4ee13c74e55a7554a618 100644 (file)
@@ -41,6 +41,10 @@ static int test_args;
 static int numeric;
 
 static int sddl;
+static int query_sec_info = -1;
+static int set_sec_info = -1;
+
+static const char *domain_sid = NULL;
 
 enum acl_mode {SMB_ACL_SET, SMB_ACL_DELETE, SMB_ACL_MODIFY, SMB_ACL_ADD };
 enum chown_mode {REQUEST_NONE, REQUEST_CHOWN, REQUEST_CHGRP, REQUEST_INHERIT};
@@ -87,12 +91,12 @@ static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
        char **domains;
        char **names;
 
-       status = cli_tcon_andx(cli, "IPC$", "?????", "", 0);
+       status = cli_tree_connect(cli, "IPC$", "?????", "", 0);
        if (!NT_STATUS_IS_OK(status)) {
-               return status;
+               goto tcon_fail;
        }
 
-       status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
+       status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
                                          &p);
        if (!NT_STATUS_IS_OK(status)) {
                goto fail;
@@ -118,6 +122,7 @@ static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
  fail:
        TALLOC_FREE(p);
        cli_tdis(cli);
+ tcon_fail:
        cli_state_set_tid(cli, orig_cnum);
        TALLOC_FREE(frame);
        return status;
@@ -136,12 +141,12 @@ static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
        struct dom_sid *sids;
        enum lsa_SidType *types;
 
-       status = cli_tcon_andx(cli, "IPC$", "?????", "", 0);
+       status = cli_tree_connect(cli, "IPC$", "?????", "", 0);
        if (!NT_STATUS_IS_OK(status)) {
-               return status;
+               goto tcon_fail;
        }
 
-       status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
+       status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
                                          &p);
        if (!NT_STATUS_IS_OK(status)) {
                goto fail;
@@ -166,6 +171,7 @@ static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
  fail:
        TALLOC_FREE(p);
        cli_tdis(cli);
+ tcon_fail:
        cli_state_set_tid(cli, orig_cnum);
        TALLOC_FREE(frame);
        return status;
@@ -181,14 +187,13 @@ static NTSTATUS cli_lsa_lookup_domain_sid(struct cli_state *cli,
        struct policy_handle handle;
        NTSTATUS status, result;
        TALLOC_CTX *frame = talloc_stackframe();
-       const struct ndr_syntax_id *lsarpc_syntax = &ndr_table_lsarpc.syntax_id;
 
-       status = cli_tcon_andx(cli, "IPC$", "?????", "", 0);
+       status = cli_tree_connect(cli, "IPC$", "?????", "", 0);
        if (!NT_STATUS_IS_OK(status)) {
                goto done;
        }
 
-       status = cli_rpc_pipe_open_noauth(cli, lsarpc_syntax, &rpc_pipe);
+       status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc, &rpc_pipe);
        if (!NT_STATUS_IS_OK(status)) {
                goto tdis;
        }
@@ -219,7 +224,8 @@ done:
        return status;
 }
 
-struct dom_sid* get_domain_sid(struct cli_state *cli) {
+static struct dom_sid *get_domain_sid(struct cli_state *cli)
+{
        NTSTATUS status;
 
        struct dom_sid *sid = talloc(talloc_tos(), struct dom_sid);
@@ -228,14 +234,22 @@ struct dom_sid* get_domain_sid(struct cli_state *cli) {
                return NULL;
        }
 
-       status = cli_lsa_lookup_domain_sid(cli, sid);
-       if (!NT_STATUS_IS_OK(status)) {
-               TALLOC_FREE(sid);
-               DEBUG(0,("failed to lookup domain sid: %s\n", nt_errstr(status)));
+       if (domain_sid) {
+               if (!dom_sid_parse(domain_sid, sid)) {
+                       DEBUG(0,("failed to parse domain sid\n"));
+                       TALLOC_FREE(sid);
+               }
        } else {
-               DEBUG(2,("Domain SID: %s\n", sid_string_dbg(sid)));
+               status = cli_lsa_lookup_domain_sid(cli, sid);
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(0,("failed to lookup domain sid: %s\n", nt_errstr(status)));
+                       TALLOC_FREE(sid);
+               }
+
        }
 
+       DEBUG(2,("Domain SID: %s\n", sid_string_dbg(sid)));
        return sid;
 }
 
@@ -822,11 +836,27 @@ static struct security_descriptor *get_secdesc(struct cli_state *cli, const char
        uint16_t fnum = (uint16_t)-1;
        struct security_descriptor *sd;
        NTSTATUS status;
+       uint32_t sec_info;
+       uint32_t desired_access = 0;
 
-       /* The desired access below is the only one I could find that works
-          with NT4, W2KP and Samba */
+       if (query_sec_info == -1) {
+               sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
+       } else {
+               sec_info = query_sec_info;
+       }
 
-       status = cli_ntcreate(cli, filename, 0, CREATE_ACCESS_READ,
+       if (sec_info & (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL)) {
+               desired_access |= SEC_STD_READ_CONTROL;
+       }
+       if (sec_info & SECINFO_SACL) {
+               desired_access |= SEC_FLAG_SYSTEM_SECURITY;
+       }
+
+       if (desired_access == 0) {
+               desired_access |= SEC_STD_READ_CONTROL;
+       }
+
+       status = cli_ntcreate(cli, filename, 0, desired_access,
                              0, FILE_SHARE_READ|FILE_SHARE_WRITE,
                              FILE_OPEN, 0x0, 0x0, &fnum);
        if (!NT_STATUS_IS_OK(status)) {
@@ -834,7 +864,8 @@ static struct security_descriptor *get_secdesc(struct cli_state *cli, const char
                return NULL;
        }
 
-       status = cli_query_secdesc(cli, fnum, talloc_tos(), &sd);
+       status = cli_query_security_descriptor(cli, fnum, sec_info,
+                                              talloc_tos(), &sd);
 
        cli_close(cli, fnum);
 
@@ -855,12 +886,41 @@ static bool set_secdesc(struct cli_state *cli, const char *filename,
        uint16_t fnum = (uint16_t)-1;
         bool result=true;
        NTSTATUS status;
+       uint32_t desired_access = 0;
+       uint32_t sec_info;
 
-       /* The desired access below is the only one I could find that works
-          with NT4, W2KP and Samba */
+       if (set_sec_info == -1) {
+               sec_info = 0;
+
+               if (sd->dacl || (sd->type & SEC_DESC_DACL_PRESENT)) {
+                       sec_info |= SECINFO_DACL;
+               }
+               if (sd->sacl || (sd->type & SEC_DESC_SACL_PRESENT)) {
+                       sec_info |= SECINFO_SACL;
+               }
+               if (sd->owner_sid) {
+                       sec_info |= SECINFO_OWNER;
+               }
+               if (sd->group_sid) {
+                       sec_info |= SECINFO_GROUP;
+               }
+       } else {
+               sec_info = set_sec_info;
+       }
+
+       /* Make the desired_access more specific. */
+       if (sec_info & SECINFO_DACL) {
+               desired_access |= SEC_STD_WRITE_DAC;
+       }
+       if (sec_info & SECINFO_SACL) {
+               desired_access |= SEC_FLAG_SYSTEM_SECURITY;
+       }
+       if (sec_info & (SECINFO_OWNER | SECINFO_GROUP)) {
+               desired_access |= SEC_STD_WRITE_OWNER;
+       }
 
        status = cli_ntcreate(cli, filename, 0,
-                             WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS,
+                             desired_access,
                              0, FILE_SHARE_READ|FILE_SHARE_WRITE,
                              FILE_OPEN, 0x0, 0x0, &fnum);
        if (!NT_STATUS_IS_OK(status)) {
@@ -868,7 +928,7 @@ static bool set_secdesc(struct cli_state *cli, const char *filename,
                return false;
        }
 
-       status = cli_set_secdesc(cli, fnum, sd);
+       status = cli_set_security_descriptor(cli, fnum, sec_info, sd);
        if (!NT_STATUS_IS_OK(status)) {
                printf("ERROR: security description set failed: %s\n",
                        nt_errstr(status));
@@ -884,25 +944,29 @@ dump the acls for a file
 *******************************************************/
 static int cacl_dump(struct cli_state *cli, const char *filename)
 {
-       int result = EXIT_FAILED;
        struct security_descriptor *sd;
 
-       if (test_args)
+       if (test_args) {
                return EXIT_OK;
+       }
 
        sd = get_secdesc(cli, filename);
+       if (sd == NULL) {
+               return EXIT_FAILED;
+       }
 
-       if (sd) {
-               if (sddl) {
-                       printf("%s\n", sddl_encode(talloc_tos(), sd,
-                                          get_domain_sid(cli)));
-               } else {
-                       sec_desc_print(cli, stdout, sd);
+       if (sddl) {
+               char *str = sddl_encode(talloc_tos(), sd, get_domain_sid(cli));
+               if (str == NULL) {
+                       return EXIT_FAILED;
                }
-               result = EXIT_OK;
+               printf("%s\n", str);
+               TALLOC_FREE(str);
+       } else {
+               sec_desc_print(cli, stdout, sd);
        }
 
-       return result;
+       return EXIT_OK;
 }
 
 /***************************************************** 
@@ -1313,7 +1377,14 @@ static struct cli_state *connect_one(struct user_auth_info *auth_info,
                { "inherit", 'I', POPT_ARG_STRING, NULL, 'I', "Inherit allow|remove|copy" },
                { "numeric", 0, POPT_ARG_NONE, &numeric, 1, "Don't resolve sids or masks to names" },
                { "sddl", 0, POPT_ARG_NONE, &sddl, 1, "Output and input acls in sddl format" },
+               { "query-security-info", 0, POPT_ARG_INT, &query_sec_info, 1,
+                 "The security-info flags for queries"
+               },
+               { "set-security-info", 0, POPT_ARG_INT, &set_sec_info, 1,
+                 "The security-info flags for modifications"
+               },
                { "test-args", 't', POPT_ARG_NONE, &test_args, 1, "Test arguments"},
+               { "domain-sid", 0, POPT_ARG_STRING, &domain_sid, 0, "Domain SID for sddl", "SID"},
                POPT_COMMON_SAMBA
                POPT_COMMON_CONNECTION
                POPT_COMMON_CREDENTIALS
@@ -1408,6 +1479,9 @@ static struct cli_state *connect_one(struct user_auth_info *auth_info,
                return -1;
        }
 
+       poptFreeContext(pc);
+       popt_burn_cmdline_password(argc, argv);
+
        string_replace(path,'/','\\');
 
        server = talloc_strdup(frame, path+2);