Getting back to a compilable state (not there yet but close).
[ira/wip.git] / source3 / rpc_server / srv_samr.c
index 08bba0eef4416265bf807714e7d3a0c3a3a70d3c..49db7a9e48650363f6d64749eb4e4dc1e6f47c77 100644 (file)
@@ -1,3 +1,4 @@
+#define OLD_NTDOMAIN 1
 /* 
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
@@ -117,7 +118,6 @@ static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
 static char *unmap_unixname(char *unix_user_name, int name_idx)
 {
        char *mapfile = lp_username_map();
-       char *s;
        char **lines;
        static pstring tok;
        int i;
@@ -134,7 +134,7 @@ static char *unmap_unixname(char *unix_user_name, int name_idx)
        DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
 
        for (i=0; lines[i]; i++) {
-               char *unixname = s;
+               char *unixname = lines[i];
                char *dosname = strchr(unixname,'=');
 
                if (!dosname)
@@ -277,6 +277,7 @@ static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
                        if ((pwd = getpwent()) == NULL) break;
                        user_name_len = strlen(pwd->pw_name);
                        pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
+                       ZERO_STRUCTP(&pw_buf[(*num_entries)]);
                        init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->pw_name, user_name_len);
                        init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
                        pw_buf[(*num_entries)].user_rid = pw_rid;
@@ -296,6 +297,7 @@ static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
                while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) && 
                        (*num_entries < max_num_entries)) {
                        user_name_len = strlen(unmap_name);
+                       ZERO_STRUCTP(&pw_buf[(*num_entries)]);
                        init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), unmap_name, user_name_len);
                        init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
                        pw_buf[(*num_entries)].user_rid = pw_rid;
@@ -331,7 +333,7 @@ static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
 /*******************************************************************
  samr_reply_unknown_1
  ********************************************************************/
-static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
+static BOOL samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
                                prs_struct *rdata)
 {
        SAMR_R_CLOSE_HND r_u;
@@ -352,10 +354,12 @@ static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
        DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
 
        /* store the response in the SMB stream */
-       samr_io_r_close_hnd("", &r_u, rdata, 0);
+       if(!samr_io_r_close_hnd("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -366,10 +370,12 @@ static BOOL api_samr_close_hnd(prs_struct *data, prs_struct *rdata)
        SAMR_Q_CLOSE_HND q_u;
 
        /* grab the samr unknown 1 */
-       samr_io_q_close_hnd("", &q_u, data, 0);
+       if(!samr_io_q_close_hnd("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_close_hnd(&q_u, rdata);
+       if(!samr_reply_close_hnd(&q_u, rdata))
+               return False;
 
        return True;
 }
@@ -378,7 +384,7 @@ static BOOL api_samr_close_hnd(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_open_domain
  ********************************************************************/
-static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
+static BOOL samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
                                prs_struct *rdata)
 {
        SAMR_R_OPEN_DOMAIN r_u;
@@ -413,10 +419,12 @@ static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
        DEBUG(5,("samr_open_domain: %d\n", __LINE__));
 
        /* store the response in the SMB stream */
-       samr_io_r_open_domain("", &r_u, rdata, 0);
+       if(!samr_io_r_open_domain("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_open_domain: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -427,10 +435,12 @@ static BOOL api_samr_open_domain(prs_struct *data, prs_struct *rdata)
        SAMR_Q_OPEN_DOMAIN q_u;
 
        /* grab the samr open */
-       samr_io_q_open_domain("", &q_u, data, 0);
+       if(!samr_io_q_open_domain("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_open_domain(&q_u, rdata);
+       if(!samr_reply_open_domain(&q_u, rdata))
+               return False;
 
        return True;
 }
@@ -439,7 +449,7 @@ static BOOL api_samr_open_domain(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_unknown_2c
  ********************************************************************/
-static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
+static BOOL samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
                                prs_struct *rdata)
 {
        SAMR_R_UNKNOWN_2C r_u;
@@ -462,10 +472,12 @@ static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
        DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
 
        /* store the response in the SMB stream */
-       samr_io_r_unknown_2c("", &r_u, rdata, 0);
+       if(!samr_io_r_unknown_2c("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -476,10 +488,12 @@ static BOOL api_samr_unknown_2c(prs_struct *data, prs_struct *rdata)
        SAMR_Q_UNKNOWN_2C q_u;
 
        /* grab the samr open */
-       samr_io_q_unknown_2c("", &q_u, data, 0);
+       if(!samr_io_q_unknown_2c("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_unknown_2c(&q_u, rdata);
+       if(!samr_reply_unknown_2c(&q_u, rdata))
+               return False;
 
        return True;
 }
@@ -488,7 +502,7 @@ static BOOL api_samr_unknown_2c(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_unknown_3
  ********************************************************************/
-static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
+static BOOL samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
                                prs_struct *rdata)
 {
        SAMR_R_UNKNOWN_3 r_u;
@@ -540,10 +554,12 @@ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
        DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
 
        /* store the response in the SMB stream */
-       samr_io_r_unknown_3("", &r_u, rdata, 0);
+       if(!samr_io_r_unknown_3("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -554,10 +570,12 @@ static BOOL api_samr_unknown_3(prs_struct *data, prs_struct *rdata)
        SAMR_Q_UNKNOWN_3 q_u;
 
        /* grab the samr open */
-       samr_io_q_unknown_3("", &q_u, data, 0);
+       if(!samr_io_q_unknown_3("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_unknown_3(&q_u, rdata);
+       if(!samr_reply_unknown_3(&q_u, rdata))
+               return False;
 
        return True;
 }
@@ -566,7 +584,7 @@ static BOOL api_samr_unknown_3(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_enum_dom_users
  ********************************************************************/
-static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
+static BOOL samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
                                prs_struct *rdata)
 {
        SAMR_R_ENUM_DOM_USERS r_e;
@@ -594,10 +612,12 @@ static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
                                   pass, r_e.status);
 
        /* store the response in the SMB stream */
-       samr_io_r_enum_dom_users("", &r_e, rdata, 0);
+       if(!samr_io_r_enum_dom_users("", &r_e, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -608,19 +628,20 @@ static BOOL api_samr_enum_dom_users(prs_struct *data, prs_struct *rdata)
        SAMR_Q_ENUM_DOM_USERS q_e;
 
        /* grab the samr open */
-       samr_io_q_enum_dom_users("", &q_e, data, 0);
+       if(!samr_io_q_enum_dom_users("", &q_e, data, 0))
+               return False;
 
        /* construct reply. */
-       samr_reply_enum_dom_users(&q_e, rdata);
+       if(!samr_reply_enum_dom_users(&q_e, rdata))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
  samr_reply_enum_dom_groups
  ********************************************************************/
-static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
+static BOOL samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
                                prs_struct *rdata)
 {
        SAMR_R_ENUM_DOM_GROUPS r_e;
@@ -642,6 +663,7 @@ static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
 
        got_grps = True;
        num_entries = 1;
+       ZERO_STRUCTP(&pass[0]);
        init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
        pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
 
@@ -651,10 +673,12 @@ static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
        }
 
        /* store the response in the SMB stream */
-       samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
+       if(!samr_io_r_enum_dom_groups("", &r_e, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -665,10 +689,12 @@ static BOOL api_samr_enum_dom_groups(prs_struct *data, prs_struct *rdata)
        SAMR_Q_ENUM_DOM_GROUPS q_e;
 
        /* grab the samr open */
-       samr_io_q_enum_dom_groups("", &q_e, data, 0);
+       if(!samr_io_q_enum_dom_groups("", &q_e, data, 0))
+               return False;
 
        /* construct reply. */
-       samr_reply_enum_dom_groups(&q_e, rdata);
+       if(!samr_reply_enum_dom_groups(&q_e, rdata))
+               return False;
 
        return True;
 }
@@ -676,7 +702,7 @@ static BOOL api_samr_enum_dom_groups(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_enum_dom_aliases
  ********************************************************************/
-static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
+static BOOL samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
                                prs_struct *rdata)
 {
        SAMR_R_ENUM_DOM_ALIASES r_e;
@@ -735,10 +761,12 @@ static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
        init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
 
        /* store the response in the SMB stream */
-       samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
+       if(!samr_io_r_enum_dom_aliases("", &r_e, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -749,10 +777,12 @@ static BOOL api_samr_enum_dom_aliases(prs_struct *data, prs_struct *rdata)
        SAMR_Q_ENUM_DOM_ALIASES q_e;
 
        /* grab the samr open */
-       samr_io_q_enum_dom_aliases("", &q_e, data, 0);
+       if(!samr_io_q_enum_dom_aliases("", &q_e, data, 0))
+               return False;
 
        /* construct reply. */
-       samr_reply_enum_dom_aliases(&q_e, rdata);
+       if(!samr_reply_enum_dom_aliases(&q_e, rdata))
+               return False;
 
        return True;
 }
@@ -761,8 +791,7 @@ static BOOL api_samr_enum_dom_aliases(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_query_dispinfo
  ********************************************************************/
-static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
-                               prs_struct *rdata)
+static BOOL samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u, prs_struct *rdata)
 {
        SAMR_R_QUERY_DISPINFO r_e;
        SAM_INFO_CTR ctr;
@@ -789,10 +818,36 @@ static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
 
        if (r_e.status == 0x0)
        {
+         /* decide how many entries to get depending on the max_entries 
+            and max_size passed by client */
+         uint32 retsize;
+
+         if(q_u->max_entries > MAX_SAM_ENTRIES)
+           q_u->max_entries = MAX_SAM_ENTRIES;
+         
+         retsize = (q_u->max_entries * (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1)))
+           + 3*sizeof(uint32);
+
+         if(retsize > q_u->max_size)
+           {
+             /* determine max_entries based on max_size */
+             q_u->max_entries = (q_u->max_size - 3*sizeof(uint32)) /
+               (sizeof(SAM_ENTRY1)+sizeof(SAM_STR1));
+             q_u->max_entries = (q_u->max_entries>0?q_u->max_entries:1);
+           }
+
+         DEBUG(10,("samr_reply_query_dispinfo: Setting q_u->max_entries to %u\n",q_u->max_entries));
+
                become_root(True);
-               got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
+               got_pwds = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, q_u->max_entries, 0);
                unbecome_root(True);
 
+               /* more left - set resume handle */
+               if(total_entries > num_entries)
+                 {
+                   r_e.status = 0x105;
+                 }
+
                switch (q_u->switch_level)
                {
                        case 0x1:
@@ -821,16 +876,24 @@ static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
                }
        }
 
-       if (r_e.status == 0)
+       /* more left - set resume handle */
+       if(total_entries > num_entries)
+         {
+           r_e.status = 0x105;
+         }
+
+       if (r_e.status == 0 || r_e.status == 0x105)
        {
-               init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
+         init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
        }
 
        /* store the response in the SMB stream */
-       samr_io_r_query_dispinfo("", &r_e, rdata, 0);
+       if(!samr_io_r_query_dispinfo("", &r_e, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -841,10 +904,12 @@ static BOOL api_samr_query_dispinfo(prs_struct *data, prs_struct *rdata)
        SAMR_Q_QUERY_DISPINFO q_e;
 
        /* grab the samr open */
-       samr_io_q_query_dispinfo("", &q_e, data, 0);
+       if(!samr_io_q_query_dispinfo("", &q_e, data, 0))
+               return False;
 
        /* construct reply. */
-       samr_reply_query_dispinfo(&q_e, rdata);
+       if(!samr_reply_query_dispinfo(&q_e, rdata))
+               return False;
 
        return True;
 }
@@ -853,39 +918,43 @@ static BOOL api_samr_query_dispinfo(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_query_aliasinfo
  ********************************************************************/
-static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
+static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
                                prs_struct *rdata)
 {
-       SAMR_R_QUERY_ALIASINFO r_e;
+  SAMR_R_QUERY_ALIASINFO r_e;
+  fstring alias_desc = "Local Unix group";
+  fstring alias="";
+  uint8 type;
+  uint32 alias_rid;
 
-       r_e.status = 0x0;
-       r_e.ptr = 0;
+  ZERO_STRUCT(r_e);
 
-       /* find the policy handle.  open a policy on it. */
-       if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
-       {
-               r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-
-       DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
-
-       if (r_e.status == 0x0)
-       {
-               if (q_u->switch_level != 3)
-               {
-                       r_e.status = NT_STATUS_INVALID_INFO_CLASS;
-               }
-       }
+  DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
 
-       init_samr_r_query_aliasinfo(&r_e, q_u->switch_level,
-                           "local UNIX group",
-                               r_e.status);
+  /* find the policy handle.  open a policy on it. */
+  if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+    {
+      r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+    }
 
-       /* store the response in the SMB stream */
-       samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
+  alias_rid = get_lsa_policy_samr_rid(&q_u->pol);
+  if(alias_rid == 0xffffffff)
+      r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
 
-       DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
+  if(!lookup_local_rid(alias_rid, alias, &type))
+    {
+      r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
+    }
+  
+  init_samr_r_query_aliasinfo(&r_e, q_u->switch_level, alias, alias_desc);
+  
+  /* store the response in the SMB stream */
+  if(!samr_io_r_query_aliasinfo("", &r_e, rdata, 0))
+               return False;
+  
+  DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -896,10 +965,12 @@ static BOOL api_samr_query_aliasinfo(prs_struct *data, prs_struct *rdata)
        SAMR_Q_QUERY_ALIASINFO q_e;
 
        /* grab the samr open */
-       samr_io_q_query_aliasinfo("", &q_e, data, 0);
+       if(!samr_io_q_query_aliasinfo("", &q_e, data, 0))
+               return False;
 
        /* construct reply. */
-       samr_reply_query_aliasinfo(&q_e, rdata);
+       if(!samr_reply_query_aliasinfo(&q_e, rdata))
+               return False;
 
        return True;
 }
@@ -908,7 +979,7 @@ static BOOL api_samr_query_aliasinfo(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_lookup_ids
  ********************************************************************/
-static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
+static BOOL samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
                                prs_struct *rdata)
 {
        uint32 rid[MAX_SAM_ENTRIES];
@@ -961,10 +1032,12 @@ static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
        init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
 
        /* store the response in the SMB stream */
-       samr_io_r_lookup_ids("", &r_u, rdata, 0);
+       if(!samr_io_r_lookup_ids("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -975,10 +1048,12 @@ static BOOL api_samr_lookup_ids(prs_struct *data, prs_struct *rdata)
        SAMR_Q_LOOKUP_IDS q_u;
 
        /* grab the samr 0x10 */
-       samr_io_q_lookup_ids("", &q_u, data, 0);
+       if(!samr_io_q_lookup_ids("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_lookup_ids(&q_u, rdata);
+       if(!samr_reply_lookup_ids(&q_u, rdata))
+               return False;
 
        return True;
 }
@@ -988,71 +1063,73 @@ static BOOL api_samr_lookup_ids(prs_struct *data, prs_struct *rdata)
  ********************************************************************/
 
 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
-                               prs_struct *rdata)
+                                   prs_struct *rdata)
 {
-       uint32 rid[MAX_SAM_ENTRIES];
-       uint8  type[MAX_SAM_ENTRIES];
-       uint32 status = 0;
-       int i;
-       int num_rids = q_u->num_names1;
-       DOM_SID pol_sid;
-
-       SAMR_R_LOOKUP_NAMES r_u;
-
-       DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
-
-       ZERO_ARRAY(rid);
-       ZERO_ARRAY(type);
-
-       if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
-        status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
-               init_samr_r_lookup_names(&r_u, 0, rid, type, status);
-               if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
-                       DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
-               return False;
-               }
-               return True;
+  uint32 rid[MAX_SAM_ENTRIES];
+  uint8  type[MAX_SAM_ENTRIES];
+  uint32 status = 0;
+  int i;
+  int num_rids = q_u->num_names1;
+  DOM_SID pol_sid;
+
+  SAMR_R_LOOKUP_NAMES r_u;
+
+  DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
+
+  ZERO_ARRAY(rid);
+  ZERO_ARRAY(type);
+
+  if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
+    status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+    init_samr_r_lookup_names(&r_u, 0, rid, type, status);
+    if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
+      DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
+      return False;
     }
+    return True;
+  }
 
-       if (num_rids > MAX_SAM_ENTRIES) {
-               num_rids = MAX_SAM_ENTRIES;
-               DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
-       }
-
-       SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
+  if (num_rids > MAX_SAM_ENTRIES) {
+    num_rids = MAX_SAM_ENTRIES;
+    DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
+  }
 
-       for (i = 0; i < num_rids; i++) {
-               fstring name;
+  SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
 
-               status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+  for (i = 0; i < num_rids; i++) {
+    fstring name;
 
-               rid [i] = 0xffffffff;
-               type[i] = SID_NAME_UNKNOWN;
+    status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
 
-               fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
-                               q_u->uni_name[i].uni_str_len));
+    rid [i] = 0xffffffff;
+    type[i] = SID_NAME_UNKNOWN;
 
-               if(sid_equal(&pol_sid, &global_sam_sid)) {
-                       DOM_SID sid;
+    fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
+                              q_u->uni_name[i].uni_str_len));
 
-                       if(lookup_local_name(global_myname, name, &sid, &type[i])) {
-                               sid_split_rid( &sid, &rid[i]);
-                               status = 0;
-                       }
-               }
+    if(sid_equal(&pol_sid, &global_sam_sid)) 
+    {
+      DOM_SID sid;
+      if(lookup_local_name(global_myname, name, 
+                          &sid, &type[i]))
+       {
+         sid_split_rid( &sid, &rid[i]);
+         status = 0;
        }
+    }
+  }
 
-       init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
+  init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
 
-       /* store the response in the SMB stream */
-       if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
-               DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
-               return False;
-       }
+  /* store the response in the SMB stream */
+  if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
+    DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
+    return False;
+  }
 
-       DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
+  DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
 
-       return True;
+  return True;
 }
 
 /*******************************************************************
@@ -1141,8 +1218,7 @@ static BOOL api_samr_chgpasswd_user(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_unknown_38
  ********************************************************************/
-static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
-                               prs_struct *rdata)
+static BOOL samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, prs_struct *rdata)
 {
        SAMR_R_UNKNOWN_38 r_u;
 
@@ -1151,9 +1227,11 @@ static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
        init_samr_r_unknown_38(&r_u);
 
        /* store the response in the SMB stream */
-       samr_io_r_unknown_38("", &r_u, rdata, 0);
+       if(!samr_io_r_unknown_38("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
+       return True;
 }
 
 /*******************************************************************
@@ -1164,10 +1242,12 @@ static BOOL api_samr_unknown_38(prs_struct *data, prs_struct *rdata)
        SAMR_Q_UNKNOWN_38 q_u;
 
        /* unknown 38 command */
-       samr_io_q_unknown_38("", &q_u, data, 0);
+       if(!samr_io_q_unknown_38("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_unknown_38(&q_u, rdata);
+       if(!samr_reply_unknown_38(&q_u, rdata))
+               return False;
 
        return True;
 }
@@ -1176,7 +1256,7 @@ static BOOL api_samr_unknown_38(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_unknown_12
  ********************************************************************/
-static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
                                prs_struct *rdata)
 {
        fstring group_names[MAX_SAM_ENTRIES];
@@ -1213,10 +1293,12 @@ static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
        init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
 
        /* store the response in the SMB stream */
-       samr_io_r_unknown_12("", &r_u, rdata, 0);
+       if(!samr_io_r_unknown_12("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -1227,10 +1309,12 @@ static BOOL api_samr_unknown_12(prs_struct *data, prs_struct *rdata)
        SAMR_Q_UNKNOWN_12 q_u;
 
        /* grab the samr lookup names */
-       samr_io_q_unknown_12("", &q_u, data, 0);
+       if(!samr_io_q_unknown_12("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_unknown_12(&q_u, rdata);
+       if(!samr_reply_unknown_12(&q_u, rdata))
+               return False;
 
        return True;
 }
@@ -1239,9 +1323,7 @@ static BOOL api_samr_unknown_12(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_open_user
  ********************************************************************/
-static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
-                               prs_struct *rdata,
-                               int status)
+static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int status)
 {
        SAMR_R_OPEN_USER r_u;
        struct sam_passwd *sam_pass;
@@ -1289,10 +1371,12 @@ static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
        DEBUG(5,("samr_open_user: %d\n", __LINE__));
 
        /* store the response in the SMB stream */
-       samr_io_r_open_user("", &r_u, rdata, 0);
+       if(!samr_io_r_open_user("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_open_user: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -1303,10 +1387,12 @@ static BOOL api_samr_open_user(prs_struct *data, prs_struct *rdata)
        SAMR_Q_OPEN_USER q_u;
 
        /* grab the samr unknown 22 */
-       samr_io_q_open_user("", &q_u, data, 0);
+       if(!samr_io_q_open_user("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_open_user(&q_u, rdata, 0x0);
+       if(!samr_reply_open_user(&q_u, rdata, 0x0))
+               return False;
 
        return True;
 }
@@ -1419,7 +1505,7 @@ static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
 /*******************************************************************
  samr_reply_query_userinfo
  ********************************************************************/
-static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
+static BOOL samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
                                prs_struct *rdata)
 {
        SAMR_R_QUERY_USERINFO r_u;
@@ -1494,10 +1580,12 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
        init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
 
        /* store the response in the SMB stream */
-       samr_io_r_query_userinfo("", &r_u, rdata, 0);
+       if(!samr_io_r_query_userinfo("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -1508,10 +1596,12 @@ static BOOL api_samr_query_userinfo(prs_struct *data, prs_struct *rdata)
        SAMR_Q_QUERY_USERINFO q_u;
 
        /* grab the samr unknown 24 */
-       samr_io_q_query_userinfo("", &q_u, data, 0);
+       if(!samr_io_q_query_userinfo("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_query_userinfo(&q_u, rdata);
+       if(!samr_reply_query_userinfo(&q_u, rdata))
+               return False;
 
        return True;
 }
@@ -1520,7 +1610,7 @@ static BOOL api_samr_query_userinfo(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_query_usergroups
  ********************************************************************/
-static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
+static BOOL samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
                                prs_struct *rdata)
 {
        SAMR_R_QUERY_USERGROUPS r_u;
@@ -1569,15 +1659,18 @@ static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
        init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
 
        /* store the response in the SMB stream */
-       samr_io_r_query_usergroups("", &r_u, rdata, 0);
+       if(!samr_io_r_query_usergroups("", &r_u, rdata, 0)) {
+               if (gids)
+                       free((char *)gids);
+               return False;
+       }
 
        if (gids)
-       {
                free((char *)gids);
-       }
 
        DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
-
+       
+       return True;
 }
 
 /*******************************************************************
@@ -1587,10 +1680,12 @@ static BOOL api_samr_query_usergroups(prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_QUERY_USERGROUPS q_u;
        /* grab the samr unknown 32 */
-       samr_io_q_query_usergroups("", &q_u, data, 0);
+       if(!samr_io_q_query_usergroups("", &q_u, data, 0))
+               return False;
 
        /* construct reply. */
-       samr_reply_query_usergroups(&q_u, rdata);
+       if(!samr_reply_query_usergroups(&q_u, rdata))
+               return False;
 
        return True;
 }
@@ -1599,8 +1694,7 @@ static BOOL api_samr_query_usergroups(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_query_dom_info
  ********************************************************************/
-static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
-                               prs_struct *rdata)
+static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *rdata)
 {
        SAMR_R_QUERY_DOMAIN_INFO r_u;
        SAM_UNK_CTR ctr;
@@ -1643,10 +1737,12 @@ static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
        init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
 
        /* store the response in the SMB stream */
-       samr_io_r_query_dom_info("", &r_u, rdata, 0);
+       if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -1657,20 +1753,20 @@ static BOOL api_samr_query_dom_info(prs_struct *data, prs_struct *rdata)
        SAMR_Q_QUERY_DOMAIN_INFO q_e;
 
        /* grab the samr unknown 8 command */
-       samr_io_q_query_dom_info("", &q_e, data, 0);
+       if(!samr_io_q_query_dom_info("", &q_e, data, 0))
+               return False;
 
        /* construct reply. */
-       samr_reply_query_dom_info(&q_e, rdata);
+       if(!samr_reply_query_dom_info(&q_e, rdata))
+               return False;
 
        return True;
 }
 
-
-
 /*******************************************************************
  samr_reply_unknown_32
  ********************************************************************/
-static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
+static BOOL samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
                                prs_struct *rdata,
                                int status)
 {
@@ -1693,10 +1789,12 @@ static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
        DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
 
        /* store the response in the SMB stream */
-       samr_io_r_unknown_32("", &r_u, rdata, 0);
+       if(!samr_io_r_unknown_32("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -1739,7 +1837,8 @@ static BOOL api_samr_unknown_32(prs_struct *data, prs_struct *rdata)
        }
 
        /* construct reply. */
-       samr_reply_unknown_32(&q_u, rdata, status);
+       if(!samr_reply_unknown_32(&q_u, rdata, status))
+               return False;
 
        return True;
 }
@@ -1748,8 +1847,7 @@ static BOOL api_samr_unknown_32(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_connect_anon
  ********************************************************************/
-static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
-                               prs_struct *rdata)
+static BOOL samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u, prs_struct *rdata)
 {
        SAMR_R_CONNECT_ANON r_u;
        BOOL pol_open = False;
@@ -1778,10 +1876,12 @@ static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
        DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
 
        /* store the response in the SMB stream */
-       samr_io_r_connect_anon("", &r_u, rdata, 0);
+       if(!samr_io_r_connect_anon("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -1792,10 +1892,12 @@ static BOOL api_samr_connect_anon(prs_struct *data, prs_struct *rdata)
        SAMR_Q_CONNECT_ANON q_u;
 
        /* grab the samr open policy */
-       samr_io_q_connect_anon("", &q_u, data, 0);
+       if(!samr_io_q_connect_anon("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_connect_anon(&q_u, rdata);
+       if(!samr_reply_connect_anon(&q_u, rdata))
+               return False;
 
        return True;
 }
@@ -1803,8 +1905,7 @@ static BOOL api_samr_connect_anon(prs_struct *data, prs_struct *rdata)
 /*******************************************************************
  samr_reply_connect
  ********************************************************************/
-static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
-                               prs_struct *rdata)
+static BOOL samr_reply_connect(SAMR_Q_CONNECT *q_u, prs_struct *rdata)
 {
        SAMR_R_CONNECT r_u;
        BOOL pol_open = False;
@@ -1833,10 +1934,12 @@ static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
        DEBUG(5,("samr_connect: %d\n", __LINE__));
 
        /* store the response in the SMB stream */
-       samr_io_r_connect("", &r_u, rdata, 0);
+       if(!samr_io_r_connect("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_connect: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
@@ -1847,19 +1950,103 @@ static BOOL api_samr_connect(prs_struct *data, prs_struct *rdata)
        SAMR_Q_CONNECT q_u;
 
        /* grab the samr open policy */
-       samr_io_q_connect("", &q_u, data, 0);
+       if(!samr_io_q_connect("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_connect(&q_u, rdata);
+       if(!samr_reply_connect(&q_u, rdata))
+               return False;
+
+       return True;
+}
+
+/**********************************************************************
+ api_reply_lookup_domain
+ **********************************************************************/
+static BOOL samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN* q_u, prs_struct* rdata)
+{
+  SAMR_R_LOOKUP_DOMAIN r_u;
+  
+  r_u.status = 0x0;
+  if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
+       {
+               r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+               DEBUG(5,("samr_reply_lookup_domain: invalid handle\n"));
+       }
+  
+  /* assume the domain name sent is our global_myname and 
+     send global_sam_sid */
+  init_samr_r_lookup_domain(&r_u, &global_sam_sid, r_u.status);
+  
+       if(!samr_io_r_lookup_domain("", &r_u, rdata, 0))
+               return False;
+
+  DEBUG(5,("samr_reply_lookup_domain: %d\n", __LINE__));
+       return True; 
+}
+  
+/**********************************************************************
+ api_samr_lookup_domain
+ **********************************************************************/
+static BOOL api_samr_lookup_domain(prs_struct* data, prs_struct* rdata)
+{
+  SAMR_Q_LOOKUP_DOMAIN q_u;
+  
+  if(!samr_io_q_lookup_domain("", &q_u, data, 0))
+               return False;
+
+  if(!samr_reply_lookup_domain(&q_u, rdata))
+               return False;
+  
+  return True;
+}
+
+/**********************************************************************
+ samr_reply_enum_domains
+ **********************************************************************/
+static BOOL samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS* q_u, prs_struct* rdata)
+{
+  SAMR_R_ENUM_DOMAINS r_u;
+  fstring dom[2];
+
+  fstrcpy(dom[0],global_myname);
+  fstrcpy(dom[1],"Builtin");
+  r_u.status = 0;
+   
+  init_samr_r_enum_domains(&r_u, q_u->start_idx, dom, 2); 
+  if(!samr_io_r_enum_domains("", &r_u, rdata, 0)) {
+               free(r_u.sam);
+               free(r_u.uni_dom_name);
+               return False;
+       }
+
+  free(r_u.sam);
+  free(r_u.uni_dom_name);
 
        return True;
 }
 
+/**********************************************************************
+ api_samr_enum_domains
+ **********************************************************************/
+static BOOL api_samr_enum_domains(prs_struct* data, prs_struct* rdata)
+{
+  SAMR_Q_ENUM_DOMAINS q_u;
+
+  if(!samr_io_q_enum_domains("", &q_u, data, 0))
+               return False;
+  
+  if(!samr_reply_enum_domains(&q_u, rdata))
+               return False;
+
+  return True;
+}
+
 /*******************************************************************
  samr_reply_open_alias
  ********************************************************************/
-static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
-                               prs_struct *rdata)
+static BOOL samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, prs_struct *rdata)
 {
        SAMR_R_OPEN_ALIAS r_u;
        BOOL pol_open = False;
@@ -1888,10 +2075,12 @@ static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
        DEBUG(5,("samr_open_alias: %d\n", __LINE__));
 
        /* store the response in the SMB stream */
-       samr_io_r_open_alias("", &r_u, rdata, 0);
+       if(!samr_io_r_open_alias("", &r_u, rdata, 0))
+               return False;
 
        DEBUG(5,("samr_open_alias: %d\n", __LINE__));
-
+       
+       return True;
 }
 
 /*******************************************************************
@@ -1903,10 +2092,12 @@ static BOOL api_samr_open_alias(prs_struct *data, prs_struct *rdata)
        SAMR_Q_OPEN_ALIAS q_u;
 
        /* grab the samr open policy */
-       samr_io_q_open_alias("", &q_u, data, 0);
+       if(!samr_io_q_open_alias("", &q_u, data, 0))
+               return False;
 
        /* construct reply.  always indicate success */
-       samr_reply_open_alias(&q_u, rdata);
+       if(!samr_reply_open_alias(&q_u, rdata))
+               return False;
 
        return True;
 }
@@ -1938,6 +2129,8 @@ static struct api_struct api_samr_cmds [] =
        { "SAMR_OPEN_DOMAIN"      , SAMR_OPEN_DOMAIN      , api_samr_open_domain      },
        { "SAMR_UNKNOWN_3"        , SAMR_UNKNOWN_3        , api_samr_unknown_3        },
        { "SAMR_UNKNOWN_2C"       , SAMR_UNKNOWN_2C       , api_samr_unknown_2c       },
+       { "SAMR_LOOKUP_DOMAIN"    , SAMR_LOOKUP_DOMAIN    , api_samr_lookup_domain    },
+       { "SAMR_ENUM_DOMAINS"     , SAMR_ENUM_DOMAINS     , api_samr_enum_domains     },
        { NULL                    , 0                     , NULL                      }
 };
 
@@ -1948,3 +2141,4 @@ BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
 {
     return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);
 }
+#undef OLD_NTDOMAIN