s3-smbd provide struct smbd_server_connection * to conn_snum_used
[nivanova/samba-autobuild/.git] / source3 / smbd / lanman.c
index 744d460e8b8b7dd610d6172944e6876cce75fd1f..5958bb9746da1f8ee19c58b48dca3f0ce1ea4577 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    Inter-process communication and named pipe handling
    Copyright (C) Andrew Tridgell 1992-1998
    */
 
 #include "includes.h"
+#include "smbd/smbd.h"
 #include "smbd/globals.h"
-#include "../librpc/gen_ndr/cli_samr.h"
-#include "../librpc/gen_ndr/cli_spoolss.h"
+#include "rpc_client/rpc_client.h"
+#include "../librpc/gen_ndr/ndr_samr_c.h"
+#include "../librpc/gen_ndr/ndr_spoolss_c.h"
 #include "rpc_client/cli_spoolss.h"
 #include "rpc_client/init_spoolss.h"
-#include "../librpc/gen_ndr/cli_srvsvc.h"
-#include "../librpc/gen_ndr/srv_samr.h"
-#include "../librpc/gen_ndr/srv_spoolss.h"
-#include "../librpc/gen_ndr/srv_srvsvc.h"
+#include "../librpc/gen_ndr/ndr_srvsvc_c.h"
 #include "../librpc/gen_ndr/rap.h"
 #include "../lib/util/binsearch.h"
+#include "../libcli/auth/libcli_auth.h"
+#include "rpc_client/init_lsa.h"
+#include "../libcli/security/security.h"
+#include "printing.h"
+#include "passdb/machine_sid.h"
+#include "auth.h"
+#include "rpc_server/rpc_ncacn_np.h"
 
 #ifdef CHECK_TYPES
 #undef CHECK_TYPES
@@ -72,14 +78,16 @@ static char *smb_realloc_limit(void *ptr, size_t size)
        return val;
 }
 
-static bool api_Unsupported(connection_struct *conn, uint16 vuid,
+static bool api_Unsupported(struct smbd_server_connection *sconn,
+                           connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt, int mprcnt,
                                char **rdata, char **rparam,
                                int *rdata_len, int *rparam_len);
 
-static bool api_TooSmall(connection_struct *conn, uint16 vuid, char *param, char *data,
+static bool api_TooSmall(struct smbd_server_connection *sconn,
+                        connection_struct *conn, uint16 vuid, char *param, char *data,
                         int mdrcnt, int mprcnt,
                         char **rdata, char **rparam,
                         int *rdata_len, int *rparam_len);
@@ -109,11 +117,11 @@ static int CopyExpanded(connection_struct *conn,
        }
        buf = talloc_sub_advanced(ctx,
                                lp_servicename(SNUM(conn)),
-                               conn->server_info->unix_name,
+                               conn->session_info->unix_name,
                                conn->connectpath,
-                               conn->server_info->utok.gid,
-                               conn->server_info->sanitized_username,
-                               pdb_get_domain(conn->server_info->sam_account),
+                               conn->session_info->utok.gid,
+                               conn->session_info->sanitized_username,
+                               conn->session_info->info3->base.domain.string,
                                buf);
        if (!buf) {
                *p_space_remaining = 0;
@@ -160,11 +168,11 @@ static int StrlenExpanded(connection_struct *conn, int snum, char *s)
        }
        buf = talloc_sub_advanced(ctx,
                                lp_servicename(SNUM(conn)),
-                               conn->server_info->unix_name,
+                               conn->session_info->unix_name,
                                conn->connectpath,
-                               conn->server_info->utok.gid,
-                               conn->server_info->sanitized_username,
-                               pdb_get_domain(conn->server_info->sam_account),
+                               conn->session_info->utok.gid,
+                               conn->session_info->sanitized_username,
+                               conn->session_info->info3->base.domain.string,
                                buf);
        if (!buf) {
                return 0;
@@ -188,7 +196,7 @@ struct pack_desc {
        int buflen;        /* remaining size for fixed part; on init: length of base */
        int subcount;       /* count of substructures */
        char *structbuf;  /* pointer into buffer for remaining fixed part */
-       int stringlen;    /* remaining size for variable part */                
+       int stringlen;    /* remaining size for variable part */
        char *stringbuf;  /* pointer into buffer for remaining variable part */
        int neededlen;    /* total needed size */
        int usedlen;        /* total used size (usedlen <= neededlen and usedlen <= buflen) */
@@ -509,7 +517,7 @@ static int check_printq_info(struct pack_desc* desc,
 #define RAP_QUEUE_STATUS_PAUSED 1
 #define RAP_QUEUE_STATUS_ERROR 2
 
-/* turn a print job status into a on the wire status 
+/* turn a print job status into a on the wire status
 */
 static int printj_spoolss_status(int v)
 {
@@ -524,7 +532,7 @@ static int printj_spoolss_status(int v)
        return 0;
 }
 
-/* turn a print queue status into a on the wire status 
+/* turn a print queue status into a on the wire status
 */
 static int printq_spoolss_status(int v)
 {
@@ -604,9 +612,9 @@ static void fill_printq_info_52(struct spoolss_DriverInfo3 *driver,
 {
        int                             i;
        fstring                         location;
-       trim_string((char *)driver->driver_path, "\\print$\\WIN40\\0\\", 0);
-       trim_string((char *)driver->data_file, "\\print$\\WIN40\\0\\", 0);
-       trim_string((char *)driver->help_file, "\\print$\\WIN40\\0\\", 0);
+       trim_string(discard_const_p(char, driver->driver_path), "\\print$\\WIN40\\0\\", 0);
+       trim_string(discard_const_p(char, driver->data_file), "\\print$\\WIN40\\0\\", 0);
+       trim_string(discard_const_p(char, driver->help_file), "\\print$\\WIN40\\0\\", 0);
 
        PACKI(desc, "W", 0x0400);                     /* don't know */
        PACKS(desc, "z", driver->driver_name);        /* long printer name */
@@ -633,7 +641,7 @@ static void fill_printq_info_52(struct spoolss_DriverInfo3 *driver,
 
        for ( i=0; i<count && driver->dependent_files && *driver->dependent_files[i]; i++)
        {
-               trim_string((char *)driver->dependent_files[i], "\\print$\\WIN40\\0\\", 0);
+               trim_string(discard_const_p(char, driver->dependent_files[i]), "\\print$\\WIN40\\0\\", 0);
                PACKS(desc,"z",driver->dependent_files[i]);         /* driver files to copy */
                DEBUG(3,("Dependent File: %s:\n", driver->dependent_files[i]));
        }
@@ -747,7 +755,8 @@ static int get_printerdrivernumber(const struct spoolss_DriverInfo3 *driver)
        return result;
 }
 
-static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
+static bool api_DosPrintQGetInfo(struct smbd_server_connection *sconn,
+                                connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -768,10 +777,11 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
        TALLOC_CTX *mem_ctx = talloc_tos();
        NTSTATUS status;
        struct rpc_pipe_client *cli = NULL;
+       struct dcerpc_binding_handle *b = NULL;
        struct policy_handle handle;
        struct spoolss_DevmodeContainer devmode_ctr;
        union spoolss_DriverInfo driver_info;
-       union spoolss_JobInfo *job_info;
+       union spoolss_JobInfo *job_info = NULL;
        union spoolss_PrinterInfo printer_info;
 
        if (!str1 || !str2 || !p) {
@@ -816,19 +826,28 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
 
        ZERO_STRUCT(handle);
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_spoolss.syntax_id,
-                                       rpc_spoolss_dispatch, conn->server_info,
-                                       &cli);
+       if (QueueName == NULL || (strlen(QueueName) < 1)) {
+               desc.errcode = W_ERROR_V(WERR_INVALID_PARAM);
+               goto out;
+       }
+
+       status = rpc_pipe_open_interface(conn,
+                                        &ndr_table_spoolss.syntax_id,
+                                        conn->session_info,
+                                        &conn->sconn->client_id,
+                                        conn->sconn->msg_ctx,
+                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_DosPrintQGetInfo: could not connect to spoolss: %s\n",
                          nt_errstr(status)));
                desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
                goto out;
        }
+       b = cli->binding_handle;
 
        ZERO_STRUCT(devmode_ctr);
 
-       status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
+       status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
                                            QueueName,
                                            "RAW",
                                            devmode_ctr,
@@ -925,8 +944,8 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
                desc.errcode = ERRbuftoosmall;
 
  out:
-       if (cli && is_valid_policy_hnd(&handle)) {
-               rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
+       if (b && is_valid_policy_hnd(&handle)) {
+               dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
        }
 
        *rdata_len = desc.usedlen;
@@ -951,7 +970,8 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
  View list of all print jobs on all queues.
 ****************************************************************************/
 
-static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
+static bool api_DosPrintQEnum(struct smbd_server_connection *sconn,
+                             connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt, int mprcnt,
@@ -972,6 +992,7 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
        TALLOC_CTX *mem_ctx = talloc_tos();
        NTSTATUS status;
        struct rpc_pipe_client *cli = NULL;
+       struct dcerpc_binding_handle *b = NULL;
        struct spoolss_DevmodeContainer devmode_ctr;
        uint32_t num_printers;
        union spoolss_PrinterInfo *printer_info;
@@ -1007,15 +1028,19 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
                return(True);
        }
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_spoolss.syntax_id,
-                                       rpc_spoolss_dispatch, conn->server_info,
-                                       &cli);
+       status = rpc_pipe_open_interface(conn,
+                                        &ndr_table_spoolss.syntax_id,
+                                        conn->session_info,
+                                        &conn->sconn->client_id,
+                                        conn->sconn->msg_ctx,
+                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_DosPrintQEnum: could not connect to spoolss: %s\n",
                          nt_errstr(status)));
                desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
                goto out;
        }
+       b = cli->binding_handle;
 
        werr = rpccli_spoolss_enumprinters(cli, mem_ctx,
                                           PRINTER_ENUM_LOCAL,
@@ -1070,7 +1095,7 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
                ZERO_STRUCT(handle);
                ZERO_STRUCT(devmode_ctr);
 
-               status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
+               status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
                                                    printername,
                                                    "RAW",
                                                    devmode_ctr,
@@ -1122,9 +1147,7 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
                subcntarr[i] = num_jobs;
                subcnt += subcntarr[i];
 
-               if (cli && is_valid_policy_hnd(&handle)) {
-                       rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
-               }
+               dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
        }
 
        if (init_package(&desc,queuecnt,subcnt)) {
@@ -1162,7 +1185,7 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
  Get info level for a server list query.
 ****************************************************************************/
 
-static bool check_server_info(int uLevel, char* id)
+static bool check_session_info(int uLevel, char* id)
 {
        switch( uLevel ) {
                case 0:
@@ -1175,7 +1198,7 @@ static bool check_server_info(int uLevel, char* id)
                                return False;
                        }
                        break;
-               default: 
+               default:
                        return False;
        }
        return True;
@@ -1194,7 +1217,7 @@ struct srv_info_struct {
  number of entries.
 ******************************************************************/
 
-static int get_server_info(uint32 servertype, 
+static int get_session_info(uint32 servertype,
                           struct srv_info_struct **servers,
                           const char *domain)
 {
@@ -1235,7 +1258,7 @@ static int get_server_info(uint32 servertype,
                        alloced += 10;
                        *servers = SMB_REALLOC_ARRAY(*servers,struct srv_info_struct, alloced);
                        if (!*servers) {
-                               DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n"));
+                               DEBUG(0,("get_session_info: failed to enlarge servers info struct!\n"));
                                TALLOC_FREE(lines);
                                return 0;
                        }
@@ -1294,7 +1317,7 @@ static int get_server_info(uint32 servertype,
                        ok = False;
                }
 
-               if ((servertype & SV_TYPE_DOMAIN_ENUM) != 
+               if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
                                (s->type & SV_TYPE_DOMAIN_ENUM)) {
                        DEBUG(4,("s: dom mismatch "));
                        ok = False;
@@ -1326,8 +1349,8 @@ static int get_server_info(uint32 servertype,
  Fill in a server info structure.
 ******************************************************************/
 
-static int fill_srv_info(struct srv_info_struct *service, 
-                        int uLevel, char **buf, int *buflen, 
+static int fill_srv_info(struct srv_info_struct *service,
+                        int uLevel, char **buf, int *buflen,
                         char **stringbuf, int *stringspace, char *baseaddr)
 {
        int struct_len;
@@ -1404,7 +1427,7 @@ static int fill_srv_info(struct srv_info_struct *service,
 
 static int srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
 {
-       return StrCaseCmp(s1->name,s2->name);
+       return strcasecmp_m(s1->name,s2->name);
 }
 
 /****************************************************************************
@@ -1412,10 +1435,11 @@ static int srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
  extracted from lists saved by nmbd on the local host.
 ****************************************************************************/
 
-static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid,
+static bool api_RNetServerEnum2(struct smbd_server_connection *sconn,
+                               connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
-                               int mdrcnt, int mprcnt, char **rdata, 
+                               int mdrcnt, int mprcnt, char **rdata,
                                char **rparam, int *rdata_len, int *rparam_len)
 {
        char *str1 = get_safe_str_ptr(param, tpscnt, param, 2);
@@ -1447,9 +1471,9 @@ static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid,
        }
 
        /* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
-          any other bit (they may just set this bit on its own) they 
-          want all the locally seen servers. However this bit can be 
-          set on its own so set the requested servers to be 
+          any other bit (they may just set this bit on its own) they
+          want all the locally seen servers. However this bit can be
+          set on its own so set the requested servers to be
           ALL - DOMAIN_ENUM. */
 
        if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) && !(servertype & SV_TYPE_DOMAIN_ENUM)) {
@@ -1464,7 +1488,7 @@ static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid,
        if (!prefix_ok(str1,"WrLehD")) {
                return False;
        }
-       if (!check_server_info(uLevel,str2)) {
+       if (!check_session_info(uLevel,str2)) {
                return False;
        }
 
@@ -1484,7 +1508,7 @@ static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid,
        DEBUG(4, ("domain [%s]\n", domain));
 
        if (lp_browse_list()) {
-               total = get_server_info(servertype,&servers,domain);
+               total = get_session_info(servertype,&servers,domain);
        }
 
        data_len = fixed_len = string_len = 0;
@@ -1572,7 +1596,7 @@ static int srv_name_match(const char *n1, const char *n2)
         *  the server will return a list of servers that exist on
         *  the network greater than or equal to the FirstNameToReturn.
         */
-       int ret = StrCaseCmp(n1, n2);
+       int ret = strcasecmp_m(n1, n2);
 
        if (ret <= 0) {
                return 0;
@@ -1581,7 +1605,8 @@ static int srv_name_match(const char *n1, const char *n2)
        return ret;
 }
 
-static bool api_RNetServerEnum3(connection_struct *conn, uint16 vuid,
+static bool api_RNetServerEnum3(struct smbd_server_connection *sconn,
+                               connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt, int mprcnt, char **rdata,
@@ -1634,7 +1659,7 @@ static bool api_RNetServerEnum3(connection_struct *conn, uint16 vuid,
        if (strcmp(str1, "WrLehDzz") != 0) {
                return false;
        }
-       if (!check_server_info(uLevel,str2)) {
+       if (!check_session_info(uLevel,str2)) {
                return False;
        }
 
@@ -1659,7 +1684,7 @@ static bool api_RNetServerEnum3(connection_struct *conn, uint16 vuid,
                  domain, first_name));
 
        if (lp_browse_list()) {
-               total = get_server_info(servertype,&servers,domain);
+               total = get_session_info(servertype,&servers,domain);
        }
 
        data_len = fixed_len = string_len = 0;
@@ -1683,7 +1708,7 @@ static bool api_RNetServerEnum3(connection_struct *conn, uint16 vuid,
                         */
                        for (;first > 0;) {
                                int ret;
-                               ret = StrCaseCmp(first_name,
+                               ret = strcasecmp_m(first_name,
                                                 servers[first-1].name);
                                if (ret > 0) {
                                        break;
@@ -1773,10 +1798,11 @@ static bool api_RNetServerEnum3(connection_struct *conn, uint16 vuid,
   command 0x34 - suspected of being a "Lookup Names" stub api
   ****************************************************************************/
 
-static bool api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid,
+static bool api_RNetGroupGetUsers(struct smbd_server_connection *sconn,
+                                 connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
-                               int mdrcnt, int mprcnt, char **rdata, 
+                               int mdrcnt, int mprcnt, char **rdata,
                                char **rparam, int *rdata_len, int *rparam_len)
 {
        char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
@@ -1963,7 +1989,8 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
        return len;
 }
 
-static bool api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
+static bool api_RNetShareGetInfo(struct smbd_server_connection *sconn,
+                                connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -1972,17 +1999,18 @@ static bool api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
 {
        char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
        char *str2 = skip_string(param,tpscnt,str1);
-       char *netname = skip_string(param,tpscnt,str2);
+       char *netname_in = skip_string(param,tpscnt,str2);
+       char *netname = NULL;
        char *p = skip_string(param,tpscnt,netname);
        int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
        int snum;
 
-       if (!str1 || !str2 || !netname || !p) {
+       if (!str1 || !str2 || !netname_in || !p) {
                return False;
        }
 
-       snum = find_service(netname);
-       if (snum < 0) {
+       snum = find_service(talloc_tos(), netname_in, &netname);
+       if (snum < 0 || !netname) {
                return False;
        }
 
@@ -2026,7 +2054,8 @@ static bool api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
   Share names longer than 12 bytes must be skipped.
  ****************************************************************************/
 
-static bool api_RNetShareEnum( connection_struct *conn, uint16 vuid,
+static bool api_RNetShareEnum(struct smbd_server_connection *sconn,
+                             connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int                mdrcnt,
@@ -2063,7 +2092,7 @@ static bool api_RNetShareEnum( connection_struct *conn, uint16 vuid,
        /* Ensure all the usershares are loaded. */
        become_root();
        load_registry_shares();
-       count = load_usershare_shares();
+       count = load_usershare_shares(sconn);
        unbecome_root();
 
        data_len = fixed_len = string_len = 0;
@@ -2133,7 +2162,8 @@ static bool api_RNetShareEnum( connection_struct *conn, uint16 vuid,
   Add a share
   ****************************************************************************/
 
-static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
+static bool api_RNetShareAdd(struct smbd_server_connection *sconn,
+                            connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -2157,6 +2187,7 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
        struct rpc_pipe_client *cli = NULL;
        union srvsvc_NetShareInfo info;
        struct srvsvc_NetShareInfo2 info2;
+       struct dcerpc_binding_handle *b;
 
        if (!str1 || !str2 || !p) {
                return False;
@@ -2223,8 +2254,10 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
                return false;
        }
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_srvsvc.syntax_id,
-                                       rpc_srvsvc_dispatch, conn->server_info,
+       status = rpc_pipe_open_interface(mem_ctx, &ndr_table_srvsvc.syntax_id,
+                                       conn->session_info,
+                                       &conn->sconn->client_id,
+                                       conn->sconn->msg_ctx,
                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_RNetShareAdd: could not connect to srvsvc: %s\n",
@@ -2233,6 +2266,8 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
                goto out;
        }
 
+       b = cli->binding_handle;
+
        info2.name              = sharename;
        info2.type              = STYPE_DISKTREE;
        info2.comment           = comment;
@@ -2244,7 +2279,7 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
 
        info.info2 = &info2;
 
-       status = rpccli_srvsvc_NetShareAdd(cli, mem_ctx,
+       status = dcerpc_srvsvc_NetShareAdd(b, mem_ctx,
                                           cli->srv_name_slash,
                                           2,
                                           &info,
@@ -2288,7 +2323,8 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
   view list of groups available
   ****************************************************************************/
 
-static bool api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
+static bool api_RNetGroupEnum(struct smbd_server_connection *sconn,
+                             connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -2306,7 +2342,8 @@ static bool api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
        uint32_t resume_handle;
        struct rpc_pipe_client *samr_pipe;
        struct policy_handle samr_handle, domain_handle;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b;
 
        if (!str1 || !str2 || !p) {
                return False;
@@ -2316,9 +2353,9 @@ static bool api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
                return False;
        }
 
-       /* parameters  
+       /* parameters
         * W-> resume context (number of users to skip)
-        * r -> return parameter pointer to receive buffer 
+        * r -> return parameter pointer to receive buffer
         * L -> length of receive buffer
         * e -> return parameter number of entries
         * h -> return parameter total number of users
@@ -2328,30 +2365,46 @@ static bool api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
                return False;
        }
 
-       status = rpc_pipe_open_internal(
-               talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
-               conn->server_info, &samr_pipe);
+       status = rpc_pipe_open_interface(
+               talloc_tos(), &ndr_table_samr.syntax_id,
+               conn->session_info, &conn->sconn->client_id,
+               conn->sconn->msg_ctx, &samr_pipe);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
                          nt_errstr(status)));
                return false;
        }
 
-       status = rpccli_samr_Connect2(samr_pipe, talloc_tos(), global_myname(),
-                                     SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle);
+       b = samr_pipe->binding_handle;
+
+       status = dcerpc_samr_Connect2(b, talloc_tos(), global_myname(),
+                                     SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle,
+                                     &result);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
                          nt_errstr(status)));
                return false;
        }
+       if (!NT_STATUS_IS_OK(result)) {
+               DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
+                         nt_errstr(result)));
+               return false;
+       }
 
-       status = rpccli_samr_OpenDomain(samr_pipe, talloc_tos(), &samr_handle,
+       status = dcerpc_samr_OpenDomain(b, talloc_tos(), &samr_handle,
                                        SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
-                                       get_global_sam_sid(), &domain_handle);
+                                       get_global_sam_sid(), &domain_handle,
+                                       &result);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
                          nt_errstr(status)));
-               rpccli_samr_Close(samr_pipe, talloc_tos(), &samr_handle);
+               dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
+               return false;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
+                         nt_errstr(result)));
+               dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
                return false;
        }
 
@@ -2376,19 +2429,26 @@ static bool api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
                struct samr_SamArray *sam_entries;
                uint32_t num_entries;
 
-               status = rpccli_samr_EnumDomainGroups(samr_pipe, talloc_tos(),
+               status = dcerpc_samr_EnumDomainGroups(b, talloc_tos(),
                                                      &domain_handle,
                                                      &resume_handle,
                                                      &sam_entries, 1,
-                                                     &num_entries);
+                                                     &num_entries,
+                                                     &result);
                if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(10, ("rpccli_samr_EnumDomainGroups returned "
+                       DEBUG(10, ("dcerpc_samr_EnumDomainGroups returned "
                                   "%s\n", nt_errstr(status)));
                        break;
                }
+               if (!NT_STATUS_IS_OK(result)) {
+                       status = result;
+                       DEBUG(10, ("dcerpc_samr_EnumDomainGroups returned "
+                                  "%s\n", nt_errstr(result)));
+                       break;
+               }
 
                if (num_entries == 0) {
-                       DEBUG(10, ("rpccli_samr_EnumDomainGroups returned "
+                       DEBUG(10, ("dcerpc_samr_EnumDomainGroups returned "
                                   "no entries -- done\n"));
                        break;
                }
@@ -2423,8 +2483,8 @@ static bool api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
                TALLOC_FREE(sam_entries);
        }
 
-       rpccli_samr_Close(samr_pipe, talloc_tos(), &domain_handle);
-       rpccli_samr_Close(samr_pipe, talloc_tos(), &samr_handle);
+       dcerpc_samr_Close(b, talloc_tos(), &domain_handle, &result);
+       dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
 
        *rdata_len = PTR_DIFF(p,*rdata);
 
@@ -2445,7 +2505,8 @@ static bool api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
  Get groups that a user is a member of.
 ******************************************************************/
 
-static bool api_NetUserGetGroups(connection_struct *conn,uint16 vuid,
+static bool api_NetUserGetGroups(struct smbd_server_connection *sconn,
+                                connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -2469,7 +2530,8 @@ static bool api_NetUserGetGroups(connection_struct *conn,uint16 vuid,
        struct lsa_Strings names;
        struct samr_Ids type, rid;
        struct samr_RidWithAttributeArray *rids;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b;
 
        if (!str1 || !str2 || !UserName || !p) {
                return False;
@@ -2509,42 +2571,63 @@ static bool api_NetUserGetGroups(connection_struct *conn,uint16 vuid,
        p = *rdata;
        endp = *rdata + *rdata_len;
 
-       status = rpc_pipe_open_internal(
-               talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
-               conn->server_info, &samr_pipe);
+       status = rpc_pipe_open_interface(
+               talloc_tos(), &ndr_table_samr.syntax_id,
+               conn->session_info, &conn->sconn->client_id,
+               conn->sconn->msg_ctx, &samr_pipe);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
                          nt_errstr(status)));
                return false;
        }
 
-       status = rpccli_samr_Connect2(samr_pipe, talloc_tos(), global_myname(),
-                                     SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle);
+       b = samr_pipe->binding_handle;
+
+       status = dcerpc_samr_Connect2(b, talloc_tos(), global_myname(),
+                                     SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle,
+                                     &result);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
                          nt_errstr(status)));
                return false;
        }
+       if (!NT_STATUS_IS_OK(result)) {
+               DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
+                         nt_errstr(result)));
+               return false;
+       }
 
-       status = rpccli_samr_OpenDomain(samr_pipe, talloc_tos(), &samr_handle,
+       status = dcerpc_samr_OpenDomain(b, talloc_tos(), &samr_handle,
                                        SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
-                                       get_global_sam_sid(), &domain_handle);
+                                       get_global_sam_sid(), &domain_handle,
+                                       &result);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
                          nt_errstr(status)));
                goto close_sam;
        }
+       if (!NT_STATUS_IS_OK(result)) {
+               DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
+                         nt_errstr(result)));
+               goto close_sam;
+       }
 
        name.string = UserName;
 
-       status = rpccli_samr_LookupNames(samr_pipe, talloc_tos(),
+       status = dcerpc_samr_LookupNames(b, talloc_tos(),
                                         &domain_handle, 1, &name,
-                                        &rid, &type);
+                                        &rid, &type,
+                                        &result);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
                          nt_errstr(status)));
                goto close_domain;
        }
+       if (!NT_STATUS_IS_OK(result)) {
+               DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
+                         nt_errstr(result)));
+               goto close_domain;
+       }
 
        if (type.ids[0] != SID_NAME_USER) {
                DEBUG(10, ("%s is a %s, not a user\n", UserName,
@@ -2552,31 +2635,44 @@ static bool api_NetUserGetGroups(connection_struct *conn,uint16 vuid,
                goto close_domain;
        }
 
-       status = rpccli_samr_OpenUser(samr_pipe, talloc_tos(),
+       status = dcerpc_samr_OpenUser(b, talloc_tos(),
                                      &domain_handle,
                                      SAMR_USER_ACCESS_GET_GROUPS,
-                                     rid.ids[0], &user_handle);
+                                     rid.ids[0], &user_handle,
+                                     &result);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
                          nt_errstr(status)));
                goto close_domain;
        }
+       if (!NT_STATUS_IS_OK(result)) {
+               DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
+                         nt_errstr(result)));
+               goto close_domain;
+       }
 
-       status = rpccli_samr_GetGroupsForUser(samr_pipe, talloc_tos(),
-                                             &user_handle, &rids);
+       status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
+                                             &user_handle, &rids,
+                                             &result);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
                          nt_errstr(status)));
                goto close_user;
        }
+       if (!NT_STATUS_IS_OK(result)) {
+               DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
+                         nt_errstr(result)));
+               goto close_user;
+       }
 
        for (i=0; i<rids->count; i++) {
 
-               status = rpccli_samr_LookupRids(samr_pipe, talloc_tos(),
+               status = dcerpc_samr_LookupRids(b, talloc_tos(),
                                                &domain_handle,
                                                1, &rids->rids[i].rid,
-                                               &names, &type);
-               if (NT_STATUS_IS_OK(status) && (names.count == 1)) {
+                                               &names, &type,
+                                               &result);
+               if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result) && (names.count == 1)) {
                        strlcpy(p, names.names[0].string, PTR_DIFF(endp,p));
                        p += 21;
                        count++;
@@ -2591,11 +2687,11 @@ static bool api_NetUserGetGroups(connection_struct *conn,uint16 vuid,
        ret = True;
 
  close_user:
-       rpccli_samr_Close(samr_pipe, talloc_tos(), &user_handle);
+       dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
  close_domain:
-       rpccli_samr_Close(samr_pipe, talloc_tos(), &domain_handle);
+       dcerpc_samr_Close(b, talloc_tos(), &domain_handle, &result);
  close_sam:
-       rpccli_samr_Close(samr_pipe, talloc_tos(), &samr_handle);
+       dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
 
        return ret;
 }
@@ -2604,7 +2700,8 @@ static bool api_NetUserGetGroups(connection_struct *conn,uint16 vuid,
  Get all users.
 ******************************************************************/
 
-static bool api_RNetUserEnum(connection_struct *conn, uint16 vuid,
+static bool api_RNetUserEnum(struct smbd_server_connection *sconn,
+                            connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -2619,13 +2716,15 @@ static bool api_RNetUserEnum(connection_struct *conn, uint16 vuid,
 
        struct rpc_pipe_client *samr_pipe;
        struct policy_handle samr_handle, domain_handle;
-       NTSTATUS status;
+       NTSTATUS status, result;
 
        char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
        char *str2 = skip_string(param,tpscnt,str1);
        char *p = skip_string(param,tpscnt,str2);
        char *endp = NULL;
 
+       struct dcerpc_binding_handle *b;
+
        if (!str1 || !str2 || !p) {
                return False;
        }
@@ -2664,30 +2763,46 @@ static bool api_RNetUserEnum(connection_struct *conn, uint16 vuid,
        p = *rdata;
        endp = *rdata + *rdata_len;
 
-       status = rpc_pipe_open_internal(
-               talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
-               conn->server_info, &samr_pipe);
+       status = rpc_pipe_open_interface(
+               talloc_tos(), &ndr_table_samr.syntax_id,
+               conn->session_info, &conn->sconn->client_id,
+               conn->sconn->msg_ctx, &samr_pipe);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
                          nt_errstr(status)));
                return false;
        }
 
-       status = rpccli_samr_Connect2(samr_pipe, talloc_tos(), global_myname(),
-                                     SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle);
+       b = samr_pipe->binding_handle;
+
+       status = dcerpc_samr_Connect2(b, talloc_tos(), global_myname(),
+                                     SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle,
+                                     &result);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
                          nt_errstr(status)));
                return false;
        }
+       if (!NT_STATUS_IS_OK(result)) {
+               DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
+                         nt_errstr(result)));
+               return false;
+       }
 
-       status = rpccli_samr_OpenDomain(samr_pipe, talloc_tos(), &samr_handle,
+       status = dcerpc_samr_OpenDomain(b, talloc_tos(), &samr_handle,
                                        SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
-                                       get_global_sam_sid(), &domain_handle);
+                                       get_global_sam_sid(), &domain_handle,
+                                       &result);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
                          nt_errstr(status)));
-               rpccli_samr_Close(samr_pipe, talloc_tos(), &samr_handle);
+               dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
+               return false;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
+                         nt_errstr(result)));
+               dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
                return false;
        }
 
@@ -2699,20 +2814,26 @@ static bool api_RNetUserEnum(connection_struct *conn, uint16 vuid,
                struct samr_SamArray *sam_entries;
                uint32_t num_entries;
 
-               status = rpccli_samr_EnumDomainUsers(samr_pipe, talloc_tos(),
+               status = dcerpc_samr_EnumDomainUsers(b, talloc_tos(),
                                                     &domain_handle,
                                                     &resume_handle,
                                                     0, &sam_entries, 1,
-                                                    &num_entries);
+                                                    &num_entries,
+                                                    &result);
 
                if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(10, ("rpccli_samr_EnumDomainUsers returned "
+                       DEBUG(10, ("dcerpc_samr_EnumDomainUsers returned "
                                   "%s\n", nt_errstr(status)));
                        break;
                }
+               if (!NT_STATUS_IS_OK(result)) {
+                       DEBUG(10, ("dcerpc_samr_EnumDomainUsers returned "
+                                  "%s\n", nt_errstr(result)));
+                       break;
+               }
 
                if (num_entries == 0) {
-                       DEBUG(10, ("rpccli_samr_EnumDomainUsers returned "
+                       DEBUG(10, ("dcerpc_samr_EnumDomainUsers returned "
                                   "no entries -- done\n"));
                        break;
                }
@@ -2745,8 +2866,8 @@ static bool api_RNetUserEnum(connection_struct *conn, uint16 vuid,
                TALLOC_FREE(sam_entries);
        }
 
-       rpccli_samr_Close(samr_pipe, talloc_tos(), &domain_handle);
-       rpccli_samr_Close(samr_pipe, talloc_tos(), &samr_handle);
+       dcerpc_samr_Close(b, talloc_tos(), &domain_handle, &result);
+       dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
 
        *rdata_len = PTR_DIFF(p,*rdata);
 
@@ -2762,7 +2883,8 @@ static bool api_RNetUserEnum(connection_struct *conn, uint16 vuid,
  Get the time of day info.
 ****************************************************************************/
 
-static bool api_NetRemoteTOD(connection_struct *conn,uint16 vuid,
+static bool api_NetRemoteTOD(struct smbd_server_connection *sconn,
+                            connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -2794,7 +2916,7 @@ static bool api_NetRemoteTOD(connection_struct *conn,uint16 vuid,
                                            by NT in a "net time" operation,
                                            it seems to ignore the one below */
 
-       /* the client expects to get localtime, not GMT, in this bit 
+       /* the client expects to get localtime, not GMT, in this bit
                (I think, this needs testing) */
        t = localtime(&unixdate);
        if (!t) {
@@ -2820,7 +2942,8 @@ static bool api_NetRemoteTOD(connection_struct *conn,uint16 vuid,
  Set the user password.
 *****************************************************************************/
 
-static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
+static bool api_SetUserPassword(struct smbd_server_connection *sconn,
+                               connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -2831,6 +2954,22 @@ static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
        char *p = NULL;
        fstring user;
        fstring pass1,pass2;
+       TALLOC_CTX *mem_ctx = talloc_tos();
+       NTSTATUS status, result;
+       struct rpc_pipe_client *cli = NULL;
+       struct policy_handle connect_handle, domain_handle, user_handle;
+       struct lsa_String domain_name;
+       struct dom_sid2 *domain_sid;
+       struct lsa_String names;
+       struct samr_Ids rids;
+       struct samr_Ids types;
+       struct samr_Password old_lm_hash;
+       struct samr_Password new_lm_hash;
+       int errcode = NERR_badpass;
+       uint32_t rid;
+       int encrypted;
+       int min_pwd_length;
+       struct dcerpc_binding_handle *b = NULL;
 
        /* Skip 2 strings. */
        p = skip_string(param,tpscnt,np);
@@ -2863,6 +3002,18 @@ static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
        memcpy(pass1,p,16);
        memcpy(pass2,p+16,16);
 
+       encrypted = get_safe_SVAL(param,tpscnt,p+32,0,-1);
+       if (encrypted == -1) {
+               errcode = W_ERROR_V(WERR_INVALID_PARAM);
+               goto out;
+       }
+
+       min_pwd_length = get_safe_SVAL(param,tpscnt,p+34,0,-1);
+       if (min_pwd_length == -1) {
+               errcode = W_ERROR_V(WERR_INVALID_PARAM);
+               goto out;
+       }
+
        *rparam_len = 4;
        *rparam = smb_realloc_limit(*rparam,*rparam_len);
        if (!*rparam) {
@@ -2871,59 +3022,172 @@ static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
 
        *rdata_len = 0;
 
-       SSVAL(*rparam,0,NERR_badpass);
-       SSVAL(*rparam,2,0);             /* converter word */
+       DEBUG(3,("Set password for <%s> (encrypted: %d, min_pwd_length: %d)\n",
+               user, encrypted, min_pwd_length));
 
-       DEBUG(3,("Set password for <%s>\n",user));
+       ZERO_STRUCT(connect_handle);
+       ZERO_STRUCT(domain_handle);
+       ZERO_STRUCT(user_handle);
 
-       /*
-        * Attempt to verify the old password against smbpasswd entries
-        * Win98 clients send old and new password in plaintext for this call.
-        */
+       status = rpc_pipe_open_interface(mem_ctx, &ndr_table_samr.syntax_id,
+                                       conn->session_info,
+                                       &conn->sconn->client_id,
+                                       conn->sconn->msg_ctx,
+                                       &cli);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("api_SetUserPassword: could not connect to samr: %s\n",
+                         nt_errstr(status)));
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
 
-       {
-               struct auth_serversupplied_info *server_info = NULL;
-               DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
+       b = cli->binding_handle;
 
-               if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
+       status = dcerpc_samr_Connect2(b, mem_ctx,
+                                     global_myname(),
+                                     SAMR_ACCESS_CONNECT_TO_SERVER |
+                                     SAMR_ACCESS_ENUM_DOMAINS |
+                                     SAMR_ACCESS_LOOKUP_DOMAIN,
+                                     &connect_handle,
+                                     &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
 
-                       become_root();
-                       if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2, False, NULL))) {
-                               SSVAL(*rparam,0,NERR_Success);
-                       }
-                       unbecome_root();
+       init_lsa_String(&domain_name, get_global_sam_name());
 
-                       TALLOC_FREE(server_info);
-               }
-               data_blob_clear_free(&password);
+       status = dcerpc_samr_LookupDomain(b, mem_ctx,
+                                         &connect_handle,
+                                         &domain_name,
+                                         &domain_sid,
+                                         &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
        }
 
-       /*
-        * If the plaintext change failed, attempt
-        * the old encrypted method. NT will generate this
-        * after trying the samr method. Note that this
-        * method is done as a last resort as this
-        * password change method loses the NT password hash
-        * and cannot change the UNIX password as no plaintext
-        * is received.
-        */
+       status = dcerpc_samr_OpenDomain(b, mem_ctx,
+                                       &connect_handle,
+                                       SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+                                       domain_sid,
+                                       &domain_handle,
+                                       &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
 
-       if(SVAL(*rparam,0) != NERR_Success) {
-               struct samu *hnd = NULL;
+       init_lsa_String(&names, user);
 
-               if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd)) {
-                       become_root();
-                       if (change_lanman_password(hnd,(uchar *)pass2)) {
-                               SSVAL(*rparam,0,NERR_Success);
-                       }
-                       unbecome_root();
-                       TALLOC_FREE(hnd);
-               }
+       status = dcerpc_samr_LookupNames(b, mem_ctx,
+                                        &domain_handle,
+                                        1,
+                                        &names,
+                                        &rids,
+                                        &types,
+                                        &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
+
+       if (rids.count != 1) {
+               errcode = W_ERROR_V(WERR_NO_SUCH_USER);
+               goto out;
+       }
+       if (rids.count != types.count) {
+               errcode = W_ERROR_V(WERR_INVALID_PARAM);
+               goto out;
+       }
+       if (types.ids[0] != SID_NAME_USER) {
+               errcode = W_ERROR_V(WERR_INVALID_PARAM);
+               goto out;
+       }
+
+       rid = rids.ids[0];
+
+       status = dcerpc_samr_OpenUser(b, mem_ctx,
+                                     &domain_handle,
+                                     SAMR_USER_ACCESS_CHANGE_PASSWORD,
+                                     rid,
+                                     &user_handle,
+                                     &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
+
+       if (encrypted == 0) {
+               E_deshash(pass1, old_lm_hash.hash);
+               E_deshash(pass2, new_lm_hash.hash);
+       } else {
+               ZERO_STRUCT(old_lm_hash);
+               ZERO_STRUCT(new_lm_hash);
+               memcpy(old_lm_hash.hash, pass1, MIN(strlen(pass1), 16));
+               memcpy(new_lm_hash.hash, pass1, MIN(strlen(pass2), 16));
+       }
+
+       status = dcerpc_samr_ChangePasswordUser(b, mem_ctx,
+                                               &user_handle,
+                                               true, /* lm_present */
+                                               &old_lm_hash,
+                                               &new_lm_hash,
+                                               false, /* nt_present */
+                                               NULL, /* old_nt_crypted */
+                                               NULL, /* new_nt_crypted */
+                                               false, /* cross1_present */
+                                               NULL, /* nt_cross */
+                                               false, /* cross2_present */
+                                               NULL, /* lm_cross */
+                                               &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
+
+       errcode = NERR_Success;
+ out:
+
+       if (b && is_valid_policy_hnd(&user_handle)) {
+               dcerpc_samr_Close(b, mem_ctx, &user_handle, &result);
+       }
+       if (b && is_valid_policy_hnd(&domain_handle)) {
+               dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
+       }
+       if (b && is_valid_policy_hnd(&connect_handle)) {
+               dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
        }
 
        memset((char *)pass1,'\0',sizeof(fstring));
-       memset((char *)pass2,'\0',sizeof(fstring));      
+       memset((char *)pass2,'\0',sizeof(fstring));
 
+       SSVAL(*rparam,0,errcode);
+       SSVAL(*rparam,2,0);             /* converter word */
        return(True);
 }
 
@@ -2931,7 +3195,8 @@ static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
   Set the user password (SamOEM version - gets plaintext).
 ****************************************************************************/
 
-static bool api_SamOEMChangePassword(connection_struct *conn,uint16 vuid,
+static bool api_SamOEMChangePassword(struct smbd_server_connection *sconn,
+                                    connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -2942,13 +3207,14 @@ static bool api_SamOEMChangePassword(connection_struct *conn,uint16 vuid,
        char *p = get_safe_str_ptr(param,tpscnt,param,2);
 
        TALLOC_CTX *mem_ctx = talloc_tos();
-       NTSTATUS status;
+       NTSTATUS status, result;
        struct rpc_pipe_client *cli = NULL;
        struct lsa_AsciiString server, account;
        struct samr_CryptPassword password;
        struct samr_Password hash;
        int errcode = NERR_badpass;
        int bufsize;
+       struct dcerpc_binding_handle *b;
 
        *rparam_len = 4;
        *rparam = smb_realloc_limit(*rparam,*rparam_len);
@@ -3014,8 +3280,10 @@ static bool api_SamOEMChangePassword(connection_struct *conn,uint16 vuid,
        memcpy(password.data, data, 516);
        memcpy(hash.hash, data+516, 16);
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
-                                       rpc_samr_dispatch, conn->server_info,
+       status = rpc_pipe_open_interface(mem_ctx, &ndr_table_samr.syntax_id,
+                                       conn->session_info,
+                                       &conn->sconn->client_id,
+                                       conn->sconn->msg_ctx,
                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_SamOEMChangePassword: could not connect to samr: %s\n",
@@ -3024,18 +3292,25 @@ static bool api_SamOEMChangePassword(connection_struct *conn,uint16 vuid,
                goto out;
        }
 
+       b = cli->binding_handle;
+
        init_lsa_AsciiString(&server, global_myname());
        init_lsa_AsciiString(&account, user);
 
-       status = rpccli_samr_OemChangePasswordUser2(cli, mem_ctx,
+       status = dcerpc_samr_OemChangePasswordUser2(b, mem_ctx,
                                                    &server,
                                                    &account,
                                                    &password,
-                                                   &hash);
+                                                   &hash,
+                                                   &result);
        if (!NT_STATUS_IS_OK(status)) {
                errcode = W_ERROR_V(ntstatus_to_werror(status));
                goto out;
        }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
 
        errcode = NERR_Success;
  out:
@@ -3047,10 +3322,11 @@ static bool api_SamOEMChangePassword(connection_struct *conn,uint16 vuid,
 
 /****************************************************************************
   delete a print job
-  Form: <W> <> 
+  Form: <W> <>
   ****************************************************************************/
 
-static bool api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
+static bool api_RDosPrintJobDel(struct smbd_server_connection *sconn,
+                               connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -3069,6 +3345,7 @@ static bool api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
        TALLOC_CTX *mem_ctx = talloc_tos();
        NTSTATUS status;
        struct rpc_pipe_client *cli = NULL;
+       struct dcerpc_binding_handle *b = NULL;
        struct policy_handle handle;
        struct spoolss_DevmodeContainer devmode_ctr;
        enum spoolss_JobControl command;
@@ -3099,19 +3376,23 @@ static bool api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
 
        ZERO_STRUCT(handle);
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_spoolss.syntax_id,
-                                       rpc_spoolss_dispatch, conn->server_info,
-                                       &cli);
+       status = rpc_pipe_open_interface(conn,
+                                        &ndr_table_spoolss.syntax_id,
+                                        conn->session_info,
+                                        &conn->sconn->client_id,
+                                        conn->sconn->msg_ctx,
+                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_RDosPrintJobDel: could not connect to spoolss: %s\n",
                          nt_errstr(status)));
                errcode = W_ERROR_V(ntstatus_to_werror(status));
                goto out;
        }
+       b = cli->binding_handle;
 
        ZERO_STRUCT(devmode_ctr);
 
-       status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
+       status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
                                            sharename,
                                            "RAW",
                                            devmode_ctr,
@@ -3147,7 +3428,7 @@ static bool api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
                goto out;
        }
 
-       status = rpccli_spoolss_SetJob(cli, mem_ctx,
+       status = dcerpc_spoolss_SetJob(b, mem_ctx,
                                       &handle,
                                       jobid,
                                       NULL, /* unique ptr ctr */
@@ -3163,11 +3444,11 @@ static bool api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
        }
 
  out:
-       if (cli && is_valid_policy_hnd(&handle)) {
-               rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
+       if (b && is_valid_policy_hnd(&handle)) {
+               dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
        }
 
-       SSVAL(*rparam,0,errcode);       
+       SSVAL(*rparam,0,errcode);
        SSVAL(*rparam,2,0);             /* converter word */
 
        return(True);
@@ -3177,7 +3458,8 @@ static bool api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
   Purge a print queue - or pause or resume it.
   ****************************************************************************/
 
-static bool api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid,
+static bool api_WPrintQueueCtrl(struct smbd_server_connection *sconn,
+                               connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -3194,6 +3476,7 @@ static bool api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid,
 
        TALLOC_CTX *mem_ctx = talloc_tos();
        struct rpc_pipe_client *cli = NULL;
+       struct dcerpc_binding_handle *b = NULL;
        struct policy_handle handle;
        struct spoolss_SetPrinterInfoCtr info_ctr;
        struct spoolss_DevmodeContainer devmode_ctr;
@@ -3221,19 +3504,23 @@ static bool api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid,
 
        ZERO_STRUCT(handle);
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_spoolss.syntax_id,
-                                       rpc_spoolss_dispatch, conn->server_info,
-                                       &cli);
+       status = rpc_pipe_open_interface(conn,
+                                        &ndr_table_spoolss.syntax_id,
+                                        conn->session_info,
+                                        &conn->sconn->client_id,
+                                        conn->sconn->msg_ctx,
+                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_WPrintQueueCtrl: could not connect to spoolss: %s\n",
                          nt_errstr(status)));
                errcode = W_ERROR_V(ntstatus_to_werror(status));
                goto out;
        }
+       b = cli->binding_handle;
 
        ZERO_STRUCT(devmode_ctr);
 
-       status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
+       status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
                                            QueueName,
                                            NULL,
                                            devmode_ctr,
@@ -3272,7 +3559,7 @@ static bool api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid,
        ZERO_STRUCT(info_ctr);
        ZERO_STRUCT(secdesc_ctr);
 
-       status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
+       status = dcerpc_spoolss_SetPrinter(b, mem_ctx,
                                           &handle,
                                           &info_ctr,
                                           &devmode_ctr,
@@ -3292,8 +3579,8 @@ static bool api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid,
 
  out:
 
-       if (cli && is_valid_policy_hnd(&handle)) {
-               rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
+       if (b && is_valid_policy_hnd(&handle)) {
+               dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
        }
 
        SSVAL(*rparam,0,errcode);
@@ -3306,8 +3593,8 @@ static bool api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid,
   set the property of a print job (undocumented?)
   ? function = 0xb -> set name of print job
   ? function = 0x6 -> move print job up/down
-  Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz> 
-  or   <WWsTP> <WB21BB16B10zWWzDDz> 
+  Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz>
+  or   <WWsTP> <WB21BB16B10zWWzDDz>
 ****************************************************************************/
 
 static int check_printjob_info(struct pack_desc* desc,
@@ -3333,7 +3620,8 @@ static int check_printjob_info(struct pack_desc* desc,
        return True;
 }
 
-static bool api_PrintJobInfo(connection_struct *conn, uint16 vuid,
+static bool api_PrintJobInfo(struct smbd_server_connection *sconn,
+                            connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -3354,6 +3642,7 @@ static bool api_PrintJobInfo(connection_struct *conn, uint16 vuid,
        WERROR werr;
        NTSTATUS status;
        struct rpc_pipe_client *cli = NULL;
+       struct dcerpc_binding_handle *b = NULL;
        struct policy_handle handle;
        struct spoolss_DevmodeContainer devmode_ctr;
        struct spoolss_JobInfoContainer ctr;
@@ -3397,19 +3686,23 @@ static bool api_PrintJobInfo(connection_struct *conn, uint16 vuid,
 
        ZERO_STRUCT(handle);
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_spoolss.syntax_id,
-                                       rpc_spoolss_dispatch, conn->server_info,
-                                       &cli);
+       status = rpc_pipe_open_interface(conn,
+                                        &ndr_table_spoolss.syntax_id,
+                                        conn->session_info,
+                                        &conn->sconn->client_id,
+                                        conn->sconn->msg_ctx,
+                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_PrintJobInfo: could not connect to spoolss: %s\n",
                          nt_errstr(status)));
                errcode = W_ERROR_V(ntstatus_to_werror(status));
                goto out;
        }
+       b = cli->binding_handle;
 
        ZERO_STRUCT(devmode_ctr);
 
-       status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
+       status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
                                            sharename,
                                            "RAW",
                                            devmode_ctr,
@@ -3454,7 +3747,7 @@ static bool api_PrintJobInfo(connection_struct *conn, uint16 vuid,
        ctr.level = 1;
        ctr.info.info1 = &info1;
 
-       status = rpccli_spoolss_SetJob(cli, mem_ctx,
+       status = dcerpc_spoolss_SetJob(b, mem_ctx,
                                       &handle,
                                       jobid,
                                       &ctr,
@@ -3472,8 +3765,8 @@ static bool api_PrintJobInfo(connection_struct *conn, uint16 vuid,
        errcode = NERR_Success;
  out:
 
-       if (cli && is_valid_policy_hnd(&handle)) {
-               rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
+       if (b && is_valid_policy_hnd(&handle)) {
+               dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
        }
 
        SSVALS(*rparam,0,errcode);
@@ -3487,7 +3780,8 @@ static bool api_PrintJobInfo(connection_struct *conn, uint16 vuid,
  Get info about the server.
 ****************************************************************************/
 
-static bool api_RNetServerGetInfo(connection_struct *conn,uint16 vuid,
+static bool api_RNetServerGetInfo(struct smbd_server_connection *sconn,
+                                 connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -3507,6 +3801,7 @@ static bool api_RNetServerGetInfo(connection_struct *conn,uint16 vuid,
        struct rpc_pipe_client *cli = NULL;
        union srvsvc_NetSrvInfo info;
        int errcode;
+       struct dcerpc_binding_handle *b;
 
        if (!str1 || !str2 || !p) {
                return False;
@@ -3569,8 +3864,10 @@ static bool api_RNetServerGetInfo(connection_struct *conn,uint16 vuid,
        p = *rdata;
        p2 = p + struct_len;
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_srvsvc.syntax_id,
-                                       rpc_srvsvc_dispatch, conn->server_info,
+       status = rpc_pipe_open_interface(mem_ctx, &ndr_table_srvsvc.syntax_id,
+                                       conn->session_info,
+                                       &conn->sconn->client_id,
+                                       conn->sconn->msg_ctx,
                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_RNetServerGetInfo: could not connect to srvsvc: %s\n",
@@ -3579,7 +3876,9 @@ static bool api_RNetServerGetInfo(connection_struct *conn,uint16 vuid,
                goto out;
        }
 
-       status = rpccli_srvsvc_NetSrvGetInfo(cli, mem_ctx,
+       b = cli->binding_handle;
+
+       status = dcerpc_srvsvc_NetSrvGetInfo(b, mem_ctx,
                                             NULL,
                                             101,
                                             &info,
@@ -3653,7 +3952,8 @@ static bool api_RNetServerGetInfo(connection_struct *conn,uint16 vuid,
  Get info about the server.
 ****************************************************************************/
 
-static bool api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid,
+static bool api_NetWkstaGetInfo(struct smbd_server_connection *sconn,
+                               connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -3711,7 +4011,7 @@ static bool api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid,
        p += 4;
 
        SIVAL(p,0,PTR_DIFF(p2,*rdata));
-       strlcpy(p2,conn->server_info->sanitized_username,PTR_DIFF(endp,p2));
+       strlcpy(p2,conn->session_info->sanitized_username,PTR_DIFF(endp,p2));
        p2 = skip_string(*rdata,*rdata_len,p2);
        if (!p2) {
                return False;
@@ -3758,9 +4058,9 @@ static bool api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid,
   get info about a user
 
     struct user_info_11 {
-        char                usri11_name[21];  0-20 
-        char                usri11_pad;       21 
-        char                *usri11_comment;  22-25 
+        char                usri11_name[21];  0-20
+        char                usri11_pad;       21
+        char                *usri11_comment;  22-25
         char            *usri11_usr_comment;  26-29
         unsigned short      usri11_priv;      30-31
         unsigned long       usri11_auth_flags; 32-35
@@ -3891,7 +4191,7 @@ There is no auxiliary data in the response.
 
   ****************************************************************************/
 
-#define usri11_name           0 
+#define usri11_name           0
 #define usri11_pad            21
 #define usri11_comment        22
 #define usri11_usr_comment    26
@@ -3914,24 +4214,14 @@ There is no auxiliary data in the response.
 #define usri11_code_page      84
 #define usri11_end            86
 
-#define USER_PRIV_GUEST 0
-#define USER_PRIV_USER 1
-#define USER_PRIV_ADMIN 2
-
-#define AF_OP_PRINT     0 
-#define AF_OP_COMM      1
-#define AF_OP_SERVER    2
-#define AF_OP_ACCOUNTS  3
-
-
-static bool api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
+static bool api_RNetUserGetInfo(struct smbd_server_connection *sconn,
+                               connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
                                char **rdata,char **rparam,
                                int *rdata_len,int *rparam_len)
 {
-       struct smbd_server_connection *sconn = smbd_server_conn;
        char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
        char *str2 = skip_string(param,tpscnt,str1);
        char *UserName = skip_string(param,tpscnt,str2);
@@ -3941,15 +4231,19 @@ static bool api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
        char *endp;
        const char *level_string;
 
-       /* get NIS home of a previously validated user - simeon */
-       /* With share level security vuid will always be zero.
-          Don't depend on vuser being non-null !!. JRA */
-       user_struct *vuser = get_valid_user_struct(sconn, vuid);
-       if(vuser != NULL) {
-               DEBUG(3,("  Username of UID %d is %s\n",
-                        (int)vuser->server_info->utok.uid,
-                        vuser->server_info->unix_name));
-       }
+       TALLOC_CTX *mem_ctx = talloc_tos();
+       NTSTATUS status, result;
+       struct rpc_pipe_client *cli = NULL;
+       struct policy_handle connect_handle, domain_handle, user_handle;
+       struct lsa_String domain_name;
+       struct dom_sid2 *domain_sid;
+       struct lsa_String names;
+       struct samr_Ids rids;
+       struct samr_Ids types;
+       int errcode = W_ERROR_V(WERR_USER_NOT_FOUND);
+       uint32_t rid;
+       union samr_UserInfo *info;
+       struct dcerpc_binding_handle *b = NULL;
 
        if (!str1 || !str2 || !UserName || !p) {
                return False;
@@ -3986,9 +4280,6 @@ static bool api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
                return False;
        }
 
-       SSVAL(*rparam,0,NERR_Success);
-       SSVAL(*rparam,2,0);             /* converter word */
-
        p = *rdata;
        endp = *rdata + *rdata_len;
        p2 = get_safe_ptr(*rdata,*rdata_len,p,usri11_end);
@@ -3996,6 +4287,138 @@ static bool api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
                return False;
        }
 
+       ZERO_STRUCT(connect_handle);
+       ZERO_STRUCT(domain_handle);
+       ZERO_STRUCT(user_handle);
+
+       status = rpc_pipe_open_interface(mem_ctx, &ndr_table_samr.syntax_id,
+                                       conn->session_info,
+                                       &conn->sconn->client_id,
+                                       conn->sconn->msg_ctx,
+                                       &cli);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("api_RNetUserGetInfo: could not connect to samr: %s\n",
+                         nt_errstr(status)));
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+
+       b = cli->binding_handle;
+
+       status = dcerpc_samr_Connect2(b, mem_ctx,
+                                     global_myname(),
+                                     SAMR_ACCESS_CONNECT_TO_SERVER |
+                                     SAMR_ACCESS_ENUM_DOMAINS |
+                                     SAMR_ACCESS_LOOKUP_DOMAIN,
+                                     &connect_handle,
+                                     &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
+
+       init_lsa_String(&domain_name, get_global_sam_name());
+
+       status = dcerpc_samr_LookupDomain(b, mem_ctx,
+                                         &connect_handle,
+                                         &domain_name,
+                                         &domain_sid,
+                                         &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
+
+       status = dcerpc_samr_OpenDomain(b, mem_ctx,
+                                       &connect_handle,
+                                       SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+                                       domain_sid,
+                                       &domain_handle,
+                                       &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
+
+       init_lsa_String(&names, UserName);
+
+       status = dcerpc_samr_LookupNames(b, mem_ctx,
+                                        &domain_handle,
+                                        1,
+                                        &names,
+                                        &rids,
+                                        &types,
+                                        &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
+
+       if (rids.count != 1) {
+               errcode = W_ERROR_V(WERR_NO_SUCH_USER);
+               goto out;
+       }
+       if (rids.count != types.count) {
+               errcode = W_ERROR_V(WERR_INVALID_PARAM);
+               goto out;
+       }
+       if (types.ids[0] != SID_NAME_USER) {
+               errcode = W_ERROR_V(WERR_INVALID_PARAM);
+               goto out;
+       }
+
+       rid = rids.ids[0];
+
+       status = dcerpc_samr_OpenUser(b, mem_ctx,
+                                     &domain_handle,
+                                     SAMR_USER_ACCESS_GET_LOCALE |
+                                     SAMR_USER_ACCESS_GET_LOGONINFO |
+                                     SAMR_USER_ACCESS_GET_ATTRIBUTES |
+                                     SAMR_USER_ACCESS_GET_GROUPS |
+                                     SAMR_USER_ACCESS_GET_GROUP_MEMBERSHIP |
+                                     SEC_STD_READ_CONTROL,
+                                     rid,
+                                     &user_handle,
+                                     &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
+
+       status = dcerpc_samr_QueryUserInfo2(b, mem_ctx,
+                                           &user_handle,
+                                           UserAllInformation,
+                                           &info,
+                                           &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!NT_STATUS_IS_OK(result)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(result));
+               goto out;
+       }
+
        memset(p,0,21);
        fstrcpy(p+usri11_name,UserName); /* 21 bytes - user name */
 
@@ -4021,9 +4444,7 @@ static bool api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
 
                /* EEK! the cifsrap.txt doesn't have this in!!!! */
                SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */
-               strlcpy(p2,((vuser != NULL)
-                           ? pdb_get_fullname(vuser->server_info->sam_account)
-                           : UserName),PTR_DIFF(endp,p2));
+               strlcpy(p2,info->info21.full_name.string,PTR_DIFF(endp,p2));
                p2 = skip_string(*rdata,*rdata_len,p2);
                if (!p2) {
                        return False;
@@ -4031,11 +4452,7 @@ static bool api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
        }
 
        if (uLevel == 11) {
-               const char *homedir = "";
-               if (vuser != NULL) {
-                       homedir = pdb_get_homedir(
-                               vuser->server_info->sam_account);
-               }
+               const char *homedir = info->info21.home_directory.string;
                /* modelled after NTAS 3.51 reply */
                SSVAL(p,usri11_priv,
                        (get_current_uid(conn) == sec_initial_uid())?
@@ -4095,8 +4512,7 @@ static bool api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
                        (get_current_uid(conn) == sec_initial_uid())?
                        USER_PRIV_ADMIN:USER_PRIV_USER);
                SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
-               strlcpy(p2, vuser ? pdb_get_homedir(
-                               vuser->server_info->sam_account) : "",
+               strlcpy(p2, info->info21.home_directory.string,
                        PTR_DIFF(endp,p2));
                p2 = skip_string(*rdata,*rdata_len,p2);
                if (!p2) {
@@ -4106,42 +4522,39 @@ static bool api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
                *p2++ = 0;
                SSVAL(p,52,0);          /* flags */
                SIVAL(p,54,PTR_DIFF(p2,*rdata));                /* script_path */
-               strlcpy(p2, vuser ? pdb_get_logon_script(
-                               vuser->server_info->sam_account) : "",
+               strlcpy(p2, info->info21.logon_script.string,
                        PTR_DIFF(endp,p2));
                p2 = skip_string(*rdata,*rdata_len,p2);
                if (!p2) {
                        return False;
                }
                if (uLevel == 2) {
-                       SIVAL(p,60,0);          /* auth_flags */
-                       SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
-                       strlcpy(p2,((vuser != NULL)
-                                   ? pdb_get_fullname(vuser->server_info->sam_account)
-                                   : UserName),PTR_DIFF(endp,p2));
+                       SIVAL(p,58,0);          /* auth_flags */
+                       SIVAL(p,62,PTR_DIFF(p2,*rdata)); /* full_name */
+                       strlcpy(p2,info->info21.full_name.string,PTR_DIFF(endp,p2));
                        p2 = skip_string(*rdata,*rdata_len,p2);
                        if (!p2) {
                                return False;
                        }
-                       SIVAL(p,68,0);          /* urs_comment */
-                       SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
+                       SIVAL(p,66,0);          /* urs_comment */
+                       SIVAL(p,70,PTR_DIFF(p2,*rdata)); /* parms */
                        strlcpy(p2,"",PTR_DIFF(endp,p2));
                        p2 = skip_string(*rdata,*rdata_len,p2);
                        if (!p2) {
                                return False;
                        }
-                       SIVAL(p,76,0);          /* workstations */
-                       SIVAL(p,80,0);          /* last_logon */
-                       SIVAL(p,84,0);          /* last_logoff */
-                       SIVALS(p,88,-1);                /* acct_expires */
-                       SIVALS(p,92,-1);                /* max_storage */
-                       SSVAL(p,96,168);        /* units_per_week */
-                       SIVAL(p,98,PTR_DIFF(p2,*rdata)); /* logon_hours */
+                       SIVAL(p,74,0);          /* workstations */
+                       SIVAL(p,78,0);          /* last_logon */
+                       SIVAL(p,82,0);          /* last_logoff */
+                       SIVALS(p,86,-1);                /* acct_expires */
+                       SIVALS(p,90,-1);                /* max_storage */
+                       SSVAL(p,94,168);        /* units_per_week */
+                       SIVAL(p,96,PTR_DIFF(p2,*rdata)); /* logon_hours */
                        memset(p2,-1,21);
                        p2 += 21;
-                       SSVALS(p,102,-1);       /* bad_pw_count */
-                       SSVALS(p,104,-1);       /* num_logons */
-                       SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
+                       SSVALS(p,100,-1);       /* bad_pw_count */
+                       SSVALS(p,102,-1);       /* num_logons */
+                       SIVAL(p,104,PTR_DIFF(p2,*rdata)); /* logon_server */
                        {
                                TALLOC_CTX *ctx = talloc_tos();
                                int space_rem = *rdata_len - (p2 - *rdata);
@@ -4171,26 +4584,41 @@ static bool api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
                        if (!p2) {
                                return False;
                        }
-                       SSVAL(p,110,49);        /* country_code */
-                       SSVAL(p,112,860);       /* code page */
+                       SSVAL(p,108,49);        /* country_code */
+                       SSVAL(p,110,860);       /* code page */
                }
        }
 
+       errcode = NERR_Success;
+
+ out:
        *rdata_len = PTR_DIFF(p2,*rdata);
 
+       if (b && is_valid_policy_hnd(&user_handle)) {
+               dcerpc_samr_Close(b, mem_ctx, &user_handle, &result);
+       }
+       if (b && is_valid_policy_hnd(&domain_handle)) {
+               dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
+       }
+       if (b && is_valid_policy_hnd(&connect_handle)) {
+               dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
+       }
+
+       SSVAL(*rparam,0,errcode);
+       SSVAL(*rparam,2,0);             /* converter word */
        SSVAL(*rparam,4,*rdata_len);    /* is this right?? */
 
        return(True);
 }
 
-static bool api_WWkstaUserLogon(connection_struct *conn,uint16 vuid,
+static bool api_WWkstaUserLogon(struct smbd_server_connection *sconn,
+                               connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
                                char **rdata,char **rparam,
                                int *rdata_len,int *rparam_len)
 {
-       struct smbd_server_connection *sconn = smbd_server_conn;
        char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
        char *str2 = skip_string(param,tpscnt,str1);
        char *p = skip_string(param,tpscnt,str2);
@@ -4207,8 +4635,8 @@ static bool api_WWkstaUserLogon(connection_struct *conn,uint16 vuid,
 
        if(vuser != NULL) {
                DEBUG(3,("  Username of UID %d is %s\n",
-                        (int)vuser->server_info->utok.uid,
-                        vuser->server_info->unix_name));
+                        (int)vuser->session_info->utok.uid,
+                        vuser->session_info->unix_name));
        }
 
        uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
@@ -4267,8 +4695,9 @@ static bool api_WWkstaUserLogon(connection_struct *conn,uint16 vuid,
                }
 
                PACKS(&desc,"z",lp_workgroup());/* domain */
-               PACKS(&desc,"z", vuser ? pdb_get_logon_script(
-                             vuser->server_info->sam_account) : ""); /* script path */
+               PACKS(&desc,"z", vuser ?
+                       vuser->session_info->info3->base.logon_script.string
+                       : ""); /* script path */
                PACKI(&desc,"D",0x00000000);            /* reserved */
        }
 
@@ -4291,7 +4720,8 @@ static bool api_WWkstaUserLogon(connection_struct *conn,uint16 vuid,
  api_WAccessGetUserPerms
 ****************************************************************************/
 
-static bool api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid,
+static bool api_WAccessGetUserPerms(struct smbd_server_connection *sconn,
+                                   connection_struct *conn,uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -4336,7 +4766,8 @@ static bool api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid,
   api_WPrintJobEnumerate
   ****************************************************************************/
 
-static bool api_WPrintJobGetInfo(connection_struct *conn, uint16 vuid,
+static bool api_WPrintJobGetInfo(struct smbd_server_connection *sconn,
+                                connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -4356,6 +4787,7 @@ static bool api_WPrintJobGetInfo(connection_struct *conn, uint16 vuid,
        WERROR werr;
        NTSTATUS status;
        struct rpc_pipe_client *cli = NULL;
+       struct dcerpc_binding_handle *b = NULL;
        struct policy_handle handle;
        struct spoolss_DevmodeContainer devmode_ctr;
        union spoolss_JobInfo info;
@@ -4385,19 +4817,23 @@ static bool api_WPrintJobGetInfo(connection_struct *conn, uint16 vuid,
 
        ZERO_STRUCT(handle);
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_spoolss.syntax_id,
-                                       rpc_spoolss_dispatch, conn->server_info,
-                                       &cli);
+       status = rpc_pipe_open_interface(conn,
+                                        &ndr_table_spoolss.syntax_id,
+                                        conn->session_info,
+                                        &conn->sconn->client_id,
+                                        conn->sconn->msg_ctx,
+                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_WPrintJobGetInfo: could not connect to spoolss: %s\n",
                          nt_errstr(status)));
                desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
                goto out;
        }
+       b = cli->binding_handle;
 
        ZERO_STRUCT(devmode_ctr);
 
-       status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
+       status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
                                            sharename,
                                            "RAW",
                                            devmode_ctr,
@@ -4448,8 +4884,8 @@ static bool api_WPrintJobGetInfo(connection_struct *conn, uint16 vuid,
                *rdata_len = 0;
        }
  out:
-       if (cli && is_valid_policy_hnd(&handle)) {
-               rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
+       if (b && is_valid_policy_hnd(&handle)) {
+               dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
        }
 
        *rparam_len = 6;
@@ -4468,7 +4904,8 @@ static bool api_WPrintJobGetInfo(connection_struct *conn, uint16 vuid,
        return True;
 }
 
-static bool api_WPrintJobEnumerate(connection_struct *conn, uint16 vuid,
+static bool api_WPrintJobEnumerate(struct smbd_server_connection *sconn,
+                                  connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -4487,9 +4924,10 @@ static bool api_WPrintJobEnumerate(connection_struct *conn, uint16 vuid,
        WERROR werr;
        NTSTATUS status;
        struct rpc_pipe_client *cli = NULL;
+       struct dcerpc_binding_handle *b = NULL;
        struct policy_handle handle;
        struct spoolss_DevmodeContainer devmode_ctr;
-       uint32_t count;
+       uint32_t count = 0;
        union spoolss_JobInfo *info;
 
        if (!str1 || !str2 || !p) {
@@ -4515,25 +4953,29 @@ static bool api_WPrintJobEnumerate(connection_struct *conn, uint16 vuid,
                return False;   /* defined only for uLevel 0,1,2 */
        }
 
-       if (!check_printjob_info(&desc,uLevel,str2)) { 
+       if (!check_printjob_info(&desc,uLevel,str2)) {
                return False;
        }
 
        ZERO_STRUCT(handle);
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_spoolss.syntax_id,
-                                       rpc_spoolss_dispatch, conn->server_info,
-                                       &cli);
+       status = rpc_pipe_open_interface(conn,
+                                        &ndr_table_spoolss.syntax_id,
+                                        conn->session_info,
+                                        &conn->sconn->client_id,
+                                        conn->sconn->msg_ctx,
+                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_WPrintJobEnumerate: could not connect to spoolss: %s\n",
                          nt_errstr(status)));
                desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
                goto out;
        }
+       b = cli->binding_handle;
 
        ZERO_STRUCT(devmode_ctr);
 
-       status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
+       status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
                                            name,
                                            NULL,
                                            devmode_ctr,
@@ -4581,8 +5023,8 @@ static bool api_WPrintJobEnumerate(connection_struct *conn, uint16 vuid,
                }
        }
  out:
-       if (cli && is_valid_policy_hnd(&handle)) {
-               rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
+       if (b && is_valid_policy_hnd(&handle)) {
+               dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
        }
 
        *rdata_len = desc.usedlen;
@@ -4625,7 +5067,7 @@ static int check_printdest_info(struct pack_desc* desc,
                        return False;
        }
        if (id == NULL || strcmp(desc->format,id) != 0) {
-               DEBUG(0,("check_printdest_info: invalid string %s\n", 
+               DEBUG(0,("check_printdest_info: invalid string %s\n",
                        id ? id : "<NULL>" ));
                return False;
        }
@@ -4668,7 +5110,8 @@ static void fill_printdest_info(struct spoolss_PrinterInfo2 *info2, int uLevel,
        }
 }
 
-static bool api_WPrintDestGetInfo(connection_struct *conn, uint16 vuid,
+static bool api_WPrintDestGetInfo(struct smbd_server_connection *sconn,
+                                 connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -4687,6 +5130,7 @@ static bool api_WPrintDestGetInfo(connection_struct *conn, uint16 vuid,
        WERROR werr;
        NTSTATUS status;
        struct rpc_pipe_client *cli = NULL;
+       struct dcerpc_binding_handle *b = NULL;
        struct policy_handle handle;
        struct spoolss_DevmodeContainer devmode_ctr;
        union spoolss_PrinterInfo info;
@@ -4715,19 +5159,23 @@ static bool api_WPrintDestGetInfo(connection_struct *conn, uint16 vuid,
 
        ZERO_STRUCT(handle);
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_spoolss.syntax_id,
-                                       rpc_spoolss_dispatch, conn->server_info,
-                                       &cli);
+       status = rpc_pipe_open_interface(conn,
+                                        &ndr_table_spoolss.syntax_id,
+                                        conn->session_info,
+                                        &conn->sconn->client_id,
+                                        conn->sconn->msg_ctx,
+                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_WPrintDestGetInfo: could not connect to spoolss: %s\n",
                          nt_errstr(status)));
                desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
                goto out;
        }
+       b = cli->binding_handle;
 
        ZERO_STRUCT(devmode_ctr);
 
-       status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
+       status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
                                            PrinterName,
                                            NULL,
                                            devmode_ctr,
@@ -4779,8 +5227,8 @@ static bool api_WPrintDestGetInfo(connection_struct *conn, uint16 vuid,
        }
 
  out:
-       if (cli && is_valid_policy_hnd(&handle)) {
-               rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
+       if (b && is_valid_policy_hnd(&handle)) {
+               dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
        }
 
        *rdata_len = desc.usedlen;
@@ -4800,7 +5248,8 @@ static bool api_WPrintDestGetInfo(connection_struct *conn, uint16 vuid,
        return True;
 }
 
-static bool api_WPrintDestEnum(connection_struct *conn, uint16 vuid,
+static bool api_WPrintDestEnum(struct smbd_server_connection *sconn,
+                              connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -4842,9 +5291,12 @@ static bool api_WPrintDestEnum(connection_struct *conn, uint16 vuid,
 
        queuecnt = 0;
 
-       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_spoolss.syntax_id,
-                                       rpc_spoolss_dispatch, conn->server_info,
-                                       &cli);
+       status = rpc_pipe_open_interface(conn,
+                                        &ndr_table_spoolss.syntax_id,
+                                        conn->session_info,
+                                        &conn->sconn->client_id,
+                                        conn->sconn->msg_ctx,
+                                        &cli);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("api_WPrintDestEnum: could not connect to spoolss: %s\n",
                          nt_errstr(status)));
@@ -4878,7 +5330,7 @@ static bool api_WPrintDestEnum(connection_struct *conn, uint16 vuid,
 
        desc.base = *rdata;
        desc.buflen = mdrcnt;
-       if (init_package(&desc,queuecnt,0)) {    
+       if (init_package(&desc,queuecnt,0)) {
                succnt = 0;
                n = 0;
                for (i = 0; i < count; i++) {
@@ -4907,7 +5359,8 @@ static bool api_WPrintDestEnum(connection_struct *conn, uint16 vuid,
        return True;
 }
 
-static bool api_WPrintDriverEnum(connection_struct *conn, uint16 vuid,
+static bool api_WPrintDriverEnum(struct smbd_server_connection *sconn,
+                                connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -4970,7 +5423,8 @@ static bool api_WPrintDriverEnum(connection_struct *conn, uint16 vuid,
        return True;
 }
 
-static bool api_WPrintQProcEnum(connection_struct *conn, uint16 vuid,
+static bool api_WPrintQProcEnum(struct smbd_server_connection *sconn,
+                               connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -5033,7 +5487,8 @@ static bool api_WPrintQProcEnum(connection_struct *conn, uint16 vuid,
        return True;
 }
 
-static bool api_WPrintPortEnum(connection_struct *conn, uint16 vuid,
+static bool api_WPrintPortEnum(struct smbd_server_connection *sconn,
+                              connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -5102,7 +5557,8 @@ static bool api_WPrintPortEnum(connection_struct *conn, uint16 vuid,
  List open sessions
  ****************************************************************************/
 
-static bool api_RNetSessionEnum(connection_struct *conn, uint16 vuid,
+static bool api_RNetSessionEnum(struct smbd_server_connection *sconn,
+                               connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt,int mprcnt,
@@ -5115,14 +5571,22 @@ static bool api_RNetSessionEnum(connection_struct *conn, uint16 vuid,
        char *p = skip_string(param,tpscnt,str2);
        int uLevel;
        struct pack_desc desc;
-       struct sessionid *session_list;
-       int i, num_sessions;
+       int i;
+
+       TALLOC_CTX *mem_ctx = talloc_tos();
+       WERROR werr;
+       NTSTATUS status;
+       struct rpc_pipe_client *cli = NULL;
+       struct dcerpc_binding_handle *b = NULL;
+       struct srvsvc_NetSessInfoCtr info_ctr;
+       uint32_t totalentries, resume_handle = 0;
+       uint32_t count = 0;
 
        if (!str1 || !str2 || !p) {
                return False;
        }
 
-       memset((char *)&desc,'\0',sizeof(desc));
+       ZERO_STRUCT(desc);
 
        uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
 
@@ -5138,27 +5602,72 @@ static bool api_RNetSessionEnum(connection_struct *conn, uint16 vuid,
                return False;
        }
 
-       num_sessions = list_sessions(talloc_tos(), &session_list);
+       status = rpc_pipe_open_interface(conn,
+                                        &ndr_table_srvsvc.syntax_id,
+                                        conn->session_info,
+                                        &conn->sconn->client_id,
+                                        conn->sconn->msg_ctx,
+                                        &cli);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("RNetSessionEnum: could not connect to srvsvc: %s\n",
+                         nt_errstr(status)));
+               desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       b = cli->binding_handle;
+
+       info_ctr.level = 1;
+       info_ctr.ctr.ctr1 = talloc_zero(talloc_tos(), struct srvsvc_NetSessCtr1);
+       if (info_ctr.ctr.ctr1 == NULL) {
+               desc.errcode = W_ERROR_V(WERR_NOMEM);
+               goto out;
+       }
+
+       status = dcerpc_srvsvc_NetSessEnum(b, mem_ctx,
+                                          cli->srv_name_slash,
+                                          NULL, /* client */
+                                          NULL, /* user */
+                                          &info_ctr,
+                                          (uint32_t)-1, /* max_buffer */
+                                          &totalentries,
+                                          &resume_handle,
+                                          &werr);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("RNetSessionEnum: dcerpc_srvsvc_NetSessEnum failed: %s\n",
+                         nt_errstr(status)));
+               desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
 
+       if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(0,("RNetSessionEnum: dcerpc_srvsvc_NetSessEnum failed: %s\n",
+                         win_errstr(werr)));
+               desc.errcode = W_ERROR_V(werr);
+               goto out;
+       }
+
+       count = info_ctr.ctr.ctr1->count;
+
+ out:
        if (mdrcnt > 0) {
                *rdata = smb_realloc_limit(*rdata,mdrcnt);
                if (!*rdata) {
                        return False;
                }
        }
-       memset((char *)&desc,'\0',sizeof(desc));
+
        desc.base = *rdata;
        desc.buflen = mdrcnt;
        desc.format = str2;
-       if (!init_package(&desc,num_sessions,0)) {
+       if (!init_package(&desc, count,0)) {
                return False;
        }
 
-       for(i=0; i<num_sessions; i++) {
-               PACKS(&desc, "z", session_list[i].remote_machine);
-               PACKS(&desc, "z", session_list[i].username);
+       for(i=0; i < count; i++) {
+               PACKS(&desc, "z", info_ctr.ctr.ctr1->array[i].client);
+               PACKS(&desc, "z", info_ctr.ctr.ctr1->array[i].user);
                PACKI(&desc, "W", 1); /* num conns */
-               PACKI(&desc, "W", 0); /* num opens */
+               PACKI(&desc, "W", info_ctr.ctr.ctr1->array[i].num_open);
                PACKI(&desc, "W", 1); /* num users */
                PACKI(&desc, "D", 0); /* session time */
                PACKI(&desc, "D", 0); /* idle time */
@@ -5175,7 +5684,7 @@ static bool api_RNetSessionEnum(connection_struct *conn, uint16 vuid,
        }
        SSVALS(*rparam,0,desc.errcode);
        SSVAL(*rparam,2,0); /* converter */
-       SSVAL(*rparam,4,num_sessions); /* count */
+       SSVAL(*rparam,4, count); /* count */
 
        DEBUG(4,("RNetSessionEnum: errorcode %d\n",desc.errcode));
 
@@ -5187,7 +5696,8 @@ static bool api_RNetSessionEnum(connection_struct *conn, uint16 vuid,
  The buffer was too small.
  ****************************************************************************/
 
-static bool api_TooSmall(connection_struct *conn,uint16 vuid, char *param, char *data,
+static bool api_TooSmall(struct smbd_server_connection *sconn,
+                        connection_struct *conn,uint16 vuid, char *param, char *data,
                         int mdrcnt, int mprcnt,
                         char **rdata, char **rparam,
                         int *rdata_len, int *rparam_len)
@@ -5211,7 +5721,8 @@ static bool api_TooSmall(connection_struct *conn,uint16 vuid, char *param, char
  The request is not supported.
  ****************************************************************************/
 
-static bool api_Unsupported(connection_struct *conn, uint16 vuid,
+static bool api_Unsupported(struct smbd_server_connection *sconn,
+                           connection_struct *conn, uint16 vuid,
                                char *param, int tpscnt,
                                char *data, int tdscnt,
                                int mdrcnt, int mprcnt,
@@ -5237,7 +5748,8 @@ static bool api_Unsupported(connection_struct *conn, uint16 vuid,
 static const struct {
        const char *name;
        int id;
-       bool (*fn)(connection_struct *, uint16,
+       bool (*fn)(struct smbd_server_connection *sconn,
+                  connection_struct *, uint16,
                        char *, int,
                        char *, int,
                        int,int,char **,char **,int *,int *);
@@ -5280,7 +5792,7 @@ static const struct {
        {NULL,          -1,     api_Unsupported}
        /*  The following RAP calls are not implemented by Samba:
 
-       RAP_WFileEnum2 - anon not OK 
+       RAP_WFileEnum2 - anon not OK
        */
 };
 
@@ -5295,7 +5807,6 @@ void api_reply(connection_struct *conn, uint16 vuid,
               int tdscnt, int tpscnt,
               int mdrcnt, int mprcnt)
 {
-       struct smbd_server_connection *sconn = smbd_server_conn;
        int api_command;
        char *rdata = NULL;
        char *rparam = NULL;
@@ -5344,9 +5855,9 @@ void api_reply(connection_struct *conn, uint16 vuid,
        /* Check whether this api call can be done anonymously */
 
        if (api_commands[i].auth_user && lp_restrict_anonymous()) {
-               user_struct *user = get_valid_user_struct(sconn, vuid);
+               user_struct *user = get_valid_user_struct(req->sconn, vuid);
 
-               if (!user || user->server_info->guest) {
+               if (!user || user->session_info->guest) {
                        reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                        return;
                }
@@ -5370,7 +5881,7 @@ void api_reply(connection_struct *conn, uint16 vuid,
                return;
        }
 
-       reply = api_commands[i].fn(conn,
+       reply = api_commands[i].fn(req->sconn, conn,
                                vuid,
                                params,tpscnt,  /* params + length */
                                data,tdscnt,    /* data + length */
@@ -5379,13 +5890,16 @@ void api_reply(connection_struct *conn, uint16 vuid,
 
 
        if (rdata_len > mdrcnt || rparam_len > mprcnt) {
-               reply = api_TooSmall(conn,vuid,params,data,mdrcnt,mprcnt,
+               reply = api_TooSmall(req->sconn,conn,vuid,params,data,
+                                    mdrcnt,mprcnt,
                                        &rdata,&rparam,&rdata_len,&rparam_len);
        }
 
        /* if we get False back then it's actually unsupported */
        if (!reply) {
-               reply = api_Unsupported(conn,vuid,params,tpscnt,data,tdscnt,mdrcnt,mprcnt,
+               reply = api_Unsupported(req->sconn,conn,vuid,params,tpscnt,
+                                       data,
+                                       tdscnt,mdrcnt,mprcnt,
                        &rdata,&rparam,&rdata_len,&rparam_len);
        }