libcli/security Provide a common, top level libcli/security/security.h
[kamenim/samba.git] / source3 / smbd / lanman.c
index affce70f40300df370cbc4e5e8b88f9b4e3147fc..e5527a581240dc4de021fc5a49bc8636a72d4506 100644 (file)
 #include "smbd/globals.h"
 #include "../librpc/gen_ndr/cli_samr.h"
 #include "../librpc/gen_ndr/cli_spoolss.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/rap.h"
 #include "../lib/util/binsearch.h"
+#include "../libcli/auth/libcli_auth.h"
+#include "rpc_client/init_lsa.h"
+#include "rpc_server/rpc_ncacn_np.h"
+#include "../libcli/security/security.h"
 
 #ifdef CHECK_TYPES
 #undef CHECK_TYPES
@@ -68,14 +75,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,7 +118,7 @@ static int CopyExpanded(connection_struct *conn,
                                conn->connectpath,
                                conn->server_info->utok.gid,
                                conn->server_info->sanitized_username,
-                               pdb_get_domain(conn->server_info->sam_account),
+                               conn->server_info->info3->base.domain.string,
                                buf);
        if (!buf) {
                *p_space_remaining = 0;
@@ -160,7 +169,7 @@ static int StrlenExpanded(connection_struct *conn, int snum, char *s)
                                conn->connectpath,
                                conn->server_info->utok.gid,
                                conn->server_info->sanitized_username,
-                               pdb_get_domain(conn->server_info->sam_account),
+                               conn->server_info->info3->base.domain.string,
                                buf);
        if (!buf) {
                return 0;
@@ -531,21 +540,6 @@ static int printq_spoolss_status(int v)
        return RAP_QUEUE_STATUS_ERROR;
 }
 
-static time_t spoolss_Time_to_time_t(const struct spoolss_Time *r)
-{
-       struct tm unixtime;
-
-       unixtime.tm_year        = r->year - 1900;
-       unixtime.tm_mon         = r->month - 1;
-       unixtime.tm_wday        = r->day_of_week;
-       unixtime.tm_mday        = r->day;
-       unixtime.tm_hour        = r->hour;
-       unixtime.tm_min         = r->minute;
-       unixtime.tm_sec         = r->second;
-
-       return mktime(&unixtime);
-}
-
 static void fill_spoolss_printjob_info(int uLevel,
                                       struct pack_desc *desc,
                                       struct spoolss_JobInfo2 *info2,
@@ -758,7 +752,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,
@@ -782,7 +777,7 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
        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) {
@@ -827,9 +822,17 @@ 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->server_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)));
@@ -841,9 +844,9 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
 
        status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
                                            QueueName,
-                                           NULL,
+                                           "RAW",
                                            devmode_ctr,
-                                           SEC_FLAG_MAXIMUM_ALLOWED,
+                                           PRINTER_ACCESS_USE,
                                            &handle,
                                            &werr);
        if (!NT_STATUS_IS_OK(status)) {
@@ -962,7 +965,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,
@@ -1018,9 +1022,12 @@ 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->server_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)));
@@ -1083,9 +1090,9 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
 
                status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
                                                    printername,
-                                                   NULL,
+                                                   "RAW",
                                                    devmode_ctr,
-                                                   SEC_FLAG_MAXIMUM_ALLOWED,
+                                                   PRINTER_ACCESS_USE,
                                                    &handle,
                                                    &werr);
                if (!NT_STATUS_IS_OK(status)) {
@@ -1423,7 +1430,8 @@ 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, 
@@ -1592,7 +1600,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,
@@ -1784,7 +1793,8 @@ 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, 
@@ -1974,7 +1984,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,
@@ -2037,7 +2048,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,
@@ -2144,7 +2156,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,
@@ -2158,12 +2171,17 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
        fstring sharename;
        fstring comment;
        char *pathname = NULL;
-       char *command, *cmdname;
        unsigned int offset;
-       int snum;
        int res = ERRunsup;
        size_t converted_size;
 
+       WERROR werr = WERR_OK;
+       TALLOC_CTX *mem_ctx = talloc_tos();
+       NTSTATUS status;
+       struct rpc_pipe_client *cli = NULL;
+       union srvsvc_NetShareInfo info;
+       struct srvsvc_NetShareInfo2 info2;
+
        if (!str1 || !str2 || !p) {
                return False;
        }
@@ -2184,11 +2202,6 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
                return False;
        }
        pull_ascii_fstring(sharename,data);
-       snum = find_service(sharename);
-       if (snum >= 0) { /* already exists */
-               res = ERRfilexists;
-               goto error_exit;
-       }
 
        if (mdrcnt < 28) {
                return False;
@@ -2202,7 +2215,7 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
        offset = IVAL(data, 16);
        if (offset >= mdrcnt) {
                res = ERRinvalidparam;
-               goto error_exit;
+               goto out;
        }
 
        /* Do we have a string ? */
@@ -2215,7 +2228,7 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
 
        if (offset >= mdrcnt) {
                res = ERRinvalidparam;
-               goto error_exit;
+               goto out;
        }
 
        /* Do we have a string ? */
@@ -2234,34 +2247,42 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
                return false;
        }
 
-       string_replace(sharename, '"', ' ');
-       string_replace(pathname, '"', ' ');
-       string_replace(comment, '"', ' ');
-
-       cmdname = lp_add_share_cmd();
-
-       if (!cmdname || *cmdname == '\0') {
-               return False;
+       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_srvsvc.syntax_id,
+                                       conn->server_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",
+                         nt_errstr(status)));
+               res = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
        }
 
-       if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
-                    lp_add_share_cmd(), get_dyn_CONFIGFILE(), sharename,
-                    pathname, comment) == -1) {
-               return false;
-       }
+       info2.name              = sharename;
+       info2.type              = STYPE_DISKTREE;
+       info2.comment           = comment;
+       info2.permissions       = 0;
+       info2.max_users         = 0;
+       info2.current_users     = 0;
+       info2.path              = pathname;
+       info2.password          = NULL;
 
-       DEBUG(10,("api_RNetShareAdd: Running [%s]\n", command ));
+       info.info2 = &info2;
 
-       if ((res = smbrun(command, NULL)) != 0) {
-               DEBUG(1,("api_RNetShareAdd: Running [%s] returned (%d)\n",
-                        command, res ));
-               SAFE_FREE(command);
-               res = ERRnoaccess;
-               goto error_exit;
-       } else {
-               SAFE_FREE(command);
-               message_send_all(smbd_messaging_context(),
-                                MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
+       status = rpccli_srvsvc_NetShareAdd(cli, mem_ctx,
+                                          cli->srv_name_slash,
+                                          2,
+                                          &info,
+                                          NULL,
+                                          &werr);
+       if (!NT_STATUS_IS_OK(status)) {
+               res = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!W_ERROR_IS_OK(werr)) {
+               res = W_ERROR_V(werr);
+               goto out;
        }
 
        *rparam_len = 6;
@@ -2276,7 +2297,7 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
 
        return True;
 
-  error_exit:
+  out:
 
        *rparam_len = 4;
        *rparam = smb_realloc_limit(*rparam,*rparam_len);
@@ -2293,7 +2314,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,
@@ -2334,8 +2356,9 @@ static bool api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
        }
 
        status = rpc_pipe_open_internal(
-               talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
-               conn->server_info, &samr_pipe);
+               talloc_tos(), &ndr_table_samr.syntax_id,
+               conn->server_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)));
@@ -2450,7 +2473,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,
@@ -2515,8 +2539,9 @@ static bool api_NetUserGetGroups(connection_struct *conn,uint16 vuid,
        endp = *rdata + *rdata_len;
 
        status = rpc_pipe_open_internal(
-               talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
-               conn->server_info, &samr_pipe);
+               talloc_tos(), &ndr_table_samr.syntax_id,
+               conn->server_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)));
@@ -2609,7 +2634,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,
@@ -2670,8 +2696,9 @@ static bool api_RNetUserEnum(connection_struct *conn, uint16 vuid,
        endp = *rdata + *rdata_len;
 
        status = rpc_pipe_open_internal(
-               talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
-               conn->server_info, &samr_pipe);
+               talloc_tos(), &ndr_table_samr.syntax_id,
+               conn->server_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)));
@@ -2767,7 +2794,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,
@@ -2825,7 +2853,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,
@@ -2836,6 +2865,21 @@ 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;
+       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;
 
        /* Skip 2 strings. */
        p = skip_string(param,tpscnt,np);
@@ -2868,6 +2912,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) {
@@ -2876,59 +2932,140 @@ 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_internal(mem_ctx, &ndr_table_samr.syntax_id,
+                                       conn->server_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);
+       status = rpccli_samr_Connect2(cli, mem_ctx,
+                                     global_myname(),
+                                     SAMR_ACCESS_CONNECT_TO_SERVER |
+                                     SAMR_ACCESS_ENUM_DOMAINS |
+                                     SAMR_ACCESS_LOOKUP_DOMAIN,
+                                     &connect_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
 
-               if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
+       init_lsa_String(&domain_name, get_global_sam_name());
 
-                       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();
+       status = rpccli_samr_LookupDomain(cli, mem_ctx,
+                                         &connect_handle,
+                                         &domain_name,
+                                         &domain_sid);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
 
-                       TALLOC_FREE(server_info);
-               }
-               data_blob_clear_free(&password);
+       status = rpccli_samr_OpenDomain(cli, mem_ctx,
+                                       &connect_handle,
+                                       SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+                                       domain_sid,
+                                       &domain_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               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.
-        */
+       init_lsa_String(&names, user);
 
-       if(SVAL(*rparam,0) != NERR_Success) {
-               struct samu *hnd = NULL;
+       status = rpccli_samr_LookupNames(cli, mem_ctx,
+                                        &domain_handle,
+                                        1,
+                                        &names,
+                                        &rids,
+                                        &types);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
 
-               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);
-               }
+       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 = rpccli_samr_OpenUser(cli, mem_ctx,
+                                     &domain_handle,
+                                     SAMR_USER_ACCESS_CHANGE_PASSWORD,
+                                     rid,
+                                     &user_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               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 = rpccli_samr_ChangePasswordUser(cli, 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 */
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+
+       errcode = NERR_Success;
+ out:
+
+       if (cli && is_valid_policy_hnd(&user_handle)) {
+               rpccli_samr_Close(cli, mem_ctx, &user_handle);
+       }
+       if (cli && is_valid_policy_hnd(&domain_handle)) {
+               rpccli_samr_Close(cli, mem_ctx, &domain_handle);
+       }
+       if (cli && is_valid_policy_hnd(&connect_handle)) {
+               rpccli_samr_Close(cli, mem_ctx, &connect_handle);
        }
 
        memset((char *)pass1,'\0',sizeof(fstring));
        memset((char *)pass2,'\0',sizeof(fstring));      
 
+       SSVAL(*rparam,0,errcode);
+       SSVAL(*rparam,2,0);             /* converter word */
        return(True);
 }
 
@@ -2936,17 +3073,27 @@ 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,
                                char **rdata,char **rparam,
                                int *rdata_len,int *rparam_len)
 {
-       struct smbd_server_connection *sconn = smbd_server_conn;
        fstring user;
        char *p = get_safe_str_ptr(param,tpscnt,param,2);
-       *rparam_len = 2;
+
+       TALLOC_CTX *mem_ctx = talloc_tos();
+       NTSTATUS status;
+       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;
+
+       *rparam_len = 4;
        *rparam = smb_realloc_limit(*rparam,*rparam_len);
        if (!*rparam) {
                return False;
@@ -2996,17 +3143,50 @@ static bool api_SamOEMChangePassword(connection_struct *conn,uint16 vuid,
 
        DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
 
-       /*
-        * Pass the user through the NT -> unix user mapping
-        * function.
-        */
+       if (tdscnt != 532) {
+               errcode = W_ERROR_V(WERR_INVALID_PARAM);
+               goto out;
+       }
+
+       bufsize = get_safe_SVAL(param,tpscnt,p,0,-1);
+       if (bufsize != 532) {
+               errcode = W_ERROR_V(WERR_INVALID_PARAM);
+               goto out;
+       }
 
-       (void)map_username(sconn, user);
+       memcpy(password.data, data, 516);
+       memcpy(hash.hash, data+516, 16);
 
-       if (NT_STATUS_IS_OK(pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL, NULL))) {
-               SSVAL(*rparam,0,NERR_Success);
+       status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+                                       conn->server_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",
+                         nt_errstr(status)));
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
        }
 
+       init_lsa_AsciiString(&server, global_myname());
+       init_lsa_AsciiString(&account, user);
+
+       status = rpccli_samr_OemChangePasswordUser2(cli, mem_ctx,
+                                                   &server,
+                                                   &account,
+                                                   &password,
+                                                   &hash);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+
+       errcode = NERR_Success;
+ out:
+       SSVAL(*rparam,0,errcode);
+       SSVAL(*rparam,2,0);             /* converter word */
+
        return(True);
 }
 
@@ -3015,7 +3195,8 @@ static bool api_SamOEMChangePassword(connection_struct *conn,uint16 vuid,
   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,
@@ -3064,9 +3245,12 @@ 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->server_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)));
@@ -3078,9 +3262,9 @@ static bool api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
 
        status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
                                            sharename,
-                                           NULL,
+                                           "RAW",
                                            devmode_ctr,
-                                           SEC_FLAG_MAXIMUM_ALLOWED,
+                                           JOB_ACCESS_ADMINISTER,
                                            &handle,
                                            &werr);
        if (!NT_STATUS_IS_OK(status)) {
@@ -3142,7 +3326,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,
@@ -3186,9 +3371,12 @@ 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->server_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)));
@@ -3298,7 +3486,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,
@@ -3362,9 +3551,12 @@ 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->server_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)));
@@ -3376,9 +3568,9 @@ static bool api_PrintJobInfo(connection_struct *conn, uint16 vuid,
 
        status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
                                            sharename,
-                                           NULL,
+                                           "RAW",
                                            devmode_ctr,
-                                           SEC_FLAG_MAXIMUM_ALLOWED,
+                                           PRINTER_ACCESS_USE,
                                            &handle,
                                            &werr);
        if (!NT_STATUS_IS_OK(status)) {
@@ -3452,7 +3644,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,
@@ -3466,6 +3659,13 @@ static bool api_RNetServerGetInfo(connection_struct *conn,uint16 vuid,
        char *p2;
        int struct_len;
 
+       NTSTATUS status;
+       WERROR werr;
+       TALLOC_CTX *mem_ctx = talloc_tos();
+       struct rpc_pipe_client *cli = NULL;
+       union srvsvc_NetSrvInfo info;
+       int errcode;
+
        if (!str1 || !str2 || !p) {
                return False;
        }
@@ -3526,64 +3726,57 @@ 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,
+                                       conn->server_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",
+                         nt_errstr(status)));
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+
+       status = rpccli_srvsvc_NetSrvGetInfo(cli, mem_ctx,
+                                            NULL,
+                                            101,
+                                            &info,
+                                            &werr);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+       if (!W_ERROR_IS_OK(werr)) {
+               errcode = W_ERROR_V(werr);
+               goto out;
+       }
+
+       if (info.info101 == NULL) {
+               errcode = W_ERROR_V(WERR_INVALID_PARAM);
+               goto out;
+       }
+
        if (uLevel != 20) {
-               srvstr_push(NULL, 0, p,global_myname(),16,
+               srvstr_push(NULL, 0, p, info.info101->server_name, 16,
                        STR_ASCII|STR_UPPER|STR_TERMINATE);
        }
        p += 16;
        if (uLevel > 0) {
-               struct srv_info_struct *servers=NULL;
-               int i,count;
-               char *comment = NULL;
-               TALLOC_CTX *ctx = talloc_tos();
-               uint32 servertype= lp_default_server_announce();
-
-               comment = talloc_strdup(ctx,lp_serverstring());
-               if (!comment) {
-                       return false;
-               }
-
-               if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
-                       for (i=0;i<count;i++) {
-                               if (strequal(servers[i].name,global_myname())) {
-                                       servertype = servers[i].type;
-                                       TALLOC_FREE(comment);
-                                       comment = talloc_strdup(ctx,
-                                                       servers[i].comment);
-                                       if (comment) {
-                                               return false;
-                                       }
-                               }
-                       }
-               }
-
-               SAFE_FREE(servers);
-
-               SCVAL(p,0,lp_major_announce_version());
-               SCVAL(p,1,lp_minor_announce_version());
-               SIVAL(p,2,servertype);
+               SCVAL(p,0,info.info101->version_major);
+               SCVAL(p,1,info.info101->version_minor);
+               SIVAL(p,2,info.info101->server_type);
 
                if (mdrcnt == struct_len) {
                        SIVAL(p,6,0);
                } else {
                        SIVAL(p,6,PTR_DIFF(p2,*rdata));
-                       comment = talloc_sub_advanced(
-                               ctx,
-                               lp_servicename(SNUM(conn)),
-                               conn->server_info->unix_name,
-                               conn->connectpath,
-                               conn->server_info->utok.gid,
-                               conn->server_info->sanitized_username,
-                               pdb_get_domain(conn->server_info->sam_account),
-                               comment);
-                       if (comment) {
-                               return false;
-                       }
                        if (mdrcnt - struct_len <= 0) {
                                return false;
                        }
                        push_ascii(p2,
-                               comment,
+                               info.info101->comment,
                                MIN(mdrcnt - struct_len,
                                        MAX_SERVER_STRING_LENGTH),
                                STR_TERMINATE);
@@ -3598,6 +3791,10 @@ static bool api_RNetServerGetInfo(connection_struct *conn,uint16 vuid,
                return False;           /* not yet implemented */
        }
 
+       errcode = NERR_Success;
+
+ out:
+
        *rdata_len = PTR_DIFF(p2,*rdata);
 
        *rparam_len = 6;
@@ -3605,7 +3802,7 @@ static bool api_RNetServerGetInfo(connection_struct *conn,uint16 vuid,
        if (!*rparam) {
                return False;
        }
-       SSVAL(*rparam,0,NERR_Success);
+       SSVAL(*rparam,0,errcode);
        SSVAL(*rparam,2,0);             /* converter word */
        SSVAL(*rparam,4,*rdata_len);
 
@@ -3616,7 +3813,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,
@@ -3877,24 +4075,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);
@@ -3904,15 +4092,18 @@ 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;
+       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;
 
        if (!str1 || !str2 || !UserName || !p) {
                return False;
@@ -3949,9 +4140,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);
@@ -3959,6 +4147,106 @@ 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_internal(mem_ctx, &ndr_table_samr.syntax_id,
+                                       conn->server_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;
+       }
+
+       status = rpccli_samr_Connect2(cli, mem_ctx,
+                                     global_myname(),
+                                     SAMR_ACCESS_CONNECT_TO_SERVER |
+                                     SAMR_ACCESS_ENUM_DOMAINS |
+                                     SAMR_ACCESS_LOOKUP_DOMAIN,
+                                     &connect_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+
+       init_lsa_String(&domain_name, get_global_sam_name());
+
+       status = rpccli_samr_LookupDomain(cli, mem_ctx,
+                                         &connect_handle,
+                                         &domain_name,
+                                         &domain_sid);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+
+       status = rpccli_samr_OpenDomain(cli, mem_ctx,
+                                       &connect_handle,
+                                       SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+                                       domain_sid,
+                                       &domain_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+
+       init_lsa_String(&names, UserName);
+
+       status = rpccli_samr_LookupNames(cli, mem_ctx,
+                                        &domain_handle,
+                                        1,
+                                        &names,
+                                        &rids,
+                                        &types);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               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 = rpccli_samr_OpenUser(cli, 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);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+
+       status = rpccli_samr_QueryUserInfo2(cli, mem_ctx,
+                                           &user_handle,
+                                           UserAllInformation,
+                                           &info);
+       if (!NT_STATUS_IS_OK(status)) {
+               errcode = W_ERROR_V(ntstatus_to_werror(status));
+               goto out;
+       }
+
        memset(p,0,21);
        fstrcpy(p+usri11_name,UserName); /* 21 bytes - user name */
 
@@ -3984,9 +4272,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;
@@ -3994,11 +4280,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())?
@@ -4058,8 +4340,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) {
@@ -4069,42 +4350,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);
@@ -4134,26 +4412,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 (cli && is_valid_policy_hnd(&user_handle)) {
+               rpccli_samr_Close(cli, mem_ctx, &user_handle);
+       }
+       if (cli && is_valid_policy_hnd(&domain_handle)) {
+               rpccli_samr_Close(cli, mem_ctx, &domain_handle);
+       }
+       if (cli && is_valid_policy_hnd(&connect_handle)) {
+               rpccli_samr_Close(cli, mem_ctx, &connect_handle);
+       }
+
+       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);
@@ -4230,8 +4523,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->server_info->info3->base.logon_script.string
+                       : ""); /* script path */
                PACKI(&desc,"D",0x00000000);            /* reserved */
        }
 
@@ -4254,7 +4548,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,
@@ -4299,7 +4594,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,
@@ -4348,9 +4644,12 @@ 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->server_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)));
@@ -4362,9 +4661,9 @@ static bool api_WPrintJobGetInfo(connection_struct *conn, uint16 vuid,
 
        status = rpccli_spoolss_OpenPrinter(cli, mem_ctx,
                                            sharename,
-                                           NULL,
+                                           "RAW",
                                            devmode_ctr,
-                                           SEC_FLAG_MAXIMUM_ALLOWED,
+                                           PRINTER_ACCESS_USE,
                                            &handle,
                                            &werr);
        if (!NT_STATUS_IS_OK(status)) {
@@ -4431,7 +4730,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,
@@ -4452,7 +4752,7 @@ static bool api_WPrintJobEnumerate(connection_struct *conn, uint16 vuid,
        struct rpc_pipe_client *cli = 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) {
@@ -4484,9 +4784,12 @@ static bool api_WPrintJobEnumerate(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->server_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)));
@@ -4631,7 +4934,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,
@@ -4678,9 +4982,12 @@ 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->server_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)));
@@ -4763,7 +5070,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,
@@ -4805,9 +5113,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->server_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)));
@@ -4870,7 +5181,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,
@@ -4933,7 +5245,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,
@@ -4996,7 +5309,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,
@@ -5065,7 +5379,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,
@@ -5150,7 +5465,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)
@@ -5174,7 +5490,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,
@@ -5200,7 +5517,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 *);
@@ -5258,7 +5576,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;
@@ -5307,7 +5624,7 @@ 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) {
                        reply_nterror(req, NT_STATUS_ACCESS_DENIED);
@@ -5333,7 +5650,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 */
@@ -5342,13 +5659,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);
        }