r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation
[samba.git] / source3 / rpcclient / cmd_lsarpc.c
index 56ae4c6e68a337fda28aa2874a834c4454382f5f..2b8279ccd2e8c73373279517e0f5b3d1b27f2767 100644 (file)
@@ -1,8 +1,9 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    RPC pipe client
 
-   Copyright (C) Tim Potter 2000
+   Copyright (C) Tim Potter              2000
+   Copyright (C) Rafal Szczesniak        2002
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include "includes.h"
 #include "rpcclient.h"
 
+
+/* useful function to allow entering a name instead of a SID and
+ * looking it up automatically */
+static NTSTATUS name_to_sid(struct cli_state *cli, 
+                           TALLOC_CTX *mem_ctx,
+                           DOM_SID *sid, const char *name)
+{
+       POLICY_HND pol;
+       uint32 *sid_types;
+       NTSTATUS result;
+       DOM_SID *sids;
+
+       /* maybe its a raw SID */
+       if (strncmp(name, "S-", 2) == 0 &&
+           string_to_sid(sid, name)) {
+               return NT_STATUS_OK;
+       }
+
+       result = cli_lsa_open_policy(cli, mem_ctx, True, 
+                                    SEC_RIGHTS_MAXIMUM_ALLOWED,
+                                    &pol);
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       result = cli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, &sids, &sid_types);
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       cli_lsa_close(cli, mem_ctx, &pol);
+
+       *sid = sids[0];
+
+done:
+       return result;
+}
+
+
 /* Look up domain related information on a remote host */
 
 static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli, 
                                           TALLOC_CTX *mem_ctx, int argc, 
-                                          char **argv) 
+                                          const char **argv) 
 {
        POLICY_HND pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       DOM_SID dom_sid;
-       fstring sid_str, domain_name;
+       DOM_SID *dom_sid;
+       struct uuid *dom_guid;
+       fstring sid_str;
+       char *domain_name = NULL;
+       char *dns_name = NULL;
+       char *forest_name = NULL;
+
        uint32 info_class = 3;
 
        if (argc > 2) {
@@ -42,28 +85,51 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli,
        if (argc == 2)
                info_class = atoi(argv[1]);
        
-       result = cli_lsa_open_policy(cli, mem_ctx, True, 
+       /* Lookup info policy */
+       switch (info_class) {
+       case 12:
+               result = cli_lsa_open_policy2(cli, mem_ctx, True, 
+                                            SEC_RIGHTS_MAXIMUM_ALLOWED,
+                                            &pol);
+
+               if (!NT_STATUS_IS_OK(result))
+                       goto done;
+               result = cli_lsa_query_info_policy2(cli, mem_ctx, &pol,
+                                                   info_class, &domain_name,
+                                                   &dns_name, &forest_name,
+                                                   &dom_guid, &dom_sid);
+               break;
+       default:
+               result = cli_lsa_open_policy(cli, mem_ctx, True, 
                                     SEC_RIGHTS_MAXIMUM_ALLOWED,
                                     &pol);
 
-       if (!NT_STATUS_IS_OK(result))
-               goto done;
-
-       /* Lookup info policy */
-
-       result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, 
-                                          domain_name, &dom_sid);
+               if (!NT_STATUS_IS_OK(result))
+                       goto done;
+               result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, 
+                                                  info_class, &domain_name, 
+                                                  &dom_sid);
+       }
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
+       
+       sid_to_string(sid_str, dom_sid);
 
-       sid_to_string(sid_str, &dom_sid);
-
-       if (domain_name[0])
+       if (domain_name)
                printf("domain %s has sid %s\n", domain_name, sid_str);
        else
                printf("could not query info for level %d\n", info_class);
 
+       if (dns_name)
+               printf("domain dns name is %s\n", dns_name);
+       if (forest_name)
+               printf("forest name is %s\n", forest_name);
+
+       if (info_class == 12) {
+               printf("domain GUID is ");
+               smb_uuid_string_static(*dom_guid);
+       }
  done:
        return result;
 }
@@ -72,7 +138,7 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli,
 
 static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli, 
                                      TALLOC_CTX *mem_ctx, int argc, 
-                                     char **argv)
+                                     const char **argv)
 {
        POLICY_HND pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -95,18 +161,19 @@ static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
        result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1, 
                                      (const char**)(argv + 1), &sids, &types);
 
-       if (!NT_STATUS_IS_OK(result) && 
-           NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED))
+       if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 
+           NT_STATUS_V(STATUS_SOME_UNMAPPED))
                goto done;
 
+       result = NT_STATUS_OK;
+
        /* Print results */
 
        for (i = 0; i < (argc - 1); i++) {
                fstring sid_str;
-
                sid_to_string(sid_str, &sids[i]);
-               printf("%s %s (%d)\n", argv[i + 1], sid_str,
-                      types[i]);
+               printf("%s %s (%s: %d)\n", argv[i + 1], sid_str,
+                      sid_type_lookup(types[i]), types[i]);
        }
 
  done:
@@ -116,7 +183,7 @@ static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
 /* Resolve a list of SIDs to a list of names */
 
 static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                    int argc, char **argv)
+                                    int argc, const char **argv)
 {
        POLICY_HND pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -140,32 +207,37 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Convert arguments to sids */
 
-       sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * (argc - 1));
+       sids = TALLOC_ARRAY(mem_ctx, DOM_SID, argc - 1);
 
        if (!sids) {
                printf("could not allocate memory for %d sids\n", argc - 1);
                goto done;
        }
 
-       for (i = 0; i < (argc - 1); i++)
-               string_to_sid(&sids[i], argv[i + 1]);
+       for (i = 0; i < argc - 1; i++) 
+               if (!string_to_sid(&sids[i], argv[i + 1])) {
+                       result = NT_STATUS_INVALID_SID;
+                       goto done;
+               }
 
        /* Lookup the SIDs */
 
        result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids, 
                                     &domains, &names, &types);
 
-       if (!NT_STATUS_IS_OK(result) && 
-           NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED))
+       if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 
+           NT_STATUS_V(STATUS_SOME_UNMAPPED))
                goto done;
 
+       result = NT_STATUS_OK;
+
        /* Print results */
 
        for (i = 0; i < (argc - 1); i++) {
                fstring sid_str;
 
                sid_to_string(sid_str, &sids[i]);
-               printf("%s [%s]\\[%s] (%d)\n", sid_str, 
+               printf("%s %s\\%s (%d)\n", sid_str, 
                       domains[i] ? domains[i] : "*unknown*", 
                       names[i] ? names[i] : "*unknown*", types[i]);
        }
@@ -178,23 +250,29 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
 static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli, 
                                        TALLOC_CTX *mem_ctx, int argc, 
-                                       char **argv)
+                                       const char **argv)
 {
        POLICY_HND pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        DOM_SID *domain_sids;
        char **domain_names;
+
+       /* defaults, but may be changed using params */
        uint32 enum_ctx = 0;
-       uint32 num_domains;
+       uint32 num_domains = 0;
        int i;
 
-       if (argc != 1) {
-               printf("Usage: %s\n", argv[0]);
+       if (argc > 2) {
+               printf("Usage: %s [enum context (0)]\n", argv[0]);
                return NT_STATUS_OK;
        }
 
+       if (argc == 2 && argv[1]) {
+               enum_ctx = atoi(argv[2]);
+       }       
+
        result = cli_lsa_open_policy(cli, mem_ctx, True, 
-                                    SEC_RIGHTS_MAXIMUM_ALLOWED,
+                                    POLICY_VIEW_LOCAL_INFORMATION,
                                     &pol);
 
        if (!NT_STATUS_IS_OK(result))
@@ -203,14 +281,14 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
        /* Lookup list of trusted domains */
 
        result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
-                                       &num_domains, &domain_names,
-                                       &domain_sids);
-
-       if (!NT_STATUS_IS_OK(result))
-               goto done;
-
-       /* Print results */
-
+                                       &num_domains,
+                                       &domain_names, &domain_sids);
+       if (!NT_STATUS_IS_OK(result) &&
+           !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
+           !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
+           goto done;
+
+       /* Print results: list of names and sids returned in this response. */   
        for (i = 0; i < num_domains; i++) {
                fstring sid_str;
 
@@ -226,8 +304,8 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
 /* Enumerates privileges */
 
 static NTSTATUS cmd_lsa_enum_privilege(struct cli_state *cli, 
-                                          TALLOC_CTX *mem_ctx, int argc, 
-                                          char **argv) 
+                                      TALLOC_CTX *mem_ctx, int argc, 
+                                      const char **argv) 
 {
        POLICY_HND pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -280,7 +358,7 @@ static NTSTATUS cmd_lsa_enum_privilege(struct cli_state *cli,
 
 static NTSTATUS cmd_lsa_get_dispname(struct cli_state *cli, 
                                      TALLOC_CTX *mem_ctx, int argc, 
-                                     char **argv) 
+                                     const char **argv) 
 {
        POLICY_HND pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -317,8 +395,8 @@ static NTSTATUS cmd_lsa_get_dispname(struct cli_state *cli,
 /* Enumerate the LSA SIDS */
 
 static NTSTATUS cmd_lsa_enum_sids(struct cli_state *cli, 
-                                     TALLOC_CTX *mem_ctx, int argc, 
-                                     char **argv) 
+                                 TALLOC_CTX *mem_ctx, int argc, 
+                                 const char **argv) 
 {
        POLICY_HND pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -371,7 +449,7 @@ static NTSTATUS cmd_lsa_enum_sids(struct cli_state *cli,
 
 static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli, 
                                            TALLOC_CTX *mem_ctx, int argc, 
-                                           char **argv) 
+                                           const char **argv) 
 {
        POLICY_HND dom_pol;
        POLICY_HND user_pol;
@@ -388,7 +466,9 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli,
                return NT_STATUS_OK;
        }
 
-       string_to_sid(&sid, argv[1]);
+       result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
+       if (!NT_STATUS_IS_OK(result))
+               goto done;      
 
        result = cli_lsa_open_policy2(cli, mem_ctx, True, 
                                     SEC_RIGHTS_MAXIMUM_ALLOWED,
@@ -419,11 +499,135 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli,
        return result;
 }
 
+
+/* Enumerate the privileges of an SID via LsaEnumerateAccountRights */
+
+static NTSTATUS cmd_lsa_enum_acct_rights(struct cli_state *cli, 
+                                        TALLOC_CTX *mem_ctx, int argc, 
+                                        const char **argv) 
+{
+       POLICY_HND dom_pol;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       DOM_SID sid;
+       uint32 count;
+       char **rights;
+
+       int i;
+
+       if (argc != 2 ) {
+               printf("Usage: %s SID\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
+       if (!NT_STATUS_IS_OK(result))
+               goto done;      
+
+       result = cli_lsa_open_policy2(cli, mem_ctx, True, 
+                                    SEC_RIGHTS_MAXIMUM_ALLOWED,
+                                    &dom_pol);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       result = cli_lsa_enum_account_rights(cli, mem_ctx, &dom_pol, sid, &count, &rights);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       printf("found %d privileges for SID %s\n", count, sid_string_static(&sid));
+
+       for (i = 0; i < count; i++) {
+               printf("\t%s\n", rights[i]);
+       }
+
+ done:
+       return result;
+}
+
+
+/* add some privileges to a SID via LsaAddAccountRights */
+
+static NTSTATUS cmd_lsa_add_acct_rights(struct cli_state *cli, 
+                                       TALLOC_CTX *mem_ctx, int argc, 
+                                       const char **argv) 
+{
+       POLICY_HND dom_pol;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       DOM_SID sid;
+
+       if (argc < 3 ) {
+               printf("Usage: %s SID [rights...]\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
+       if (!NT_STATUS_IS_OK(result))
+               goto done;      
+
+       result = cli_lsa_open_policy2(cli, mem_ctx, True, 
+                                    SEC_RIGHTS_MAXIMUM_ALLOWED,
+                                    &dom_pol);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       result = cli_lsa_add_account_rights(cli, mem_ctx, &dom_pol, sid, 
+                                           argc-2, argv+2);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+ done:
+       return result;
+}
+
+
+/* remove some privileges to a SID via LsaRemoveAccountRights */
+
+static NTSTATUS cmd_lsa_remove_acct_rights(struct cli_state *cli, 
+                                       TALLOC_CTX *mem_ctx, int argc, 
+                                       const char **argv) 
+{
+       POLICY_HND dom_pol;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       DOM_SID sid;
+
+       if (argc < 3 ) {
+               printf("Usage: %s SID [rights...]\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
+       if (!NT_STATUS_IS_OK(result))
+               goto done;      
+
+       result = cli_lsa_open_policy2(cli, mem_ctx, True, 
+                                    SEC_RIGHTS_MAXIMUM_ALLOWED,
+                                    &dom_pol);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       result = cli_lsa_remove_account_rights(cli, mem_ctx, &dom_pol, sid, 
+                                              False, argc-2, argv+2);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+ done:
+       return result;
+}
+
+
 /* Get a privilege value given its name */
 
 static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli, 
-                                           TALLOC_CTX *mem_ctx, int argc, 
-                                           char **argv) 
+                                       TALLOC_CTX *mem_ctx, int argc, 
+                                       const char **argv) 
 {
        POLICY_HND pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -447,6 +651,7 @@ static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli,
                goto done;
 
        /* Print results */
+
        printf("%u:%u (0x%x:0x%x)\n", luid.high, luid.low, luid.high, luid.low);
 
  done:
@@ -457,7 +662,7 @@ static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli,
 
 static NTSTATUS cmd_lsa_query_secobj(struct cli_state *cli, 
                                     TALLOC_CTX *mem_ctx, int argc, 
-                                    char **argv) 
+                                    const char **argv) 
 {
        POLICY_HND pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -489,22 +694,26 @@ static NTSTATUS cmd_lsa_query_secobj(struct cli_state *cli,
        return result;
 }
 
+
 /* List of commands exported by this module */
 
 struct cmd_set lsarpc_commands[] = {
 
        { "LSARPC" },
 
-       { "lsaquery",            cmd_lsa_query_info_policy,  PIPE_LSARPC, "Query info policy",                    "" },
-       { "lookupsids",          cmd_lsa_lookup_sids,        PIPE_LSARPC, "Convert SIDs to names",                "" },
-       { "lookupnames",         cmd_lsa_lookup_names,       PIPE_LSARPC, "Convert names to SIDs",                "" },
-       { "enumtrust",           cmd_lsa_enum_trust_dom,     PIPE_LSARPC, "Enumerate trusted domains",            "" },
-       { "enumprivs",           cmd_lsa_enum_privilege,     PIPE_LSARPC, "Enumerate privileges",                 "" },
-       { "getdispname",         cmd_lsa_get_dispname,       PIPE_LSARPC, "Get the privilege name",               "" },
-       { "lsaenumsid",          cmd_lsa_enum_sids,          PIPE_LSARPC, "Enumerate the LSA SIDS",               "" },
-       { "lsaenumprivsaccount", cmd_lsa_enum_privsaccounts, PIPE_LSARPC, "Enumerate the privileges of an SID",   "" },
-       { "lsalookupprivvalue",  cmd_lsa_lookupprivvalue,    PIPE_LSARPC, "Get a privilege value given its name", "" },
-       { "lsaquerysecobj",      cmd_lsa_query_secobj,       PIPE_LSARPC, "Query LSA security object", "" },
+       { "lsaquery",            RPC_RTYPE_NTSTATUS, cmd_lsa_query_info_policy,  NULL, PI_LSARPC, "Query info policy",                    "" },
+       { "lookupsids",          RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_sids,        NULL, PI_LSARPC, "Convert SIDs to names",                "" },
+       { "lookupnames",         RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_names,       NULL, PI_LSARPC, "Convert names to SIDs",                "" },
+       { "enumtrust",           RPC_RTYPE_NTSTATUS, cmd_lsa_enum_trust_dom,     NULL, PI_LSARPC, "Enumerate trusted domains",            "Usage: [preferred max number] [enum context (0)]" },
+       { "enumprivs",           RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privilege,     NULL, PI_LSARPC, "Enumerate privileges",                 "" },
+       { "getdispname",         RPC_RTYPE_NTSTATUS, cmd_lsa_get_dispname,       NULL, PI_LSARPC, "Get the privilege name",               "" },
+       { "lsaenumsid",          RPC_RTYPE_NTSTATUS, cmd_lsa_enum_sids,          NULL, PI_LSARPC, "Enumerate the LSA SIDS",               "" },
+       { "lsaenumprivsaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privsaccounts, NULL, PI_LSARPC, "Enumerate the privileges of an SID",   "" },
+       { "lsaenumacctrights",   RPC_RTYPE_NTSTATUS, cmd_lsa_enum_acct_rights,   NULL, PI_LSARPC, "Enumerate the rights of an SID",   "" },
+       { "lsaaddacctrights",    RPC_RTYPE_NTSTATUS, cmd_lsa_add_acct_rights,    NULL, PI_LSARPC, "Add rights to an account",   "" },
+       { "lsaremoveacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_remove_acct_rights, NULL, PI_LSARPC, "Remove rights from an account",   "" },
+       { "lsalookupprivvalue",  RPC_RTYPE_NTSTATUS, cmd_lsa_lookupprivvalue,    NULL, PI_LSARPC, "Get a privilege value given its name", "" },
+       { "lsaquerysecobj",      RPC_RTYPE_NTSTATUS, cmd_lsa_query_secobj,       NULL, PI_LSARPC, "Query LSA security object", "" },
 
        { NULL }
 };