RIP BOOL. Convert BOOL -> bool. I found a few interesting
[kai/samba.git] / source3 / rpcclient / cmd_samr.c
index 6649676887d45c7cc1bcee65d40bd5c6d66c98d7..931baf3534341059735e75ac5661367f3cc7ae9d 100644 (file)
@@ -9,7 +9,7 @@
 
    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
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -18,8 +18,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -34,7 +33,7 @@ static void display_sam_user_info_7(SAM_USER_INFO_7 *usr)
 {
        fstring temp;
 
-       unistr2_to_ascii(temp, &usr->uni_name, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &usr->uni_name, sizeof(temp));
        printf("\tUser Name   :\t%s\n", temp);
 }
 
@@ -46,6 +45,14 @@ static void display_sam_user_info_9(SAM_USER_INFO_9 *usr)
        printf("\tPrimary group RID   :\tox%x\n", usr->rid_group);
 }
 
+/****************************************************************************
+ display sam_user_info_16 structure
+ ****************************************************************************/
+static void display_sam_user_info_16(SAM_USER_INFO_16 *usr)
+{
+       printf("\tAcct Flags   :\tox%x\n", usr->acb_info);
+}
+
 /****************************************************************************
  display sam_user_info_21 structure
  ****************************************************************************/
@@ -53,34 +60,34 @@ static void display_sam_user_info_21(SAM_USER_INFO_21 *usr)
 {
        fstring temp;
 
-       unistr2_to_ascii(temp, &usr->uni_user_name, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &usr->uni_user_name, sizeof(temp));
        printf("\tUser Name   :\t%s\n", temp);
        
-       unistr2_to_ascii(temp, &usr->uni_full_name, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &usr->uni_full_name, sizeof(temp));
        printf("\tFull Name   :\t%s\n", temp);
        
-       unistr2_to_ascii(temp, &usr->uni_home_dir, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &usr->uni_home_dir, sizeof(temp));
        printf("\tHome Drive  :\t%s\n", temp);
        
-       unistr2_to_ascii(temp, &usr->uni_dir_drive, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &usr->uni_dir_drive, sizeof(temp));
        printf("\tDir Drive   :\t%s\n", temp);
        
-       unistr2_to_ascii(temp, &usr->uni_profile_path, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &usr->uni_profile_path, sizeof(temp));
        printf("\tProfile Path:\t%s\n", temp);
        
-       unistr2_to_ascii(temp, &usr->uni_logon_script, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &usr->uni_logon_script, sizeof(temp));
        printf("\tLogon Script:\t%s\n", temp);
        
-       unistr2_to_ascii(temp, &usr->uni_acct_desc, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &usr->uni_acct_desc, sizeof(temp));
        printf("\tDescription :\t%s\n", temp);
        
-       unistr2_to_ascii(temp, &usr->uni_workstations, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &usr->uni_workstations, sizeof(temp));
        printf("\tWorkstations:\t%s\n", temp);
        
-       unistr2_to_ascii(temp, &usr->uni_comment, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &usr->uni_comment, sizeof(temp));
        printf("\tUnknown Str :\t%s\n", temp);
        
-       unistr2_to_ascii(temp, &usr->uni_munged_dial, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &usr->uni_munged_dial, sizeof(temp));
        printf("\tRemote Dial :\t%s\n", temp);
        
        printf("\tLogon Time               :\t%s\n", 
@@ -152,20 +159,20 @@ static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2)
 {
        fstring name;
 
-       unistr2_to_ascii(name, &info2->uni_domain, sizeof(name) - 1); 
+       unistr2_to_ascii(name, &info2->uni_domain, sizeof(name));
        printf("Domain:\t\t%s\n", name);
 
-       unistr2_to_ascii(name, &info2->uni_server, sizeof(name) - 1); 
+       unistr2_to_ascii(name, &info2->uni_server, sizeof(name));
        printf("Server:\t\t%s\n", name);
 
-       unistr2_to_ascii(name, &info2->uni_comment, sizeof(name) - 1); 
+       unistr2_to_ascii(name, &info2->uni_comment, sizeof(name));
        printf("Comment:\t%s\n", name);
 
        printf("Total Users:\t%d\n", info2->num_domain_usrs);
        printf("Total Groups:\t%d\n", info2->num_domain_grps);
        printf("Total Aliases:\t%d\n", info2->num_local_grps);
        
-       printf("Sequence No:\t%lld\n", info2->seq_num);
+       printf("Sequence No:\t%llu\n", (unsigned long long)info2->seq_num);
 
        printf("Force Logoff:\t%d\n", (int)nt_time_to_unix_abs(&info2->logout));
 
@@ -183,7 +190,7 @@ static void display_sam_unk_info_4(SAM_UNK_INFO_4 *info4)
 {
        fstring name;
 
-       unistr2_to_ascii(name, &info4->uni_comment, sizeof(name) - 1); 
+       unistr2_to_ascii(name, &info4->uni_comment, sizeof(name));
        printf("Comment:\t%s\n", name);
 }
 
@@ -191,7 +198,7 @@ static void display_sam_unk_info_5(SAM_UNK_INFO_5 *info5)
 {
        fstring name;
 
-       unistr2_to_ascii(name, &info5->uni_domain, sizeof(name) - 1); 
+       unistr2_to_ascii(name, &info5->uni_domain, sizeof(name));
        printf("Domain:\t\t%s\n", name);
 }
 
@@ -199,7 +206,7 @@ static void display_sam_unk_info_6(SAM_UNK_INFO_6 *info6)
 {
        fstring name;
 
-       unistr2_to_ascii(name, &info6->uni_server, sizeof(name) - 1); 
+       unistr2_to_ascii(name, &info6->uni_server, sizeof(name));
        printf("Server:\t\t%s\n", name);
 }
 
@@ -210,7 +217,7 @@ static void display_sam_unk_info_7(SAM_UNK_INFO_7 *info7)
 
 static void display_sam_unk_info_8(SAM_UNK_INFO_8 *info8)
 {
-       printf("Sequence No:\t%lld\n", info8->seq_num);
+       printf("Sequence No:\t%llu\n", (unsigned long long)info8->seq_num);
        printf("Domain Create Time:\t%s\n", 
                http_timestring(nt_time_to_unix(info8->domain_create_time)));
 }
@@ -229,7 +236,7 @@ static void display_sam_unk_info_12(SAM_UNK_INFO_12 *info12)
 
 static void display_sam_unk_info_13(SAM_UNK_INFO_13 *info13)
 {
-       printf("Sequence No:\t%lld\n", info13->seq_num);
+       printf("Sequence No:\t%llu\n", (unsigned long long)info13->seq_num);
        printf("Domain Create Time:\t%s\n", 
                http_timestring(nt_time_to_unix(info13->domain_create_time)));
        printf("Unknown1:\t%d\n", info13->unknown1);
@@ -245,13 +252,13 @@ static void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
        printf("RID: 0x%x ", e1->rid_user);
        printf("acb: 0x%x ", e1->acb_info);
 
-       unistr2_to_ascii(tmp, &s1->uni_acct_name, sizeof(tmp)-1);
+       unistr2_to_ascii(tmp, &s1->uni_acct_name, sizeof(tmp));
        printf("Account: %s\t", tmp);
 
-       unistr2_to_ascii(tmp, &s1->uni_full_name, sizeof(tmp)-1);
+       unistr2_to_ascii(tmp, &s1->uni_full_name, sizeof(tmp));
        printf("Name: %s\t", tmp);
 
-       unistr2_to_ascii(tmp, &s1->uni_acct_desc, sizeof(tmp)-1);
+       unistr2_to_ascii(tmp, &s1->uni_acct_desc, sizeof(tmp));
        printf("Desc: %s\n", tmp);
 }
 
@@ -263,10 +270,10 @@ static void display_sam_info_2(SAM_ENTRY2 *e2, SAM_STR2 *s2)
        printf("RID: 0x%x ", e2->rid_user);
        printf("acb: 0x%x ", e2->acb_info);
        
-       unistr2_to_ascii(tmp, &s2->uni_srv_name, sizeof(tmp)-1);
+       unistr2_to_ascii(tmp, &s2->uni_srv_name, sizeof(tmp));
        printf("Account: %s\t", tmp);
 
-       unistr2_to_ascii(tmp, &s2->uni_srv_desc, sizeof(tmp)-1);
+       unistr2_to_ascii(tmp, &s2->uni_srv_desc, sizeof(tmp));
        printf("Name: %s\n", tmp);
 
 }
@@ -279,10 +286,10 @@ static void display_sam_info_3(SAM_ENTRY3 *e3, SAM_STR3 *s3)
        printf("RID: 0x%x ", e3->rid_grp);
        printf("attr: 0x%x ", e3->attr);
        
-       unistr2_to_ascii(tmp, &s3->uni_grp_name, sizeof(tmp)-1);
+       unistr2_to_ascii(tmp, &s3->uni_grp_name, sizeof(tmp));
        printf("Account: %s\t", tmp);
 
-       unistr2_to_ascii(tmp, &s3->uni_grp_desc, sizeof(tmp)-1);
+       unistr2_to_ascii(tmp, &s3->uni_grp_desc, sizeof(tmp));
        printf("Name: %s\n", tmp);
 
 }
@@ -342,14 +349,14 @@ static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
        SAM_USERINFO_CTR *user_ctr;
        fstring server;
-       uint32 user_rid;
+       uint32 user_rid = 0;
        
        if ((argc < 2) || (argc > 4)) {
                printf("Usage: %s rid [info level] [access mask] \n", argv[0]);
                return NT_STATUS_OK;
        }
        
-       user_rid = strtoul(argv[1], NULL, 10);
+       sscanf(argv[1], "%i", &user_rid);
        
        if (argc > 2)
                sscanf(argv[2], "%i", &info_level);
@@ -411,15 +418,18 @@ static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
                goto done;
 
        switch (user_ctr->switch_value) {
-       case 21:
-               display_sam_user_info_21(user_ctr->info.id21);
-               break;
        case 7:
                display_sam_user_info_7(user_ctr->info.id7);
                break;
        case 9:
                display_sam_user_info_9(user_ctr->info.id9);
                break;
+       case 16:
+               display_sam_user_info_16(user_ctr->info.id16);
+               break;
+       case 21:
+               display_sam_user_info_21(user_ctr->info.id21);
+               break;
        default:
                printf("Unsupported infolevel: %d\n", info_level);
                break;
@@ -440,9 +450,9 @@ static void display_group_info1(GROUP_INFO1 *info1)
 {
        fstring temp;
 
-       unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp));
        printf("\tGroup Name:\t%s\n", temp);
-       unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp));
        printf("\tDescription:\t%s\n", temp);
        printf("\tGroup Attribute:%d\n", info1->group_attr);
        printf("\tNum Members:%d\n", info1->num_members);
@@ -455,7 +465,7 @@ static void display_group_info2(GROUP_INFO2 *info2)
 {
        fstring name;
 
-       unistr2_to_ascii(name, &info2->uni_acct_name, sizeof(name)-1);
+       unistr2_to_ascii(name, &info2->uni_acct_name, sizeof(name));
        printf("\tGroup Description:%s\n", name);
 }
 
@@ -476,7 +486,7 @@ static void display_group_info4(GROUP_INFO4 *info4)
 {
        fstring desc;
 
-       unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1);
+       unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc));
        printf("\tGroup Description:%s\n", desc);
 }
 
@@ -487,9 +497,9 @@ static void display_group_info5(GROUP_INFO5 *info5)
 {
        fstring temp;
 
-       unistr2_to_ascii(temp, &info5->uni_acct_name, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &info5->uni_acct_name, sizeof(temp));
        printf("\tGroup Name:\t%s\n", temp);
-       unistr2_to_ascii(temp, &info5->uni_acct_desc, sizeof(temp)-1);
+       unistr2_to_ascii(temp, &info5->uni_acct_desc, sizeof(temp));
        printf("\tDescription:\t%s\n", temp);
        printf("\tGroup Attribute:%d\n", info5->group_attr);
        printf("\tNum Members:%d\n", info5->num_members);
@@ -684,12 +694,18 @@ static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
                        printf("%s is not a legal SID\n", argv[i]);
                        return NT_STATUS_INVALID_PARAMETER;
                }
-               add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
+               if (!add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids)) {
+                       return NT_STATUS_NO_MEMORY;
+               }
        }
 
-       sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
-       if (sid2 == NULL)
-               return NT_STATUS_NO_MEMORY;
+       if (num_sids) {
+               sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
+               if (sid2 == NULL)
+                       return NT_STATUS_NO_MEMORY;
+       } else {
+               sid2 = NULL;
+       }
 
        for (i=0; i<num_sids; i++) {
                sid_copy(&sid2[i].sid, &sids[i]);
@@ -751,6 +767,7 @@ static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
        int i;
        fstring                 server;
+       unsigned int old_timeout;
        
        if ((argc < 2) || (argc > 3)) {
                printf("Usage: %s rid [access mask]\n", argv[0]);
@@ -785,10 +802,15 @@ static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
        if (!NT_STATUS_IS_OK(result))
                goto done;
 
+       /* Make sure to wait for our DC's reply */
+       old_timeout = cli_set_timeout(cli->cli, MAX(cli->cli->timeout,30000)); /* 30 seconds. */
+
        result = rpccli_samr_query_groupmem(cli, mem_ctx, &group_pol,
                                         &num_members, &group_rids,
                                         &group_attrs);
 
+       cli_set_timeout(cli->cli, old_timeout);
+
        if (!NT_STATUS_IS_OK(result))
                goto done;
 
@@ -817,7 +839,7 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
        uint32 *dom_rids;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
        uint32 acb_mask = ACB_NORMAL;
-       BOOL got_connect_pol = False, got_domain_pol = False;
+       bool got_connect_pol = False, got_domain_pol = False;
 
        if ((argc < 1) || (argc > 3)) {
                printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
@@ -892,7 +914,7 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
        uint32 start_idx, size, num_dom_groups, i;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
        struct acct_info *dom_groups;
-       BOOL got_connect_pol = False, got_domain_pol = False;
+       bool got_connect_pol = False, got_domain_pol = False;
 
        if ((argc < 1) || (argc > 2)) {
                printf("Usage: %s [access_mask]\n", argv[0]);
@@ -965,7 +987,7 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
        uint32 start_idx, size, num_als_groups, i;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
        struct acct_info *als_groups;
-       BOOL got_connect_pol = False, got_domain_pol = False;
+       bool got_connect_pol = False, got_domain_pol = False;
 
        if ((argc < 2) || (argc > 3)) {
                printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
@@ -1185,10 +1207,9 @@ static NTSTATUS cmd_samr_delete_alias(struct rpc_pipe_client *cli,
 
 /* Query display info */
 
-static NTSTATUS cmd_samr_query_dispinfo_int(struct rpc_pipe_client *cli, 
-                                           TALLOC_CTX *mem_ctx,
-                                           int argc, const char **argv, 
-                                           int opcode)
+static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli, 
+                                        TALLOC_CTX *mem_ctx,
+                                        int argc, const char **argv) 
 {
        POLICY_HND connect_pol, domain_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -1202,7 +1223,7 @@ static NTSTATUS cmd_samr_query_dispinfo_int(struct rpc_pipe_client *cli,
        SAM_DISPINFO_4 info4;
        SAM_DISPINFO_5 info5;
        int loop_count = 0;
-       BOOL got_params = False; /* Use get_query_dispinfo_params() or not? */
+       bool got_params = False; /* Use get_query_dispinfo_params() or not? */
 
        if (argc > 6) {
                printf("Usage: %s [info level] [start index] [max entries] [max size] [access mask]\n", argv[0]);
@@ -1279,31 +1300,11 @@ static NTSTATUS cmd_samr_query_dispinfo_int(struct rpc_pipe_client *cli,
                if (!got_params)
                        get_query_dispinfo_params(
                                loop_count, &max_entries, &max_size);
-
-               switch (opcode) {
-               case SAMR_QUERY_DISPINFO:
-                       result = rpccli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
-                                                           &start_idx, info_level,
-                                                           &num_entries, max_entries, 
-                                                           max_size, &ctr);
-                       break;
-               case SAMR_QUERY_DISPINFO2:
-                       result = rpccli_samr_query_dispinfo2(cli, mem_ctx, &domain_pol,
-                                                            &start_idx, info_level,
-                                                            &num_entries, max_entries, 
-                                                            max_size, &ctr);
-                       break;
-               case SAMR_QUERY_DISPINFO3:
-                       result = rpccli_samr_query_dispinfo3(cli, mem_ctx, &domain_pol,
-                                                            &start_idx, info_level,
-                                                            &num_entries, max_entries, 
-                                                            max_size, &ctr);
-                       break;
-               default:
-                       printf("unknown opcode: %d\n", opcode);
-                       return NT_STATUS_INVALID_PARAMETER;
-                       break;
-               }
+               
+               result = rpccli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
+                                                &start_idx, info_level,
+                                                &num_entries, max_entries, 
+                                                max_size, &ctr);
 
                loop_count++;
 
@@ -1340,26 +1341,6 @@ static NTSTATUS cmd_samr_query_dispinfo_int(struct rpc_pipe_client *cli,
        return result;
 }
 
-static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli, 
-                                       TALLOC_CTX *mem_ctx,
-                                       int argc, const char **argv)
-{
-       return cmd_samr_query_dispinfo_int(cli, mem_ctx, argc, argv, SAMR_QUERY_DISPINFO);
-}
-
-static NTSTATUS cmd_samr_query_dispinfo2(struct rpc_pipe_client *cli, 
-                                        TALLOC_CTX *mem_ctx,
-                                        int argc, const char **argv) 
-{
-       return cmd_samr_query_dispinfo_int(cli, mem_ctx, argc, argv, SAMR_QUERY_DISPINFO2);
-}
-
-static NTSTATUS cmd_samr_query_dispinfo3(struct rpc_pipe_client *cli, 
-                                        TALLOC_CTX *mem_ctx,
-                                        int argc, const char **argv) 
-{
-       return cmd_samr_query_dispinfo_int(cli, mem_ctx, argc, argv, SAMR_QUERY_DISPINFO3);
-}
 /* Query domain info */
 
 static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli, 
@@ -1687,6 +1668,7 @@ static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
        /* Look up names */
 
        num_names = argc - 2;
+
        if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) {
                rpccli_samr_close(cli, mem_ctx, &domain_pol);
                rpccli_samr_close(cli, mem_ctx, &connect_pol);
@@ -1694,7 +1676,7 @@ static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
                goto done;
        }
 
-       for (i = 0; i < argc - 2; i++)
+       for (i = 0; i < num_names; i++)
                names[i] = argv[i + 2];
 
        result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
@@ -1758,7 +1740,7 @@ static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
        /* Look up rids */
 
        num_rids = argc - 2;
-       rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids);
+
        if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
                rpccli_samr_close(cli, mem_ctx, &domain_pol);
                rpccli_samr_close(cli, mem_ctx, &connect_pol);
@@ -1787,6 +1769,78 @@ static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
        return result;
 }
 
+/* Delete domain group */
+
+static NTSTATUS cmd_samr_delete_dom_group(struct rpc_pipe_client *cli, 
+                                         TALLOC_CTX *mem_ctx,
+                                         int argc, const char **argv) 
+{
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+       POLICY_HND connect_pol, domain_pol, group_pol;
+       uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
+
+       if ((argc < 2) || (argc > 3)) {
+               printf("Usage: %s groupname\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+       
+       if (argc > 2)
+                sscanf(argv[2], "%x", &access_mask);
+
+       /* Get sam policy and domain handles */
+
+       result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
+                                  &connect_pol);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
+                                     MAXIMUM_ALLOWED_ACCESS,
+                                     &domain_sid, &domain_pol);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       /* Get handle on group */
+
+       {
+               uint32 *group_rids, num_rids, *name_types;
+               uint32 flags = 0x000003e8; /* Unknown */
+
+               result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+                                              flags, 1, (const char **)&argv[1],
+                                              &num_rids, &group_rids,
+                                              &name_types);
+
+               if (!NT_STATUS_IS_OK(result))
+                       goto done;
+
+               result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
+                                               access_mask,
+                                               group_rids[0], &group_pol);
+
+               if (!NT_STATUS_IS_OK(result))
+                       goto done;
+       }
+
+       /* Delete user */
+
+       result = rpccli_samr_delete_dom_group(cli, mem_ctx, &group_pol);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       /* Display results */
+
+       rpccli_samr_close(cli, mem_ctx, &group_pol);
+       rpccli_samr_close(cli, mem_ctx, &domain_pol);
+       rpccli_samr_close(cli, mem_ctx, &connect_pol);
+
+ done:
+       return result;
+}
+
 /* Delete domain user */
 
 static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli, 
@@ -1873,13 +1927,14 @@ static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
        uint32 user_rid = 0;
        TALLOC_CTX *ctx = NULL;
        SEC_DESC_BUF *sec_desc_buf=NULL;
-       BOOL domain = False;
+       bool domain = False;
 
        ctx=talloc_init("cmd_samr_query_sec_obj");
        
        if ((argc < 1) || (argc > 3)) {
                printf("Usage: %s [rid|-d] [sec_info]\n", argv[0]);
                printf("\tSpecify rid for security on user, -d for security on domain\n");
+               talloc_destroy(ctx);
                return NT_STATUS_OK;
        }
        
@@ -1936,7 +1991,7 @@ static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
        if (!NT_STATUS_IS_OK(result))
                goto done;
 
-       display_sec_desc(sec_desc_buf->sec);
+       display_sec_desc(sec_desc_buf->sd);
 
        rpccli_samr_close(cli, mem_ctx, &user_pol);
        rpccli_samr_close(cli, mem_ctx, &domain_pol);
@@ -2071,6 +2126,60 @@ done:
        return result;
 }
 
+/* Change user password */
+
+static NTSTATUS cmd_samr_chgpasswd2(struct rpc_pipe_client *cli, 
+                                   TALLOC_CTX *mem_ctx,
+                                   int argc, const char **argv) 
+{
+       POLICY_HND connect_pol, domain_pol;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+       const char *user, *oldpass, *newpass;
+       uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
+
+       if (argc < 3) {
+               printf("Usage: %s username oldpass newpass\n", argv[0]);
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       user = argv[1];
+       oldpass = argv[2];
+       newpass = argv[3];
+       
+       /* Get sam policy handle */
+
+       result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
+                                  &connect_pol);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       /* Get domain policy handle */
+
+       result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
+                                     access_mask,
+                                     &domain_sid, &domain_pol);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       /* Change user password */
+       result = rpccli_samr_chgpasswd_user(cli, mem_ctx, user, newpass, oldpass);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
+       if (!NT_STATUS_IS_OK(result)) goto done;
+
+       result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
+       if (!NT_STATUS_IS_OK(result)) goto done;
+
+ done:
+       return result;
+}
+
+
 /* Change user password */
 
 static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli, 
@@ -2163,8 +2272,6 @@ struct cmd_set samr_commands[] = {
        { "queryaliasmem",      RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem,    NULL, PI_SAMR, NULL,    "Query alias membership",  "" },
        { "deletealias",        RPC_RTYPE_NTSTATUS, cmd_samr_delete_alias,      NULL, PI_SAMR, NULL,    "Delete an alias",  "" },
        { "querydispinfo",      RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo,    NULL, PI_SAMR, NULL,    "Query display info",      "" },
-       { "querydispinfo2",     RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo2,   NULL, PI_SAMR, NULL,    "Query display info 2",      "" },
-       { "querydispinfo3",     RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo3,   NULL, PI_SAMR, NULL,    "Query display info 3",      "" },
        { "querydominfo",       RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo,     NULL, PI_SAMR, NULL,    "Query domain info",       "" },
        { "enumdomusers",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users,       NULL, PI_SAMR, NULL,  "Enumerate domain users", "" },
        { "enumdomgroups",      RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups,       NULL, PI_SAMR, NULL,        "Enumerate domain groups", "" },
@@ -2175,12 +2282,14 @@ struct cmd_set samr_commands[] = {
        { "createdomalias",     RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_alias,      NULL, PI_SAMR, NULL,        "Create domain alias",     "" },
        { "samlookupnames",     RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names,          NULL, PI_SAMR, NULL,        "Look up names",           "" },
        { "samlookuprids",      RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids,           NULL, PI_SAMR, NULL,        "Look up names",           "" },
+       { "deletedomgroup",     RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_group,      NULL, PI_SAMR, NULL,        "Delete domain group",     "" },
        { "deletedomuser",      RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user,       NULL, PI_SAMR, NULL,        "Delete domain user",      "" },
        { "samquerysecobj",     RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj,         NULL, PI_SAMR, NULL, "Query SAMR security object",   "" },
        { "getdompwinfo",       RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo,        NULL, PI_SAMR, NULL, "Retrieve domain password info", "" },
        { "getusrdompwinfo",    RPC_RTYPE_NTSTATUS, cmd_samr_get_usrdom_pwinfo,     NULL, PI_SAMR, NULL, "Retrieve user domain password info", "" },
 
        { "lookupdomain",       RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain,         NULL, PI_SAMR, NULL, "Lookup Domain Name", "" },
+       { "chgpasswd2",         RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2,            NULL, PI_SAMR, NULL, "Change user password", "" },
        { "chgpasswd3",         RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3,            NULL, PI_SAMR, NULL, "Change user password", "" },
        { NULL }
 };