converted another bunch of stuff to NTSTATUS
[kai/samba.git] / source3 / rpc_parse / parse_samr.c
index 395931edd9d616ea6f36a227718532841e8a04b2..f39104fed0e4c96ec88d4d224e969fd3b03112e5 100644 (file)
@@ -23,7 +23,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
 #include "includes.h"
 #include "rpc_parse.h"
 #include "nterr.h"
@@ -134,7 +133,7 @@ inits a SAMR_R_LOOKUP_DOMAIN structure.
 ********************************************************************/
 
 void init_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN * r_u,
-                              DOM_SID *dom_sid, uint32 status)
+                              DOM_SID *dom_sid, NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_lookup_domain\n"));
 
@@ -343,7 +342,7 @@ BOOL samr_io_q_get_usrdom_pwinfo(char *desc, SAMR_Q_GET_USRDOM_PWINFO * q_u,
  Init.
 ********************************************************************/
 
-void init_samr_r_get_usrdom_pwinfo(SAMR_R_GET_USRDOM_PWINFO *r_u, uint32 status)
+void init_samr_r_get_usrdom_pwinfo(SAMR_R_GET_USRDOM_PWINFO *r_u, NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_get_usrdom_pwinfo\n"));
        
@@ -594,6 +593,40 @@ static BOOL sam_io_unk_info12(char *desc, SAM_UNK_INFO_12 * u_12,
        return True;
 }
 
+/*******************************************************************
+inits a structure.
+********************************************************************/
+void init_unk_info5(SAM_UNK_INFO_5 * u_5,char *server)
+{
+       int len_server = strlen(server);
+
+       init_uni_hdr(&u_5->hdr_server, len_server);
+
+       init_unistr2(&u_5->uni_server, server, len_server);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+static BOOL sam_io_unk_info5(char *desc, SAM_UNK_INFO_5 * u_5,
+                            prs_struct *ps, int depth)
+{
+       if (u_5 == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "sam_io_unk_info5");
+       depth++;
+
+       if(!smb_io_unihdr("hdr_server", &u_5->hdr_server, ps, depth))
+               return False;
+
+       if(!smb_io_unistr2("uni_server", &u_5->uni_server, u_5->hdr_server.buffer, ps, depth))
+               return False;
+
+       return True;
+}
+
 /*******************************************************************
 inits a structure.
 ********************************************************************/
@@ -729,7 +762,7 @@ inits a SAMR_R_QUERY_DOMAIN_INFO structure.
 
 void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO * r_u,
                                uint16 switch_value, SAM_UNK_CTR * ctr,
-                               uint32 status)
+                               NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_query_dom_info\n"));
 
@@ -782,6 +815,10 @@ BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
                        if(!sam_io_unk_info6("unk_inf6",&r_u->ctr->info.inf6, ps,depth))
                                return False;
                        break;
+               case 0x05:
+                       if(!sam_io_unk_info5("unk_inf5",&r_u->ctr->info.inf5, ps,depth))
+                               return False;
+                       break;
                case 0x03:
                        if(!sam_io_unk_info3("unk_inf3",&r_u->ctr->info.inf3, ps,depth))
                                return False;
@@ -1387,7 +1424,7 @@ BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO * q_e,
 inits a SAM_DISPINFO_1 structure.
 ********************************************************************/
 
-void init_sam_dispinfo_1(SAM_DISPINFO_1 * sam, uint32 *num_entries,
+NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 *num_entries,
                         uint32 *data_size, uint32 start_idx,
                         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
 {
@@ -1404,7 +1441,22 @@ void init_sam_dispinfo_1(SAM_DISPINFO_1 * sam, uint32 *num_entries,
        DEBUG(5, ("init_sam_dispinfo_1: max_entries: %d max_dsize: 0x%x\n",
                  max_entries, max_data_size));
 
+       if (max_entries==0)
+               return NT_STATUS_OK;
+
+       sam->sam=(SAM_ENTRY1 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY1));
+       if (!sam->sam)
+               return NT_STATUS_NO_MEMORY;
+
+       sam->str=(SAM_STR1 *)talloc(ctx, max_entries*sizeof(SAM_STR1));
+       if (!sam->str)
+               return NT_STATUS_NO_MEMORY;
+
+       ZERO_STRUCTP(sam->sam);
+       ZERO_STRUCTP(sam->str);
+
        for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) {
+               DEBUG(5, ("init_sam_dispinfo_1: entry: %d\n",i));
                len_sam_name = pass[i].uni_user_name.uni_str_len;
                len_sam_full = pass[i].uni_full_name.uni_str_len;
                len_sam_desc = pass[i].uni_acct_desc.uni_str_len;
@@ -1413,6 +1465,10 @@ void init_sam_dispinfo_1(SAM_DISPINFO_1 * sam, uint32 *num_entries,
                                len_sam_name, len_sam_full, len_sam_desc,
                                pass[i].user_rid, pass[i].acb_info);
 
+               ZERO_STRUCTP(&sam->str[i].uni_acct_name);
+               ZERO_STRUCTP(&sam->str[i].uni_full_name);
+               ZERO_STRUCTP(&sam->str[i].uni_acct_desc);
+
                copy_unistr2(&sam->str[i].uni_acct_name, &pass[i].uni_user_name);
                copy_unistr2(&sam->str[i].uni_full_name, &pass[i].uni_full_name);
                copy_unistr2(&sam->str[i].uni_acct_desc, &pass[i].uni_acct_desc);
@@ -1423,6 +1479,8 @@ void init_sam_dispinfo_1(SAM_DISPINFO_1 * sam, uint32 *num_entries,
 
        *num_entries = i;
        *data_size = dsize;
+
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -1435,16 +1493,28 @@ static BOOL sam_io_sam_dispinfo_1(char *desc, SAM_DISPINFO_1 * sam,
 {
        uint32 i;
 
-       if (sam == NULL)
-               return False;
-
        prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_1");
        depth++;
 
        if(!prs_align(ps))
                return False;
 
-       SMB_ASSERT_ARRAY(sam->sam, num_entries);
+       if (UNMARSHALLING(ps) && num_entries > 0) {
+
+               if ((sam->sam = (SAM_ENTRY1 *)
+                    prs_alloc_mem(ps, sizeof(SAM_ENTRY1) *
+                                  num_entries)) == NULL) {
+                       DEBUG(0, ("out of memory allocating SAM_ENTRY1\n"));
+                       return False;
+               }
+
+               if ((sam->str = (SAM_STR1 *)
+                    prs_alloc_mem(ps, sizeof(SAM_STR1) * 
+                                  num_entries)) == NULL) {
+                       DEBUG(0, ("out of memory allocating SAM_STR1\n"));
+                       return False;
+               }
+       }
 
        for (i = 0; i < num_entries; i++) {
                if(!sam_io_sam_entry1("", &sam->sam[i], ps, depth))
@@ -1466,7 +1536,7 @@ static BOOL sam_io_sam_dispinfo_1(char *desc, SAM_DISPINFO_1 * sam,
 inits a SAM_DISPINFO_2 structure.
 ********************************************************************/
 
-void init_sam_dispinfo_2(SAM_DISPINFO_2 * sam, uint32 *num_entries,
+NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 *num_entries,
                         uint32 *data_size, uint32 start_idx,
                         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
 {
@@ -1482,6 +1552,18 @@ void init_sam_dispinfo_2(SAM_DISPINFO_2 * sam, uint32 *num_entries,
        max_entries = *num_entries;
        max_data_size = *data_size;
 
+       if (max_entries==0)
+               return NT_STATUS_OK;
+
+       if (!(sam->sam=(SAM_ENTRY2 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY2))))
+               return NT_STATUS_NO_MEMORY;
+
+       if (!(sam->str=(SAM_STR2 *)talloc(ctx, max_entries*sizeof(SAM_STR2))))
+               return NT_STATUS_NO_MEMORY;
+
+       ZERO_STRUCTP(sam->sam);
+       ZERO_STRUCTP(sam->str);
+
        for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) {
                len_sam_name = pass[i].uni_user_name.uni_str_len;
                len_sam_desc = pass[i].uni_acct_desc.uni_str_len;
@@ -1490,10 +1572,11 @@ void init_sam_dispinfo_2(SAM_DISPINFO_2 * sam, uint32 *num_entries,
                          len_sam_name, len_sam_desc,
                          pass[i].user_rid, pass[i].acb_info);
          
-               copy_unistr2(&sam->str[i].uni_srv_name,
-                      &pass[i].uni_user_name);
-               copy_unistr2(&sam->str[i].uni_srv_desc,
-                      &pass[i].uni_acct_desc);
+               ZERO_STRUCTP(&sam->str[i].uni_srv_name);
+               ZERO_STRUCTP(&sam->str[i].uni_srv_desc);
+
+               copy_unistr2(&sam->str[i].uni_srv_name, &pass[i].uni_user_name);
+               copy_unistr2(&sam->str[i].uni_srv_desc, &pass[i].uni_acct_desc);
          
                dsize += sizeof(SAM_ENTRY2);
                dsize += len_sam_name + len_sam_desc;
@@ -1501,6 +1584,8 @@ void init_sam_dispinfo_2(SAM_DISPINFO_2 * sam, uint32 *num_entries,
 
        *num_entries = i;
        *data_size = dsize;
+
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -1522,7 +1607,22 @@ static BOOL sam_io_sam_dispinfo_2(char *desc, SAM_DISPINFO_2 * sam,
        if(!prs_align(ps))
                return False;
 
-       SMB_ASSERT_ARRAY(sam->sam, num_entries);
+       if (UNMARSHALLING(ps) && num_entries > 0) {
+
+               if ((sam->sam = (SAM_ENTRY2 *)
+                    prs_alloc_mem(ps, sizeof(SAM_ENTRY2) *
+                                  num_entries)) == NULL) {
+                       DEBUG(0, ("out of memory allocating SAM_ENTRY2\n"));
+                       return False;
+               }
+
+               if ((sam->str = (SAM_STR2 *)
+                    prs_alloc_mem(ps, sizeof(SAM_STR2) * 
+                                  num_entries)) == NULL) {
+                       DEBUG(0, ("out of memory allocating SAM_STR2\n"));
+                       return False;
+               }
+       }
 
        for (i = 0; i < num_entries; i++) {
                if(!sam_io_sam_entry2("", &sam->sam[i], ps, depth))
@@ -1543,7 +1643,7 @@ static BOOL sam_io_sam_dispinfo_2(char *desc, SAM_DISPINFO_2 * sam,
 inits a SAM_DISPINFO_3 structure.
 ********************************************************************/
 
-void init_sam_dispinfo_3(SAM_DISPINFO_3 * sam, uint32 *num_entries,
+NTSTATUS init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 *num_entries,
                         uint32 *data_size, uint32 start_idx,
                         DOMAIN_GRP * grp)
 {
@@ -1559,6 +1659,18 @@ void init_sam_dispinfo_3(SAM_DISPINFO_3 * sam, uint32 *num_entries,
        max_entries = *num_entries;
        max_data_size = *data_size;
 
+       if (max_entries==0)
+               return NT_STATUS_OK;
+
+       if (!(sam->sam=(SAM_ENTRY3 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY3))))
+               return NT_STATUS_NO_MEMORY;
+
+       if (!(sam->str=(SAM_STR3 *)talloc(ctx, max_entries*sizeof(SAM_STR3))))
+               return NT_STATUS_NO_MEMORY;
+
+       ZERO_STRUCTP(sam->sam);
+       ZERO_STRUCTP(sam->str);
+
        for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) {
                len_sam_name = strlen(grp[i].name);
                len_sam_desc = strlen(grp[i].comment);
@@ -1575,6 +1687,8 @@ void init_sam_dispinfo_3(SAM_DISPINFO_3 * sam, uint32 *num_entries,
 
        *num_entries = i;
        *data_size = dsize;
+
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -1596,7 +1710,22 @@ static BOOL sam_io_sam_dispinfo_3(char *desc, SAM_DISPINFO_3 * sam,
        if(!prs_align(ps))
                return False;
 
-       SMB_ASSERT_ARRAY(sam->sam, num_entries);
+       if (UNMARSHALLING(ps) && num_entries > 0) {
+
+               if ((sam->sam = (SAM_ENTRY3 *)
+                    prs_alloc_mem(ps, sizeof(SAM_ENTRY3) *
+                                  num_entries)) == NULL) {
+                       DEBUG(0, ("out of memory allocating SAM_ENTRY3\n"));
+                       return False;
+               }
+
+               if ((sam->str = (SAM_STR3 *)
+                    prs_alloc_mem(ps, sizeof(SAM_STR3) * 
+                                  num_entries)) == NULL) {
+                       DEBUG(0, ("out of memory allocating SAM_STR3\n"));
+                       return False;
+               }
+       }
 
        for (i = 0; i < num_entries; i++) {
                if(!sam_io_sam_entry3("", &sam->sam[i], ps, depth))
@@ -1617,7 +1746,7 @@ static BOOL sam_io_sam_dispinfo_3(char *desc, SAM_DISPINFO_3 * sam,
 inits a SAM_DISPINFO_4 structure.
 ********************************************************************/
 
-void init_sam_dispinfo_4(SAM_DISPINFO_4 * sam, uint32 *num_entries,
+NTSTATUS init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 *num_entries,
                         uint32 *data_size, uint32 start_idx,
                         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
 {
@@ -1634,16 +1763,25 @@ void init_sam_dispinfo_4(SAM_DISPINFO_4 * sam, uint32 *num_entries,
        max_entries = *num_entries;
        max_data_size = *data_size;
 
+       if (max_entries==0)
+               return NT_STATUS_OK;
+
+       if (!(sam->sam=(SAM_ENTRY4 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY4))))
+               return NT_STATUS_NO_MEMORY;
+
+       if (!(sam->str=(SAM_STR4 *)talloc(ctx, max_entries*sizeof(SAM_STR4))))
+               return NT_STATUS_NO_MEMORY;
+
+       ZERO_STRUCTP(sam->sam);
+       ZERO_STRUCTP(sam->str);
+
        for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) {
                len_sam_name = pass[i].uni_user_name.uni_str_len;
          
-               init_sam_entry4(&sam->sam[i], start_idx + i + 1,
-                         len_sam_name);
-         
-               unistr2_to_ascii(sam_name, &pass[i].uni_user_name,
-                          sizeof(sam_name));
-               init_string2(&sam->str[i].acct_name, sam_name,
-                      len_sam_name);
+               init_sam_entry4(&sam->sam[i], start_idx + i + 1, len_sam_name);
+
+               unistr2_to_ascii(sam_name, &pass[i].uni_user_name, sizeof(sam_name));
+               init_string2(&sam->str[i].acct_name, sam_name, len_sam_name);
          
                dsize += sizeof(SAM_ENTRY4);
                dsize += len_sam_name;
@@ -1651,6 +1789,8 @@ void init_sam_dispinfo_4(SAM_DISPINFO_4 * sam, uint32 *num_entries,
        
        *num_entries = i;
        *data_size = dsize;
+
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -1672,7 +1812,22 @@ static BOOL sam_io_sam_dispinfo_4(char *desc, SAM_DISPINFO_4 * sam,
        if(!prs_align(ps))
                return False;
 
-       SMB_ASSERT_ARRAY(sam->sam, num_entries);
+       if (UNMARSHALLING(ps) && num_entries > 0) {
+
+               if ((sam->sam = (SAM_ENTRY4 *)
+                    prs_alloc_mem(ps, sizeof(SAM_ENTRY4) *
+                                  num_entries)) == NULL) {
+                       DEBUG(0, ("out of memory allocating SAM_ENTRY4\n"));
+                       return False;
+               }
+
+               if ((sam->str = (SAM_STR4 *)
+                    prs_alloc_mem(ps, sizeof(SAM_STR4) * 
+                                  num_entries)) == NULL) {
+                       DEBUG(0, ("out of memory allocating SAM_STR4\n"));
+                       return False;
+               }
+       }
 
        for (i = 0; i < num_entries; i++) {
                if(!sam_io_sam_entry4("", &sam->sam[i], ps, depth))
@@ -1694,7 +1849,7 @@ static BOOL sam_io_sam_dispinfo_4(char *desc, SAM_DISPINFO_4 * sam,
 inits a SAM_DISPINFO_5 structure.
 ********************************************************************/
 
-void init_sam_dispinfo_5(SAM_DISPINFO_5 * sam, uint32 *num_entries,
+NTSTATUS init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 *num_entries,
                         uint32 *data_size, uint32 start_idx,
                         DOMAIN_GRP * grp)
 {
@@ -1710,14 +1865,23 @@ void init_sam_dispinfo_5(SAM_DISPINFO_5 * sam, uint32 *num_entries,
        max_entries = *num_entries;
        max_data_size = *data_size;
 
+       if (max_entries==0)
+               return NT_STATUS_OK;
+
+       if (!(sam->sam=(SAM_ENTRY5 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY5))))
+               return NT_STATUS_NO_MEMORY;
+
+       if (!(sam->str=(SAM_STR5 *)talloc(ctx, max_entries*sizeof(SAM_STR5))))
+               return NT_STATUS_NO_MEMORY;
+
+       ZERO_STRUCTP(sam->sam);
+       ZERO_STRUCTP(sam->str);
+
        for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) {
                len_sam_name = strlen(grp[i].name);
          
-               init_sam_entry5(&sam->sam[i], start_idx + i + 1,
-                               len_sam_name);
-         
-               init_string2(&sam->str[i].grp_name, grp[i].name,
-                               len_sam_name);
+               init_sam_entry5(&sam->sam[i], start_idx + i + 1, len_sam_name);
+               init_string2(&sam->str[i].grp_name, grp[i].name, len_sam_name);
          
                dsize += sizeof(SAM_ENTRY5);
                dsize += len_sam_name;
@@ -1725,6 +1889,8 @@ void init_sam_dispinfo_5(SAM_DISPINFO_5 * sam, uint32 *num_entries,
        
        *num_entries = i;
        *data_size = dsize;
+
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -1746,7 +1912,22 @@ static BOOL sam_io_sam_dispinfo_5(char *desc, SAM_DISPINFO_5 * sam,
        if(!prs_align(ps))
                return False;
 
-       SMB_ASSERT_ARRAY(sam->sam, num_entries);
+       if (UNMARSHALLING(ps) && num_entries > 0) {
+
+               if ((sam->sam = (SAM_ENTRY5 *)
+                    prs_alloc_mem(ps, sizeof(SAM_ENTRY5) *
+                                  num_entries)) == NULL) {
+                       DEBUG(0, ("out of memory allocating SAM_ENTRY5\n"));
+                       return False;
+               }
+
+               if ((sam->str = (SAM_STR5 *)
+                    prs_alloc_mem(ps, sizeof(SAM_STR5) * 
+                                  num_entries)) == NULL) {
+                       DEBUG(0, ("out of memory allocating SAM_STR5\n"));
+                       return False;
+               }
+       }
 
        for (i = 0; i < num_entries; i++) {
                if(!sam_io_sam_entry5("", &sam->sam[i], ps, depth))
@@ -1771,7 +1952,7 @@ inits a SAMR_R_QUERY_DISPINFO structure.
 void init_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO * r_u,
                                uint32 num_entries, uint32 data_size,
                                uint16 switch_level, SAM_DISPINFO_CTR * ctr,
-                               uint32 status)
+                               NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_query_dispinfo: level %d\n", switch_level));
 
@@ -2262,7 +2443,7 @@ inits a SAMR_R_DEL_GROUPMEM structure.
 ********************************************************************/
 
 void init_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND *pol,
-                             uint32 status)
+                             NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_del_groupmem\n"));
 
@@ -2337,7 +2518,7 @@ inits a SAMR_R_ADD_GROUPMEM structure.
 ********************************************************************/
 
 void init_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND *pol,
-                             uint32 status)
+                             NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_add_groupmem\n"));
 
@@ -2408,7 +2589,7 @@ BOOL samr_io_q_set_groupinfo(char *desc, SAMR_Q_SET_GROUPINFO * q_e,
 inits a SAMR_R_SET_GROUPINFO structure.
 ********************************************************************/
 
-void init_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO * r_u, uint32 status)
+void init_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO * r_u, NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_set_groupinfo\n"));
 
@@ -2481,7 +2662,7 @@ inits a SAMR_R_QUERY_GROUPINFO structure.
 ********************************************************************/
 
 void init_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO * r_u,
-                                GROUP_INFO_CTR * ctr, uint32 status)
+                                GROUP_INFO_CTR * ctr, NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_query_groupinfo\n"));
 
@@ -2561,7 +2742,7 @@ inits a SAMR_R_QUERY_GROUPMEM structure.
 
 void init_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM * r_u,
                                uint32 num_entries, uint32 *rid,
-                               uint32 *attr, uint32 status)
+                               uint32 *attr, NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_query_groupmem\n"));
 
@@ -2695,7 +2876,7 @@ inits a SAMR_R_QUERY_USERGROUPS structure.
 
 void init_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS * r_u,
                                  uint32 num_gids, DOM_GID * gid,
-                                 uint32 status)
+                                 NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_query_usergroups\n"));
 
@@ -3314,7 +3495,7 @@ inits a SAMR_R_QUERY_ALIASINFO structure.
 ********************************************************************/
 
 void init_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO * r_u,
-                                ALIAS_INFO_CTR * ctr, uint32 status)
+                                ALIAS_INFO_CTR * ctr, NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_query_aliasinfo\n"));
 
@@ -3500,7 +3681,7 @@ inits a SAMR_R_QUERY_USERALIASES structure.
 
 void init_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES * r_u,
                                   uint32 num_rids, uint32 *rid,
-                                  uint32 status)
+                                  NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_query_useraliases\n"));
 
@@ -4146,7 +4327,7 @@ inits a SAMR_R_DELETE_DOM_ALIAS structure.
 ********************************************************************/
 
 void init_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS * r_u,
-                                 uint32 status)
+                                 NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_delete_dom_alias\n"));
 
@@ -4215,7 +4396,7 @@ inits a SAMR_R_QUERY_ALIASMEM structure.
 
 void init_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM * r_u,
                                uint32 num_sids, DOM_SID2 * sid,
-                               uint32 status)
+                               NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_query_aliasmem\n"));
 
@@ -4291,7 +4472,7 @@ BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
 inits a SAMR_Q_LOOKUP_NAMES structure.
 ********************************************************************/
 
-void init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u,
+NTSTATUS init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u,
                              POLICY_HND *pol, uint32 flags,
                              uint32 num_names, char **name)
 {
@@ -4306,14 +4487,19 @@ void init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u,
        q_u->ptr = 0;
        q_u->num_names2 = num_names;
 
-       q_u->hdr_name = (UNIHDR *)talloc_zero(ctx, num_names * sizeof(UNIHDR));
-       q_u->uni_name = (UNISTR2 *)talloc_zero(ctx, num_names * sizeof(UNISTR2));
+       if (!(q_u->hdr_name = (UNIHDR *)talloc_zero(ctx, num_names * sizeof(UNIHDR))))
+               return NT_STATUS_NO_MEMORY;
+
+       if (!(q_u->uni_name = (UNISTR2 *)talloc_zero(ctx, num_names * sizeof(UNISTR2))))
+               return NT_STATUS_NO_MEMORY;
 
        for (i = 0; i < num_names; i++) {
                int len_name = name[i] != NULL ? strlen(name[i]) : 0;
                init_uni_hdr(&q_u->hdr_name[i], len_name);      /* unicode header for user_name */
                init_unistr2(&q_u->uni_name[i], name[i], len_name);     /* unicode string for machine account */
        }
+
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -4375,10 +4561,10 @@ BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES * q_u,
 inits a SAMR_R_LOOKUP_NAMES structure.
 ********************************************************************/
 
-void init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u,
+NTSTATUS init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u,
                              uint32 num_rids,
                              uint32 *rid, uint32 *type,
-                             uint32 status)
+                             NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_lookup_names\n"));
 
@@ -4393,8 +4579,10 @@ void init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u,
                r_u->ptr_rids = 1;
                r_u->num_rids2 = num_rids;
 
-               r_u->rids = (uint32 *)talloc_zero(ctx, sizeof(uint32)*num_rids);
-               r_u->types = (uint32 *)talloc_zero(ctx, sizeof(uint32)*num_rids);
+               if (!(r_u->rids = (uint32 *)talloc_zero(ctx, sizeof(uint32)*num_rids)))
+                       return NT_STATUS_NO_MEMORY;
+               if (!(r_u->types = (uint32 *)talloc_zero(ctx, sizeof(uint32)*num_rids)))
+                       return NT_STATUS_NO_MEMORY;
 
                if (!r_u->rids || !r_u->types)
                        goto empty;
@@ -4419,6 +4607,8 @@ void init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u,
        }
 
        r_u->status = status;
+
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -4997,10 +5187,11 @@ static BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 * usr,
 
  *************************************************************************/
 
-void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516])
+void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516], uint16 pw_len)
 {
        DEBUG(10, ("init_sam_user_info24:\n"));
        memcpy(usr->pass, newpass, sizeof(usr->pass));
+       usr->pw_len = pw_len;
 }
 
 /*******************************************************************
@@ -5023,6 +5214,10 @@ static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 * usr,
                       sizeof(usr->pass)))
                return False;
        
+       if (MARSHALLING(ps) && (usr->pw_len != 0)) {
+               if (!prs_uint16("pw_len", ps, depth, &usr->pw_len))
+                       return False;
+       }
        if(!prs_align(ps))
                return False;
 
@@ -5778,11 +5973,47 @@ static BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 * usr,
        return True;
 }
 
+void init_sam_user_info20A(SAM_USER_INFO_20 *usr, SAM_ACCOUNT *pw)
+{
+       int             len_munged_dial;
+       char*           munged_dial = pdb_get_munged_dial(pw);
+
+       len_munged_dial  = munged_dial  != NULL ? strlen(munged_dial )+1 : 0;
+       init_uni_hdr(&usr->hdr_munged_dial, len_munged_dial);
+       init_unistr2(&usr->uni_munged_dial, munged_dial, len_munged_dial);
+
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+static BOOL sam_io_user_info20(char *desc, SAM_USER_INFO_20 *usr,
+                       prs_struct *ps, int depth)
+{
+       if (usr == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "sam_io_user_info20");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth))        /* wkstas user can log on from */
+               return False;
+
+       if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial,usr->hdr_munged_dial.buffer, ps, depth))   /* worksations user can log on from */
+               return False;
+
+       return True;
+}
+
 /*******************************************************************
 inits a SAM_USERINFO_CTR structure.
 ********************************************************************/
 
-uint32 make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
+NTSTATUS make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
                                    uint16 switch_value,
                                    SAM_USER_INFO_21 * usr)
 {
@@ -5843,7 +6074,7 @@ uint32 make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
                return NT_STATUS_INVALID_INFO_CLASS;
        }
 
-       return NT_STATUS_NOPROBLEMO;
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -5935,6 +6166,16 @@ static BOOL samr_io_userinfo_ctr(char *desc, SAM_USERINFO_CTR **ppctr,
                }
                ret = sam_io_user_info12("", ctr->info.id12, ps, depth);
                break;
+       case 20:
+               if (UNMARSHALLING(ps))
+                       ctr->info.id20 = (SAM_USER_INFO_20 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_20));
+
+               if (ctr->info.id20 == NULL) {
+                       DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
+                       return False;
+               }
+               ret = sam_io_user_info20("", ctr->info.id20, ps, depth);
+               break;
        case 21:
                if (UNMARSHALLING(ps))
                        ctr->info.id21 = (SAM_USER_INFO_21 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_21));
@@ -5989,7 +6230,7 @@ inits a SAMR_R_QUERY_USERINFO structure.
 ********************************************************************/
 
 void init_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO * r_u,
-                               SAM_USERINFO_CTR * ctr, uint32 status)
+                               SAM_USERINFO_CTR * ctr, NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_query_userinfo\n"));
 
@@ -6081,7 +6322,7 @@ BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO * q_u,
 inits a SAMR_R_SET_USERINFO structure.
 ********************************************************************/
 
-void init_samr_r_set_userinfo(SAMR_R_SET_USERINFO * r_u, uint32 status)
+void init_samr_r_set_userinfo(SAMR_R_SET_USERINFO * r_u, NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_set_userinfo\n"));
 
@@ -6169,7 +6410,7 @@ BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 * q_u,
 inits a SAMR_R_SET_USERINFO2 structure.
 ********************************************************************/
 
-void init_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 * r_u, uint32 status)
+void init_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 * r_u, NTSTATUS status)
 {
        DEBUG(5, ("init_samr_r_set_userinfo2\n"));
 
@@ -6584,7 +6825,7 @@ BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER * q_u,
 inits a SAMR_R_CHGPASSWD_USER structure.
 ********************************************************************/
 
-void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER * r_u, uint32 status)
+void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER * r_u, NTSTATUS status)
 {
        DEBUG(5, ("init_r_chgpasswd_user\n"));