Merge commit 'origin/master' into libcli-auth-merge-without-netlogond
authorAndrew Bartlett <abartlet@samba.org>
Mon, 20 Apr 2009 14:53:02 +0000 (16:53 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 20 Apr 2009 14:53:02 +0000 (16:53 +0200)
1  2 
source3/include/proto.h
source3/libnet/libnet_join.c
source3/libsmb/cliconnect.c
source3/rpc_server/srv_samr_nt.c
source3/utils/net_rpc.c
source3/utils/net_rpc_join.c
source4/torture/rpc/samr.c

diff --combined source3/include/proto.h
index 4cb908b66546a6090e705ff71b869878b7eee6a3,fa60e6de09524800c36e2cb2f6d74b078da0795e..c40d9c680c41479f7dbd09ca752b3ce1d5b0eb79
@@@ -1782,23 -1782,6 +1782,23 @@@ bool create_local_private_krb5_conf_for
                                                const char *sitename,
                                                struct sockaddr_storage *pss);
  
 +
 +/* The following definitions come from libsmb/credentials.c  */
 +
 +char *credstr(const unsigned char *cred);
 +void creds_server_init(uint32 neg_flags,
 +                      struct dcinfo *dc,
 +                      struct netr_Credential *clnt_chal,
 +                      struct netr_Credential *srv_chal,
 +                      const unsigned char mach_pw[16],
 +                      struct netr_Credential *init_chal_out);
 +bool netlogon_creds_server_check(const struct dcinfo *dc,
 +                               const struct netr_Credential *rcv_cli_chal_in);
 +bool netlogon_creds_server_step(struct dcinfo *dc,
 +                              const struct netr_Authenticator *received_cred,
 +                              struct netr_Authenticator *cred_out);
 +void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw);
 +
  /* The following definitions come from libads/kerberos_keytab.c  */
  
  int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc);
@@@ -2950,6 -2933,31 +2950,6 @@@ void delete_negative_conn_cache(const c
  void flush_negative_conn_cache( void );
  void flush_negative_conn_cache_for_domain(const char *domain);
  
 -/* The following definitions come from libsmb/credentials.c  */
 -
 -char *credstr(const unsigned char *cred);
 -void creds_server_init(uint32 neg_flags,
 -                      struct dcinfo *dc,
 -                      struct netr_Credential *clnt_chal,
 -                      struct netr_Credential *srv_chal,
 -                      const unsigned char mach_pw[16],
 -                      struct netr_Credential *init_chal_out);
 -bool netlogon_creds_server_check(const struct dcinfo *dc,
 -                               const struct netr_Credential *rcv_cli_chal_in);
 -bool netlogon_creds_server_step(struct dcinfo *dc,
 -                              const struct netr_Authenticator *received_cred,
 -                              struct netr_Authenticator *cred_out);
 -void creds_client_init(uint32 neg_flags,
 -                      struct dcinfo *dc,
 -                      struct netr_Credential *clnt_chal,
 -                      struct netr_Credential *srv_chal,
 -                      const unsigned char mach_pw[16],
 -                      struct netr_Credential *init_chal_out);
 -bool netlogon_creds_client_check(const struct dcinfo *dc,
 -                               const struct netr_Credential *rcv_srv_chal_in);
 -void netlogon_creds_client_step(struct dcinfo *dc,
 -                              struct netr_Authenticator *next_cred_out);
 -
  /* The following definitions come from ../librpc/rpc/dcerpc_error.c  */
  
  const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code);
@@@ -3101,6 -3109,21 +3101,6 @@@ const char *get_nt_error_c_code(NTSTATU
  NTSTATUS nt_status_string_to_code(const char *nt_status_str);
  NTSTATUS nt_status_squash(NTSTATUS nt_status);
  
 -/* The following definitions come from libsmb/ntlm_check.c  */
 -
 -NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
 -                           const DATA_BLOB *challenge,
 -                           const DATA_BLOB *lm_response,
 -                           const DATA_BLOB *nt_response,
 -                           const DATA_BLOB *lm_interactive_pwd,
 -                           const DATA_BLOB *nt_interactive_pwd,
 -                           const char *username, 
 -                           const char *client_username, 
 -                           const char *client_domain,
 -                           const uint8 *lm_pw, const uint8 *nt_pw, 
 -                           DATA_BLOB *user_sess_key, 
 -                           DATA_BLOB *lm_sess_key);
 -
  /* The following definitions come from libsmb/ntlmssp.c  */
  
  void debug_ntlmssp_flags(uint32 neg_flags);
@@@ -3122,6 -3145,13 +3122,6 @@@ DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_S
  NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state);
  NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state);
  
 -/* The following definitions come from libsmb/ntlmssp_parse.c  */
 -
 -bool msrpc_gen(DATA_BLOB *blob,
 -             const char *format, ...);
 -bool msrpc_parse(const DATA_BLOB *blob,
 -               const char *format, ...);
 -
  /* The following definitions come from libsmb/ntlmssp_sign.c  */
  
  NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state,
@@@ -3205,6 -3235,84 +3205,6 @@@ void srv_set_signing(struct smbd_server
                     const DATA_BLOB user_session_key,
                     const DATA_BLOB response);
  
 -/* The following definitions come from libsmb/smbdes.c  */
 -
 -void des_crypt56(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw);
 -void E_P16(const unsigned char *p14,unsigned char *p16);
 -void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24);
 -void D_P16(const unsigned char *p14, const unsigned char *in, unsigned char *out);
 -void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *out);
 -void des_crypt128(unsigned char out[8], const unsigned char in[8], const unsigned char key[16]);
 -void des_crypt64(unsigned char out[8], const unsigned char in[8], const unsigned char key[8]);
 -void des_crypt112(unsigned char out[8], const unsigned char in[8], const unsigned char key[14], int forw);
 -void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw);
 -void des_crypt112_16(unsigned char out[16], unsigned char in[16], const unsigned char key[14], int forw);
 -void SamOEMhash( unsigned char *data, const unsigned char key[16], size_t len);
 -void SamOEMhashBlob( unsigned char *data, size_t len, DATA_BLOB *key);
 -void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw);
 -
 -/* The following definitions come from libsmb/smbencrypt.c  */
 -
 -void SMBencrypt_hash(const uchar lm_hash[16], const uchar *c8, uchar p24[24]);
 -bool SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]);
 -void E_md4hash(const char *passwd, uchar p16[16]);
 -void E_md5hash(const uchar salt[16], const uchar nthash[16], uchar hash_out[16]);
 -bool E_deshash(const char *passwd, uchar p16[16]);
 -void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]);
 -bool ntv2_owf_gen(const uchar owf[16],
 -                const char *user_in, const char *domain_in,
 -                bool upper_case_domain, /* Transform the domain into UPPER case */
 -                uchar kr_buf[16]);
 -void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]);
 -void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p24[24]);
 -void SMBNTencrypt_hash(const uchar nt_hash[16], uchar *c8, uchar *p24);
 -void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24);
 -void SMBOWFencrypt_ntv2(const uchar kr[16],
 -                      const DATA_BLOB *srv_chal,
 -                      const DATA_BLOB *cli_chal,
 -                      uchar resp_buf[16]);
 -void SMBsesskeygen_ntv2(const uchar kr[16],
 -                      const uchar * nt_resp, uint8 sess_key[16]);
 -void SMBsesskeygen_ntv1(const uchar kr[16],
 -                      const uchar * nt_resp, uint8 sess_key[16]);
 -void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16],
 -                      const uchar lm_resp[24], /* only uses 8 */ 
 -                      uint8 sess_key[16]);
 -DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, 
 -                                   const char *domain);
 -bool SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uchar nt_hash[16], 
 -                    const DATA_BLOB *server_chal, 
 -                    const DATA_BLOB *names_blob,
 -                    DATA_BLOB *lm_response, DATA_BLOB *nt_response, 
 -                    DATA_BLOB *user_session_key) ;
 -bool SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, 
 -                    const DATA_BLOB *server_chal, 
 -                    const DATA_BLOB *names_blob,
 -                    DATA_BLOB *lm_response, DATA_BLOB *nt_response, 
 -                    DATA_BLOB *user_session_key) ;
 -bool encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags);
 -bool decode_pw_buffer(TALLOC_CTX *ctx,
 -                      uint8 in_buffer[516],
 -                      char **pp_new_pwrd,
 -                      uint32 *new_pw_len,
 -                      int string_flags);
 -void encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], const DATA_BLOB *psession_key);
 -void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, int forward);
 -char *decrypt_trustdom_secret(uint8_t nt_hash[16], DATA_BLOB *data_in);
 -void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx,
 -                                      const char *pwd,
 -                                      DATA_BLOB *session_key,
 -                                      struct wkssvc_PasswordBuffer **pwd_buf);
 -WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx,
 -                                        struct wkssvc_PasswordBuffer *pwd_buf,
 -                                        DATA_BLOB *session_key,
 -                                        char **pwd);
 -DATA_BLOB decrypt_drsuapi_blob(TALLOC_CTX *mem_ctx,
 -                             const DATA_BLOB *session_key,
 -                             bool rcrypt,
 -                             uint32_t rid,
 -                             const DATA_BLOB *buffer);
 -
  /* The following definitions come from libsmb/smberr.c  */
  
  const char *smb_dos_err_name(uint8 e_class, uint16 num);
@@@ -4636,11 -4744,11 +4636,11 @@@ bool secrets_store_afs_keyfile(const ch
  bool secrets_fetch_afs_key(const char *cell, struct afs_key *result);
  void secrets_fetch_ipc_userpass(char **username, char **domain, char **password);
  bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
 -                              const char *remote_machine,
 -                              const struct dcinfo *pdc);
 +                                       const char *remote_machine,
 +                                       const struct dcinfo *pdc);
  bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
 -                              const char *remote_machine,
 -                              struct dcinfo **ppdc);
 +                                         const char *remote_machine,
 +                                         struct dcinfo **ppdc);
  bool secrets_store_generic(const char *owner, const char *key, const char *secret);
  char *secrets_fetch_generic(const char *owner, const char *key);
  bool secrets_store_local_schannel_key(uint8_t schannel_key[16]);
@@@ -5244,7 -5352,7 +5244,7 @@@ NTSTATUS cli_rpc_pipe_open_schannel_wit
                                             const struct ndr_syntax_id *interface,
                                             enum pipe_auth_level auth_level,
                                             const char *domain,
 -                                           const struct dcinfo *pdc,
 +                                           struct netlogon_creds_CredentialState **pdc,
                                             struct rpc_pipe_client **presult);
  NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
                                                 const struct ndr_syntax_id *interface,
@@@ -5767,14 -5875,33 +5767,33 @@@ NTSTATUS evlog_convert_tdb_to_evt(TALLO
  
  /* The following definitions come from rpc_server/srv_lsa_hnd.c  */
  
+ size_t num_pipe_handles(struct handle_list *list);
  bool init_pipe_handle_list(pipes_struct *p,
                           const struct ndr_syntax_id *syntax);
  bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_ptr);
- bool find_policy_by_hnd(pipes_struct *p, struct policy_handle *hnd, void **data_p);
+ bool find_policy_by_hnd(pipes_struct *p, const struct policy_handle *hnd,
+                       void **data_p);
  bool close_policy_hnd(pipes_struct *p, struct policy_handle *hnd);
  void close_policy_by_pipe(pipes_struct *p);
  bool pipe_access_check(pipes_struct *p);
  
+ void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
+                           uint32_t access_granted, size_t data_size,
+                           const char *type, NTSTATUS *pstatus);
+ #define policy_handle_create(_p, _hnd, _access, _type, _pstatus) \
+       (_type *)_policy_handle_create((_p), (_hnd), (_access), sizeof(_type), #_type, \
+                                      (_pstatus))
+ void *_policy_handle_find(struct pipes_struct *p,
+                         const struct policy_handle *hnd,
+                         uint32_t access_required, uint32_t *paccess_granted,
+                         const char *name, const char *location,
+                         NTSTATUS *pstatus);
+ #define policy_handle_find(_p, _hnd, _access_required, _access_granted, _type, _pstatus) \
+       (_type *)_policy_handle_find((_p), (_hnd), (_access_required), \
+                                    (_access_granted), #_type, __location__, (_pstatus))
  /* The following definitions come from rpc_server/srv_pipe.c  */
  
  bool create_next_pdu(pipes_struct *p);
@@@ -6446,6 -6573,11 +6465,11 @@@ NTSTATUS notify_add(struct notify_conte
                    void (*callback)(void *, const struct notify_event *), 
                    void *private_data);
  NTSTATUS notify_remove(struct notify_context *notify, void *private_data);
+ NTSTATUS notify_remove_onelevel(struct notify_context *notify,
+                               const struct file_id *fid,
+                               void *private_data);
+ void notify_onelevel(struct notify_context *notify, uint32_t action,
+                    uint32_t filter, struct file_id fid, const char *name);
  void notify_trigger(struct notify_context *notify,
                    uint32_t action, uint32_t filter, const char *path);
  
index 8e75d36fe33b9b4b31e1fbb8669474e4c0289111,6b0604bb9fdf805b67b45596403b9e220b72353e..894f5cba3299fb5d3213a77979229f6a6d6be729
@@@ -20,7 -20,6 +20,7 @@@
  
  #include "includes.h"
  #include "libnet/libnet.h"
 +#include "libcli/auth/libcli_auth.h"
  
  /****************************************************************
  ****************************************************************/
@@@ -786,7 -785,7 +786,7 @@@ static NTSTATUS libnet_join_joindomain_
        status = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
                                      pipe_hnd->desthost,
                                      SAMR_ACCESS_ENUM_DOMAINS
-                                     | SAMR_ACCESS_OPEN_DOMAIN,
+                                     | SAMR_ACCESS_LOOKUP_DOMAIN,
                                      &sam_pol);
        if (!NT_STATUS_IS_OK(status)) {
                goto done;
@@@ -1072,7 -1071,7 +1072,7 @@@ NTSTATUS libnet_join_ok(const char *net
  
        status = cli_rpc_pipe_open_schannel_with_key(
                cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
 -              netbios_domain_name, netlogon_pipe->dc, &pipe_hnd);
 +              netbios_domain_name, &netlogon_pipe->dc, &pipe_hnd);
  
        cli_shutdown(cli);
  
index 143bdf70197587d2e2653e5f40d1dabdb94e4797,0ff9f253ef7725f2f6498750d7861614c15821ce..ffe2960967b040436ec336b53b6909419760af90
@@@ -19,7 -19,6 +19,7 @@@
  */
  
  #include "includes.h"
 +#include "../libcli/auth/libcli_auth.h"
  
  static const struct {
        int prot;
@@@ -434,11 -433,11 +434,11 @@@ static NTSTATUS cli_session_setup_nt1(s
                           the server's domain at this point.  The 'server name' is also
                           dodgy... 
                        */
 -                      names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup);
 +                      names_blob = NTLMv2_generate_names_blob(NULL, cli->called.name, workgroup);
  
 -                      if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal, 
 +                      if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass, &server_chal, 
                                              &names_blob,
 -                                            &lm_response, &nt_response, &session_key)) {
 +                                            &lm_response, &nt_response, NULL, &session_key)) {
                                data_blob_free(&names_blob);
                                data_blob_free(&server_chal);
                                return NT_STATUS_ACCESS_DENIED;
                        E_deshash(pass, session_key.data);
                        memset(&session_key.data[8], '\0', 8);
  #else
 -                      SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
 +                      SMBsesskeygen_ntv1(nt_hash, session_key.data);
  #endif
                }
                cli_temp_set_signing(cli);
@@@ -1212,7 -1211,7 +1212,7 @@@ bool cli_ulogoff(struct cli_state *cli
                return False;
        }
  
-         cli->cnum = -1;
+         cli->vuid = -1;
          return True;
  }
  
index 187c721dfb2d12972215a4f5990c2464e53b1668,cc25dbb0c09964e8297d6679cae85d041315c980..b54ed717a304be54ef0b4da6b480a6e60eea2173
@@@ -32,7 -32,6 +32,7 @@@
   */
  
  #include "includes.h"
 +#include "../libcli/auth/libcli_auth.h"
  
  #undef DBGC_CLASS
  #define DBGC_CLASS DBGC_RPC_SRV
  #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
  #define MAX_SAM_ENTRIES_W95 50
  
+ struct samr_connect_info {
+       uint8_t dummy;
+ };
+ struct samr_domain_info {
+       struct dom_sid sid;
+       struct disp_info *disp_info;
+ };
  typedef struct disp_info {
        DOM_SID sid; /* identify which domain this is. */
-       bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
        struct pdb_search *users; /* querydispinfo 1 and 4 */
        struct pdb_search *machines; /* querydispinfo 2 */
        struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
@@@ -70,7 -77,6 +78,6 @@@
  struct samr_info {
        /* for use by the \PIPE\samr policy */
        DOM_SID sid;
-       bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
        uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
        uint32 acc_granted;
        DISP_INFO *disp_info;
@@@ -298,7 -304,7 +305,7 @@@ static void map_max_allowed_access(cons
   Fetch or create a dispinfo struct.
  ********************************************************************/
  
- static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
+ static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
  {
        /*
         * We do a static cache for DISP_INFO's here. Explanation can be found
@@@ -377,26 -383,20 +384,20 @@@ static struct samr_info *get_samr_info_
                                              DOM_SID *psid)
  {
        struct samr_info *info;
-       fstring sid_str;
  
-       if (psid) {
-               sid_to_fstring(sid_str, psid);
-       } else {
-               fstrcpy(sid_str,"(NULL)");
-       }
-       if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL) {
+       info = talloc_zero(mem_ctx, struct samr_info);
+       if (info == NULL) {
                return NULL;
        }
        talloc_set_destructor(info, samr_info_destructor);
  
-       DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
+       DEBUG(10, ("get_samr_info_by_sid: created new info for sid %s\n",
+                  sid_string_dbg(psid)));
        if (psid) {
                sid_copy( &info->sid, psid);
-               info->builtin_domain = sid_check_is_builtin(psid);
        } else {
                DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
-               info->builtin_domain = False;
        }
  
        info->disp_info = get_samr_dispinfo_by_sid(psid);
@@@ -481,8 -481,10 +482,10 @@@ static void set_disp_info_cache_timeout
   We must also remove the timeout handler.
   ********************************************************************/
  
- static void force_flush_samr_cache(DISP_INFO *disp_info)
+ static void force_flush_samr_cache(const struct dom_sid *sid)
  {
+       struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
        if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
                return;
        }
@@@ -512,7 -514,7 +515,7 @@@ static uint32 count_sam_users(struct di
  {
        struct samr_displayentry *entry;
  
-       if (info->builtin_domain) {
+       if (sid_check_is_builtin(&info->sid)) {
                /* No users in builtin. */
                return 0;
        }
@@@ -536,7 -538,7 +539,7 @@@ static uint32 count_sam_groups(struct d
  {
        struct samr_displayentry *entry;
  
-       if (info->builtin_domain) {
+       if (sid_check_is_builtin(&info->sid)) {
                /* No groups in builtin. */
                return 0;
        }
@@@ -597,7 -599,8 +600,8 @@@ NTSTATUS _samr_Close(pipes_struct *p, s
  NTSTATUS _samr_OpenDomain(pipes_struct *p,
                          struct samr_OpenDomain *r)
  {
-       struct    samr_info *info;
+       struct samr_connect_info *cinfo;
+       struct samr_domain_info *dinfo;
        SEC_DESC *psd = NULL;
        uint32    acc_granted;
        uint32    des_access = r->in.access_mask;
  
        /* find the connection policy handle. */
  
-       if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
-               return NT_STATUS_INVALID_HANDLE;
-       status = access_check_samr_function(info->acc_granted,
-                                           SAMR_ACCESS_OPEN_DOMAIN,
-                                           "_samr_OpenDomain" );
-       if ( !NT_STATUS_IS_OK(status) )
+       cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
+                                  struct samr_connect_info, &status);
+       if (!NT_STATUS_IS_OK(status)) {
                return status;
+       }
  
        /*check if access can be granted as requested by client. */
        map_max_allowed_access(p->server_info->ptok, &des_access);
                return NT_STATUS_NO_SUCH_DOMAIN;
        }
  
-       /* associate the domain SID with the (unique) handle. */
-       if ((info = get_samr_info_by_sid(p->mem_ctx, r->in.sid))==NULL)
-               return NT_STATUS_NO_MEMORY;
-       info->acc_granted = acc_granted;
-       /* get a (unique) handle.  open a policy on it. */
-       if (!create_policy_hnd(p, r->out.domain_handle, info))
-               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
+                                    struct samr_domain_info, &status);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       dinfo->sid = *r->in.sid;
+       dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
  
        DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
  
@@@ -964,7 -962,7 +963,7 @@@ NTSTATUS _samr_EnumDomainUsers(pipes_st
                               struct samr_EnumDomainUsers *r)
  {
        NTSTATUS status;
-       struct samr_info *info = NULL;
+       struct samr_domain_info *dinfo;
        int num_account;
        uint32 enum_context = *r->in.resume_handle;
        enum remote_arch_types ra_type = get_remote_arch();
        struct samr_SamArray *samr_array = NULL;
        struct samr_SamEntry *samr_entries = NULL;
  
-       /* find the policy handle.  open a policy on it. */
-       if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
-               return NT_STATUS_INVALID_HANDLE;
+       DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
  
-       status = access_check_samr_function(info->acc_granted,
-                                           SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
-                                           "_samr_EnumDomainUsers");
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
+                                  struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
  
-       DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
-       if (info->builtin_domain) {
+       if (sid_check_is_builtin(&dinfo->sid)) {
                /* No users in builtin. */
                *r->out.resume_handle = *r->in.resume_handle;
                DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
  
        /* AS ROOT !!!! */
  
-       if ((info->disp_info->enum_users != NULL) &&
-           (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
-               TALLOC_FREE(info->disp_info->enum_users);
+       if ((dinfo->disp_info->enum_users != NULL) &&
+           (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
+               TALLOC_FREE(dinfo->disp_info->enum_users);
        }
  
-       if (info->disp_info->enum_users == NULL) {
-               info->disp_info->enum_users = pdb_search_users(
-                       info->disp_info, r->in.acct_flags);
-               info->disp_info->enum_acb_mask = r->in.acct_flags;
+       if (dinfo->disp_info->enum_users == NULL) {
+               dinfo->disp_info->enum_users = pdb_search_users(
+                       dinfo->disp_info, r->in.acct_flags);
+               dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
        }
  
-       if (info->disp_info->enum_users == NULL) {
+       if (dinfo->disp_info->enum_users == NULL) {
                /* END AS ROOT !!!! */
                unbecome_root();
                return NT_STATUS_ACCESS_DENIED;
        }
  
-       num_account = pdb_search_entries(info->disp_info->enum_users,
+       num_account = pdb_search_entries(dinfo->disp_info->enum_users,
                                         enum_context, max_entries,
                                         &entries);
  
        }
  
        /* Ensure we cache this enumeration. */
-       set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
+       set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
  
        DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
  
@@@ -1107,26 -1101,22 +1102,22 @@@ NTSTATUS _samr_EnumDomainGroups(pipes_s
                                struct samr_EnumDomainGroups *r)
  {
        NTSTATUS status;
-       struct samr_info *info = NULL;
+       struct samr_domain_info *dinfo;
        struct samr_displayentry *groups;
        uint32 num_groups;
        struct samr_SamArray *samr_array = NULL;
        struct samr_SamEntry *samr_entries = NULL;
  
-       /* find the policy handle.  open a policy on it. */
-       if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
-               return NT_STATUS_INVALID_HANDLE;
-       status = access_check_samr_function(info->acc_granted,
-                                           SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
-                                           "_samr_EnumDomainGroups");
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
+                                  struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
  
        DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
  
-       if (info->builtin_domain) {
+       if (sid_check_is_builtin(&dinfo->sid)) {
                /* No groups in builtin. */
                *r->out.resume_handle = *r->in.resume_handle;
                DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
  
        become_root();
  
-       if (info->disp_info->groups == NULL) {
-               info->disp_info->groups = pdb_search_groups(info->disp_info);
+       if (dinfo->disp_info->groups == NULL) {
+               dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
  
-               if (info->disp_info->groups == NULL) {
+               if (dinfo->disp_info->groups == NULL) {
                        unbecome_root();
                        return NT_STATUS_ACCESS_DENIED;
                }
        }
  
-       num_groups = pdb_search_entries(info->disp_info->groups,
+       num_groups = pdb_search_entries(dinfo->disp_info->groups,
                                        *r->in.resume_handle,
                                        MAX_SAM_ENTRIES, &groups);
        unbecome_root();
  
        /* Ensure we cache this enumeration. */
-       set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
+       set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
  
        make_group_sam_entry_list(p->mem_ctx, &samr_entries,
                                  num_groups, groups);
@@@ -1182,26 -1172,22 +1173,22 @@@ NTSTATUS _samr_EnumDomainAliases(pipes_
                                 struct samr_EnumDomainAliases *r)
  {
        NTSTATUS status;
-       struct samr_info *info;
+       struct samr_domain_info *dinfo;
        struct samr_displayentry *aliases;
        uint32 num_aliases = 0;
        struct samr_SamArray *samr_array = NULL;
        struct samr_SamEntry *samr_entries = NULL;
  
-       /* find the policy handle.  open a policy on it. */
-       if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
-               return NT_STATUS_INVALID_HANDLE;
-       DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
-                sid_string_dbg(&info->sid)));
-       status = access_check_samr_function(info->acc_granted,
-                                           SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
-                                           "_samr_EnumDomainAliases");
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
+                                  struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
  
+       DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
+                sid_string_dbg(&dinfo->sid)));
        samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
        if (!samr_array) {
                return NT_STATUS_NO_MEMORY;
  
        become_root();
  
-       if (info->disp_info->aliases == NULL) {
-               info->disp_info->aliases = pdb_search_aliases(
-                       info->disp_info, &info->sid);
-               if (info->disp_info->aliases == NULL) {
+       if (dinfo->disp_info->aliases == NULL) {
+               dinfo->disp_info->aliases = pdb_search_aliases(
+                       dinfo->disp_info, &dinfo->sid);
+               if (dinfo->disp_info->aliases == NULL) {
                        unbecome_root();
                        return NT_STATUS_ACCESS_DENIED;
                }
        }
  
-       num_aliases = pdb_search_entries(info->disp_info->aliases,
+       num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
                                         *r->in.resume_handle,
                                         MAX_SAM_ENTRIES, &aliases);
        unbecome_root();
  
        /* Ensure we cache this enumeration. */
-       set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
+       set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
  
        make_group_sam_entry_list(p->mem_ctx, &samr_entries,
                                  num_aliases, aliases);
@@@ -1447,7 -1433,7 +1434,7 @@@ NTSTATUS _samr_QueryDisplayInfo(pipes_s
                                struct samr_QueryDisplayInfo *r)
  {
        NTSTATUS status;
-       struct samr_info *info = NULL;
+       struct samr_domain_info *dinfo;
        uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
  
        uint32 max_entries = r->in.max_entries;
  
        DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
  
-       /* find the policy handle.  open a policy on it. */
-       if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
-               return NT_STATUS_INVALID_HANDLE;
-       if (info->builtin_domain) {
-               DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
-               return NT_STATUS_OK;
-       }
-       status = access_check_samr_function(info->acc_granted,
-                                           SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
-                                           "_samr_QueryDisplayInfo");
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
+                                  struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
        switch (r->in.level) {
        case 0x1:
        case 0x4:
-               if (info->disp_info->users == NULL) {
-                       info->disp_info->users = pdb_search_users(
-                               info->disp_info, ACB_NORMAL);
-                       if (info->disp_info->users == NULL) {
+               if (dinfo->disp_info->users == NULL) {
+                       dinfo->disp_info->users = pdb_search_users(
+                               dinfo->disp_info, ACB_NORMAL);
+                       if (dinfo->disp_info->users == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
                        }
                                (unsigned  int)enum_context ));
                }
  
-               num_account = pdb_search_entries(info->disp_info->users,
+               num_account = pdb_search_entries(dinfo->disp_info->users,
                                                 enum_context, max_entries,
                                                 &entries);
                break;
        case 0x2:
-               if (info->disp_info->machines == NULL) {
-                       info->disp_info->machines = pdb_search_users(
-                               info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
-                       if (info->disp_info->machines == NULL) {
+               if (dinfo->disp_info->machines == NULL) {
+                       dinfo->disp_info->machines = pdb_search_users(
+                               dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
+                       if (dinfo->disp_info->machines == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
                        }
                                (unsigned  int)enum_context ));
                }
  
-               num_account = pdb_search_entries(info->disp_info->machines,
+               num_account = pdb_search_entries(dinfo->disp_info->machines,
                                                 enum_context, max_entries,
                                                 &entries);
                break;
        case 0x3:
        case 0x5:
-               if (info->disp_info->groups == NULL) {
-                       info->disp_info->groups = pdb_search_groups(
-                               info->disp_info);
-                       if (info->disp_info->groups == NULL) {
+               if (dinfo->disp_info->groups == NULL) {
+                       dinfo->disp_info->groups = pdb_search_groups(
+                               dinfo->disp_info);
+                       if (dinfo->disp_info->groups == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
                        }
                                (unsigned  int)enum_context ));
                }
  
-               num_account = pdb_search_entries(info->disp_info->groups,
+               num_account = pdb_search_entries(dinfo->disp_info->groups,
                                                 enum_context, max_entries,
                                                 &entries);
                break;
        }
  
        /* Ensure we cache this enumeration. */
-       set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
+       set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
  
        DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
  
@@@ -1776,25 -1753,20 +1754,20 @@@ NTSTATUS _samr_QueryAliasInfo(pipes_str
  NTSTATUS _samr_LookupNames(pipes_struct *p,
                           struct samr_LookupNames *r)
  {
+       struct samr_domain_info *dinfo;
        NTSTATUS status;
        uint32 *rid;
        enum lsa_SidType *type;
        int i;
        int num_rids = r->in.num_names;
-       DOM_SID pol_sid;
-       uint32  acc_granted;
        struct samr_Ids rids, types;
        uint32_t num_mapped = 0;
  
        DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
  
-       if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
-               return NT_STATUS_OBJECT_TYPE_MISMATCH;
-       }
-       status = access_check_samr_function(acc_granted,
-                                           0, /* Don't know the acc_bits yet */
-                                           "_samr_LookupNames");
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  0 /* Don't know the acc_bits yet */, NULL,
+                                  struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
        NT_STATUS_HAVE_NO_MEMORY(type);
  
        DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
-                sid_string_dbg(&pol_sid)));
+                sid_string_dbg(&dinfo->sid)));
  
        for (i = 0; i < num_rids; i++) {
  
  
                rid[i] = 0xffffffff;
  
-               if (sid_check_is_builtin(&pol_sid)) {
+               if (sid_check_is_builtin(&dinfo->sid)) {
                        if (lookup_builtin_name(r->in.names[i].string,
                                                &rid[i]))
                        {
@@@ -2037,13 -2009,12 +2010,12 @@@ static bool make_samr_lookup_rids(TALLO
  NTSTATUS _samr_LookupRids(pipes_struct *p,
                          struct samr_LookupRids *r)
  {
+       struct samr_domain_info *dinfo;
        NTSTATUS status;
        const char **names;
        enum lsa_SidType *attrs = NULL;
        uint32 *wire_attrs = NULL;
-       DOM_SID pol_sid;
        int num_rids = (int)r->in.num_rids;
-       uint32 acc_granted;
        int i;
        struct lsa_Strings names_array;
        struct samr_Ids types_array;
  
        DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
  
-       /* find the policy handle.  open a policy on it. */
-       if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
-               return NT_STATUS_INVALID_HANDLE;
-       status = access_check_samr_function(acc_granted,
-                                           0, /* Don't know the acc_bits yet */
-                                           "_samr_LookupRids");
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  0 /* Don't know the acc_bits yet */, NULL,
+                                  struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
        }
  
        become_root();  /* lookup_sid can require root privs */
-       status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
+       status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
                                 names, attrs);
        unbecome_root();
  
@@@ -2123,7 -2090,8 +2091,8 @@@ NTSTATUS _samr_OpenUser(pipes_struct *p
  {
        struct samu *sampass=NULL;
        DOM_SID sid;
-       struct samr_info *info = NULL;
+       struct samr_domain_info *dinfo;
+       struct samr_info *info;
        SEC_DESC *psd = NULL;
        uint32    acc_granted;
        uint32    des_access = r->in.access_mask;
        bool ret;
        NTSTATUS nt_status;
        SE_PRIV se_rights;
+       NTSTATUS status;
  
-       /* find the domain policy handle and get domain SID / access bits in the domain policy. */
-       if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
-               return NT_STATUS_INVALID_HANDLE;
-       nt_status = access_check_samr_function(acc_granted,
-                                              SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
-                                              "_samr_OpenUser" );
-       if ( !NT_STATUS_IS_OK(nt_status) )
-               return nt_status;
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
+                                  struct samr_domain_info, &status);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
  
        if ( !(sampass = samu_new( p->mem_ctx )) ) {
                return NT_STATUS_NO_MEMORY;
  
        /* append the user's RID to it */
  
-       if (!sid_append_rid(&sid, r->in.rid))
+       if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
                return NT_STATUS_NO_SUCH_USER;
  
        /* check if access can be granted as requested by client. */
@@@ -2788,7 -2752,7 +2753,7 @@@ NTSTATUS _samr_QueryDomainInfo(pipes_st
                               struct samr_QueryDomainInfo *r)
  {
        NTSTATUS status = NT_STATUS_OK;
-       struct samr_info *info = NULL;
+       struct samr_domain_info *dinfo;
        union samr_DomainInfo *dom_info;
        time_t u_expire, u_min_age;
  
  
        DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
  
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
+                                  struct samr_domain_info, &status);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
        dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
        if (!dom_info) {
                return NT_STATUS_NO_MEMORY;
        }
  
-       /* find the policy handle.  open a policy on it. */
-       if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
-               return NT_STATUS_INVALID_HANDLE;
-       }
-       status = access_check_samr_function(info->acc_granted,
-                                           SAMR_ACCESS_OPEN_DOMAIN,
-                                           "_samr_QueryDomainInfo" );
-       if ( !NT_STATUS_IS_OK(status) )
-               return status;
        switch (r->in.level) {
                case 0x01:
  
  
                        /* AS ROOT !!! */
  
-                       dom_info->general.num_users     = count_sam_users(info->disp_info, ACB_NORMAL);
-                       dom_info->general.num_groups    = count_sam_groups(info->disp_info);
-                       dom_info->general.num_aliases   = count_sam_aliases(info->disp_info);
+                       dom_info->general.num_users     = count_sam_users(
+                               dinfo->disp_info, ACB_NORMAL);
+                       dom_info->general.num_groups    = count_sam_groups(
+                               dinfo->disp_info);
+                       dom_info->general.num_aliases   = count_sam_aliases(
+                               dinfo->disp_info);
  
                        pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
  
@@@ -3032,7 -2994,8 +2995,8 @@@ NTSTATUS _samr_CreateUser2(pipes_struc
        const char *account = NULL;
        DOM_SID sid;
        uint32_t acb_info = r->in.acct_flags;
-       struct samr_info *info = NULL;
+       struct samr_domain_info *dinfo;
+       struct samr_info *info;
        NTSTATUS nt_status;
        uint32 acc_granted;
        SEC_DESC *psd;
        uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
        bool can_add_account = False;
        SE_PRIV se_rights;
-       DISP_INFO *disp_info = NULL;
  
-       /* Get the domain SID stored in the domain policy */
-       if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted,
-                                    &disp_info))
-               return NT_STATUS_INVALID_HANDLE;
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
+                                  struct samr_domain_info, &nt_status);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               return nt_status;
+       }
  
-       if (disp_info->builtin_domain) {
+       if (sid_check_is_builtin(&dinfo->sid)) {
                DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
                return NT_STATUS_ACCESS_DENIED;
        }
  
-       nt_status = access_check_samr_function(acc_granted,
-                                              SAMR_DOMAIN_ACCESS_CREATE_USER,
-                                              "_samr_CreateUser2");
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               return nt_status;
-       }
        if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
              acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
                /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
        }
  
        /* After a "set" ensure we have no cached display info. */
-       force_flush_samr_cache(info->disp_info);
+       force_flush_samr_cache(&sid);
  
        *r->out.access_granted = acc_granted;
  
@@@ -3195,8 -3152,11 +3153,11 @@@ NTSTATUS _samr_CreateUser(pipes_struct 
  NTSTATUS _samr_Connect(pipes_struct *p,
                       struct samr_Connect *r)
  {
-       struct samr_info *info = NULL;
+       struct samr_connect_info *info;
+       uint32_t acc_granted;
+       struct policy_handle hnd;
        uint32    des_access = r->in.access_mask;
+       NTSTATUS status;
  
        /* Access check */
  
                return NT_STATUS_ACCESS_DENIED;
        }
  
-       /* set up the SAMR connect_anon response */
-       /* associate the user's SID with the new handle. */
-       if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
-               return NT_STATUS_NO_MEMORY;
        /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
           was observed from a win98 client trying to enumerate users (when configured
           user level access control on shares)   --jerry */
        map_max_allowed_access(p->server_info->ptok, &des_access);
  
        se_map_generic( &des_access, &sam_generic_mapping );
-       info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN);
  
-       /* get a (unique) handle.  open a policy on it. */
-       if (!create_policy_hnd(p, r->out.connect_handle, info))
-               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
+                                   |SAMR_ACCESS_LOOKUP_DOMAIN);
+       /* set up the SAMR connect_anon response */
+       info = policy_handle_create(p, &hnd, acc_granted,
+                                   struct samr_connect_info,
+                                   &status);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
  
+       *r->out.connect_handle = hnd;
        return NT_STATUS_OK;
  }
  
  NTSTATUS _samr_Connect2(pipes_struct *p,
                        struct samr_Connect2 *r)
  {
-       struct samr_info *info = NULL;
+       struct samr_connect_info *info = NULL;
+       struct policy_handle hnd;
        SEC_DESC *psd = NULL;
        uint32    acc_granted;
        uint32    des_access = r->in.access_mask;
        if ( !NT_STATUS_IS_OK(nt_status) )
                return nt_status;
  
-       /* associate the user's SID and access granted with the new handle. */
-       if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
-               return NT_STATUS_NO_MEMORY;
-       info->acc_granted = acc_granted;
-       info->status = r->in.access_mask; /* this looks so wrong... - gd */
-       /* get a (unique) handle.  open a policy on it. */
-       if (!create_policy_hnd(p, r->out.connect_handle, info))
-               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       info = policy_handle_create(p, &hnd, acc_granted,
+                                   struct samr_connect_info, &nt_status);
+         if (!NT_STATUS_IS_OK(nt_status)) {
+                 return nt_status;
+         }
  
        DEBUG(5,("%s: %d\n", fn, __LINE__));
  
-       return nt_status;
+       *r->out.connect_handle = hnd;
+       return NT_STATUS_OK;
  }
  
  /****************************************************************
@@@ -3361,20 -3320,18 +3321,18 @@@ NTSTATUS _samr_Connect5(pipes_struct *p
  NTSTATUS _samr_LookupDomain(pipes_struct *p,
                            struct samr_LookupDomain *r)
  {
-       NTSTATUS status = NT_STATUS_OK;
-       struct samr_info *info;
+       NTSTATUS status;
+       struct samr_connect_info *info;
        const char *domain_name;
        DOM_SID *sid = NULL;
  
-       if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
-               return NT_STATUS_INVALID_HANDLE;
        /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
           Reverted that change so we will work with RAS servers again */
  
-       status = access_check_samr_function(info->acc_granted,
-                                           SAMR_ACCESS_OPEN_DOMAIN,
-                                           "_samr_LookupDomain");
+       info = policy_handle_find(p, r->in.connect_handle,
+                                 SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
+                                 struct samr_connect_info,
+                                 &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@@ -3413,17 -3370,14 +3371,14 @@@ NTSTATUS _samr_EnumDomains(pipes_struc
                           struct samr_EnumDomains *r)
  {
        NTSTATUS status;
-       struct samr_info *info;
+       struct samr_connect_info *info;
        uint32_t num_entries = 2;
        struct samr_SamEntry *entry_array = NULL;
        struct samr_SamArray *sam;
  
-       if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
-               return NT_STATUS_INVALID_HANDLE;
-       status = access_check_samr_function(info->acc_granted,
-                                           SAMR_ACCESS_ENUM_DOMAINS,
-                                           "_samr_EnumDomains");
+       info = policy_handle_find(p, r->in.connect_handle,
+                                 SAMR_ACCESS_ENUM_DOMAINS, NULL,
+                                 struct samr_connect_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@@ -3465,6 -3419,7 +3420,7 @@@ NTSTATUS _samr_OpenAlias(pipes_struct *
        DOM_SID sid;
        uint32 alias_rid = r->in.rid;
        struct    samr_info *info = NULL;
+       struct samr_domain_info *dinfo;
        SEC_DESC *psd = NULL;
        uint32    acc_granted;
        uint32    des_access = r->in.access_mask;
        NTSTATUS  status;
        SE_PRIV se_rights;
  
-       /* find the domain policy and get the SID / access bits stored in the domain policy */
-       if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
-               return NT_STATUS_INVALID_HANDLE;
-       status = access_check_samr_function(acc_granted,
-                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
-                                           "_samr_OpenAlias");
-       if ( !NT_STATUS_IS_OK(status) )
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
+                                  struct samr_domain_info, &status);
+       if (!NT_STATUS_IS_OK(status)) {
                return status;
+       }
  
        /* append the alias' RID to it */
  
-       if (!sid_append_rid(&sid, alias_rid))
+       if (!sid_compose(&sid, &dinfo->sid, alias_rid))
                return NT_STATUS_NO_SUCH_ALIAS;
  
        /*check if access can be granted as requested by client. */
@@@ -3823,7 -3773,7 +3774,7 @@@ static NTSTATUS set_user_info_23(TALLOC
                                 struct samu *pwd)
  {
        char *plaintext_buf = NULL;
 -      uint32 len = 0;
 +      size_t len = 0;
        uint32_t acct_ctrl;
        NTSTATUS status;
  
                                      id23->password.data,
                                      &plaintext_buf,
                                      &len,
 -                                    STR_UNICODE)) {
 +                                    CH_UTF16)) {
                        return NT_STATUS_WRONG_PASSWORD;
                }
  
  
  static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
  {
 -      uint32 len = 0;
 +      size_t len = 0;
        char *plaintext_buf = NULL;
        uint32 acct_ctrl;
  
                                pass,
                                &plaintext_buf,
                                &len,
 -                              STR_UNICODE)) {
 +                              CH_UTF16)) {
                return False;
        }
  
@@@ -4224,8 -4174,8 +4175,8 @@@ NTSTATUS _samr_SetUserInfo(pipes_struc
                        if (!p->server_info->user_session_key.length) {
                                status = NT_STATUS_NO_USER_SESSION_KEY;
                        }
 -                      SamOEMhashBlob(info->info23.password.data, 516,
 -                                     &p->server_info->user_session_key);
 +                      arcfour_crypt_blob(info->info23.password.data, 516,
 +                                         &p->server_info->user_session_key);
  
                        dump_data(100, info->info23.password.data, 516);
  
                        if (!p->server_info->user_session_key.length) {
                                status = NT_STATUS_NO_USER_SESSION_KEY;
                        }
 -                      SamOEMhashBlob(info->info24.password.data,
 -                                     516,
 -                                     &p->server_info->user_session_key);
 +                      arcfour_crypt_blob(info->info24.password.data,
 +                                         516,
 +                                         &p->server_info->user_session_key);
  
                        dump_data(100, info->info24.password.data, 516);
  
        /* ================ END SeMachineAccountPrivilege BLOCK ================ */
  
        if (NT_STATUS_IS_OK(status)) {
-               force_flush_samr_cache(disp_info);
+               force_flush_samr_cache(&sid);
        }
  
        return status;
@@@ -4319,36 -4269,25 +4270,25 @@@ NTSTATUS _samr_GetAliasMembership(pipes
  {
        size_t num_alias_rids;
        uint32 *alias_rids;
-       struct samr_info *info = NULL;
+       struct samr_domain_info *dinfo;
        size_t i;
  
-       NTSTATUS ntstatus1;
-       NTSTATUS ntstatus2;
+       NTSTATUS status;
  
        DOM_SID *members;
  
        DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
  
-       /* find the policy handle.  open a policy on it. */
-       if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
-               return NT_STATUS_INVALID_HANDLE;
-       ntstatus1 = access_check_samr_function(info->acc_granted,
-                                              SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
-                                              "_samr_GetAliasMembership");
-       ntstatus2 = access_check_samr_function(info->acc_granted,
-                                              SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
-                                              "_samr_GetAliasMembership");
-       if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
-               if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
-                   !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
-                       return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
-               }
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
+                                  | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
+                                  struct samr_domain_info, &status);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
  
-       if (!sid_check_is_domain(&info->sid) &&
-           !sid_check_is_builtin(&info->sid))
+       if (!sid_check_is_domain(&dinfo->sid) &&
+           !sid_check_is_builtin(&dinfo->sid))
                return NT_STATUS_OBJECT_TYPE_MISMATCH;
  
        if (r->in.sids->num_sids) {
        num_alias_rids = 0;
  
        become_root();
-       ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
-                                              r->in.sids->num_sids,
-                                              &alias_rids, &num_alias_rids);
+       status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
+                                           r->in.sids->num_sids,
+                                           &alias_rids, &num_alias_rids);
        unbecome_root();
  
-       if (!NT_STATUS_IS_OK(ntstatus1)) {
-               return ntstatus1;
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
  
        r->out.rids->count = num_alias_rids;
@@@ -4560,7 -4499,7 +4500,7 @@@ NTSTATUS _samr_AddAliasMember(pipes_str
        /******** END SeAddUsers BLOCK *********/
  
        if (NT_STATUS_IS_OK(status)) {
-               force_flush_samr_cache(disp_info);
+               force_flush_samr_cache(&alias_sid);
        }
  
        return status;
@@@ -4610,7 -4549,7 +4550,7 @@@ NTSTATUS _samr_DeleteAliasMember(pipes_
        /******** END SeAddUsers BLOCK *********/
  
        if (NT_STATUS_IS_OK(status)) {
-               force_flush_samr_cache(disp_info);
+               force_flush_samr_cache(&alias_sid);
        }
  
        return status;
@@@ -4664,7 -4603,7 +4604,7 @@@ NTSTATUS _samr_AddGroupMember(pipes_str
  
        /******** END SeAddUsers BLOCK *********/
  
-       force_flush_samr_cache(disp_info);
+       force_flush_samr_cache(&group_sid);
  
        return status;
  }
@@@ -4722,7 -4661,7 +4662,7 @@@ NTSTATUS _samr_DeleteGroupMember(pipes_
  
        /******** END SeAddUsers BLOCK *********/
  
-       force_flush_samr_cache(disp_info);
+       force_flush_samr_cache(&group_sid);
  
        return status;
  }
@@@ -4812,7 -4751,7 +4752,7 @@@ NTSTATUS _samr_DeleteUser(pipes_struct 
  
        ZERO_STRUCTP(r->out.user_handle);
  
-       force_flush_samr_cache(disp_info);
+       force_flush_samr_cache(&user_sid);
  
        return NT_STATUS_OK;
  }
@@@ -4878,7 -4817,7 +4818,7 @@@ NTSTATUS _samr_DeleteDomainGroup(pipes_
        if (!close_policy_hnd(p, r->in.group_handle))
                return NT_STATUS_OBJECT_NAME_INVALID;
  
-       force_flush_samr_cache(disp_info);
+       force_flush_samr_cache(&group_sid);
  
        return NT_STATUS_OK;
  }
@@@ -4949,7 -4888,7 +4889,7 @@@ NTSTATUS _samr_DeleteDomAlias(pipes_str
        if (!close_policy_hnd(p, r->in.alias_handle))
                return NT_STATUS_OBJECT_NAME_INVALID;
  
-       force_flush_samr_cache(disp_info);
+       force_flush_samr_cache(&alias_sid);
  
        return NT_STATUS_OK;
  }
@@@ -4963,27 -4902,21 +4903,21 @@@ NTSTATUS _samr_CreateDomainGroup(pipes_
  
  {
        NTSTATUS status;
-       DOM_SID dom_sid;
        DOM_SID info_sid;
        const char *name;
+       struct samr_domain_info *dinfo;
        struct samr_info *info;
-       uint32 acc_granted;
        SE_PRIV se_rights;
        bool can_add_accounts;
-       DISP_INFO *disp_info = NULL;
-       /* Find the policy handle. Open a policy on it. */
-       if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
-               return NT_STATUS_INVALID_HANDLE;
  
-       status = access_check_samr_function(acc_granted,
-                                           SAMR_DOMAIN_ACCESS_CREATE_GROUP,
-                                           "_samr_CreateDomainGroup");
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
+                                  struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
  
-       if (!sid_equal(&dom_sid, get_global_sam_sid()))
+       if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
                return NT_STATUS_ACCESS_DENIED;
  
        name = r->in.name->string;
        if ( !NT_STATUS_IS_OK(status) )
                return status;
  
-       sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
+       sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
  
        if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
                return NT_STATUS_NO_MEMORY;
        if (!create_policy_hnd(p, r->out.group_handle, info))
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
  
-       force_flush_samr_cache(disp_info);
+       force_flush_samr_cache(&info_sid);
  
        return NT_STATUS_OK;
  }
  NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
                              struct samr_CreateDomAlias *r)
  {
-       DOM_SID dom_sid;
        DOM_SID info_sid;
        const char *name = NULL;
+       struct samr_domain_info *dinfo;
        struct samr_info *info;
-       uint32 acc_granted;
        gid_t gid;
        NTSTATUS result;
        SE_PRIV se_rights;
        bool can_add_accounts;
-       DISP_INFO *disp_info = NULL;
-       /* Find the policy handle. Open a policy on it. */
-       if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
-               return NT_STATUS_INVALID_HANDLE;
  
-       result = access_check_samr_function(acc_granted,
-                                           SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
-                                           "_samr_CreateDomAlias");
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
+                                  struct samr_domain_info, &result);
        if (!NT_STATUS_IS_OK(result)) {
                return result;
        }
  
-       if (!sid_equal(&dom_sid, get_global_sam_sid()))
+       if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
                return NT_STATUS_ACCESS_DENIED;
  
        name = r->in.alias_name->string;
                return result;
        }
  
-       sid_copy(&info_sid, get_global_sam_sid());
-       sid_append_rid(&info_sid, *r->out.rid);
+       sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
  
        if (!sid_to_gid(&info_sid, &gid)) {
                DEBUG(10, ("Could not find alias just created\n"));
        if (!create_policy_hnd(p, r->out.alias_handle, info))
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
  
-       force_flush_samr_cache(disp_info);
+       force_flush_samr_cache(&info_sid);
  
        return NT_STATUS_OK;
  }
@@@ -5293,7 -5219,7 +5220,7 @@@ NTSTATUS _samr_SetGroupInfo(pipes_struc
        /******** End SeAddUsers BLOCK *********/
  
        if (NT_STATUS_IS_OK(status)) {
-               force_flush_samr_cache(disp_info);
+               force_flush_samr_cache(&group_sid);
        }
  
        return status;
@@@ -5395,7 -5321,7 +5322,7 @@@ NTSTATUS _samr_SetAliasInfo(pipes_struc
          /******** End SeAddUsers BLOCK *********/
  
        if (NT_STATUS_IS_OK(status))
-               force_flush_samr_cache(disp_info);
+               force_flush_samr_cache(&group_sid);
  
        return status;
  }
@@@ -5444,28 -5370,24 +5371,24 @@@ NTSTATUS _samr_OpenGroup(pipes_struct *
                         struct samr_OpenGroup *r)
  
  {
-       DOM_SID sid;
        DOM_SID info_sid;
        GROUP_MAP map;
+       struct samr_domain_info *dinfo;
        struct samr_info *info;
        SEC_DESC         *psd = NULL;
        uint32            acc_granted;
        uint32            des_access = r->in.access_mask;
        size_t            sd_size;
        NTSTATUS          status;
-       fstring sid_string;
        bool ret;
        SE_PRIV se_rights;
  
-       if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
-               return NT_STATUS_INVALID_HANDLE;
-       status = access_check_samr_function(acc_granted,
-                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
-                                           "_samr_OpenGroup");
-       if ( !NT_STATUS_IS_OK(status) )
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
+                                  struct samr_domain_info, &status);
+       if (!NT_STATUS_IS_OK(status)) {
                return status;
+       }
  
        /*check if access can be granted as requested by client. */
        map_max_allowed_access(p->server_info->ptok, &des_access);
  
        /* this should not be hard-coded like this */
  
-       if (!sid_equal(&sid, get_global_sam_sid()))
+       if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
                return NT_STATUS_ACCESS_DENIED;
  
-       sid_copy(&info_sid, get_global_sam_sid());
-       sid_append_rid(&info_sid, r->in.rid);
-       sid_to_fstring(sid_string, &info_sid);
+       sid_compose(&info_sid, &dinfo->sid, r->in.rid);
  
        if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
                return NT_STATUS_NO_MEMORY;
  
        info->acc_granted = acc_granted;
  
-       DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
+       DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
+                  sid_string_dbg(&info_sid)));
  
        /* check if that group really exists */
        become_root();
  NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
                                             struct samr_RemoveMemberFromForeignDomain *r)
  {
-       DOM_SID                 delete_sid, domain_sid;
-       uint32                  acc_granted;
+       struct samr_domain_info *dinfo;
        NTSTATUS                result;
-       DISP_INFO *disp_info = NULL;
-       sid_copy( &delete_sid, r->in.sid );
  
        DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
-               sid_string_dbg(&delete_sid)));
+                sid_string_dbg(r->in.sid)));
  
        /* Find the policy handle. Open a policy on it. */
  
-       if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
-                                    &acc_granted, &disp_info))
-               return NT_STATUS_INVALID_HANDLE;
-       result = access_check_samr_function(acc_granted,
-                                           STD_RIGHT_DELETE_ACCESS,
-                                           "_samr_RemoveMemberFromForeignDomain");
-       if (!NT_STATUS_IS_OK(result))
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  STD_RIGHT_DELETE_ACCESS, NULL,
+                                  struct samr_domain_info, &result);
+       if (!NT_STATUS_IS_OK(result)) {
                return result;
+       }
  
        DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
-                 sid_string_dbg(&domain_sid)));
+                 sid_string_dbg(&dinfo->sid)));
  
        /* we can only delete a user from a group since we don't have
           nested groups anyways.  So in the latter case, just say OK */
         * only application of this call. To verify this, let people report
         * other cases. */
  
-       if (!sid_check_is_builtin(&domain_sid)) {
+       if (!sid_check_is_builtin(&dinfo->sid)) {
                DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
                         "global_sam_sid() = %s\n",
-                        sid_string_dbg(&domain_sid),
+                        sid_string_dbg(&dinfo->sid),
                         sid_string_dbg(get_global_sam_sid())));
                DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
                return NT_STATUS_OK;
        }
  
-       force_flush_samr_cache(disp_info);
+       force_flush_samr_cache(&dinfo->sid);
  
        result = NT_STATUS_OK;
  
@@@ -5599,7 -5512,7 +5513,7 @@@ NTSTATUS _samr_QueryDomainInfo2(pipes_s
  NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
                             struct samr_SetDomainInfo *r)
  {
-       struct samr_info *info = NULL;
+       struct samr_domain_info *dinfo;
        time_t u_expire, u_min_age;
        time_t u_logout;
        time_t u_lock_duration, u_reset_time;
  
        DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
  
-       /* find the policy handle.  open a policy on it. */
-       if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
-               return NT_STATUS_INVALID_HANDLE;
        /* We do have different access bits for info
         * levels here, but we're really just looking for
         * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
         * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
         * set we are ok. */
  
-       result = access_check_samr_function(info->acc_granted,
-                                           SAMR_DOMAIN_ACCESS_SET_INFO_1,
-                                           "_samr_SetDomainInfo");
-       if (!NT_STATUS_IS_OK(result))
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_SET_INFO_1, NULL,
+                                  struct samr_domain_info, &result);
+       if (!NT_STATUS_IS_OK(result)) {
                return result;
+       }
  
        DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
  
  NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
                                          struct samr_GetDisplayEnumerationIndex *r)
  {
-       struct samr_info *info = NULL;
+       struct samr_domain_info *dinfo;
        uint32_t max_entries = (uint32_t) -1;
        uint32_t enum_context = 0;
        int i;
  
        DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
  
-       /* find the policy handle.  open a policy on it. */
-       if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
-               return NT_STATUS_INVALID_HANDLE;
-       }
-       status = access_check_samr_function(info->acc_granted,
-                                           SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
-                                           "_samr_GetDisplayEnumerationIndex");
+       dinfo = policy_handle_find(p, r->in.domain_handle,
+                                  SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
+                                  struct samr_domain_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
  
        switch (r->in.level) {
        case 1:
-               if (info->disp_info->users == NULL) {
-                       info->disp_info->users = pdb_search_users(
-                               info->disp_info, ACB_NORMAL);
-                       if (info->disp_info->users == NULL) {
+               if (dinfo->disp_info->users == NULL) {
+                       dinfo->disp_info->users = pdb_search_users(
+                               dinfo->disp_info, ACB_NORMAL);
+                       if (dinfo->disp_info->users == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
                        }
                                "using cached user enumeration at index %u\n",
                                (unsigned int)enum_context));
                }
-               num_account = pdb_search_entries(info->disp_info->users,
+               num_account = pdb_search_entries(dinfo->disp_info->users,
                                                 enum_context, max_entries,
                                                 &entries);
                break;
        case 2:
-               if (info->disp_info->machines == NULL) {
-                       info->disp_info->machines = pdb_search_users(
-                               info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
-                       if (info->disp_info->machines == NULL) {
+               if (dinfo->disp_info->machines == NULL) {
+                       dinfo->disp_info->machines = pdb_search_users(
+                               dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
+                       if (dinfo->disp_info->machines == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
                        }
                                "using cached machine enumeration at index %u\n",
                                (unsigned int)enum_context));
                }
-               num_account = pdb_search_entries(info->disp_info->machines,
+               num_account = pdb_search_entries(dinfo->disp_info->machines,
                                                 enum_context, max_entries,
                                                 &entries);
                break;
        case 3:
-               if (info->disp_info->groups == NULL) {
-                       info->disp_info->groups = pdb_search_groups(
-                               info->disp_info);
-                       if (info->disp_info->groups == NULL) {
+               if (dinfo->disp_info->groups == NULL) {
+                       dinfo->disp_info->groups = pdb_search_groups(
+                               dinfo->disp_info);
+                       if (dinfo->disp_info->groups == NULL) {
                                unbecome_root();
                                return NT_STATUS_ACCESS_DENIED;
                        }
                                "using cached group enumeration at index %u\n",
                                (unsigned int)enum_context));
                }
-               num_account = pdb_search_entries(info->disp_info->groups,
+               num_account = pdb_search_entries(dinfo->disp_info->groups,
                                                 enum_context, max_entries,
                                                 &entries);
                break;
        unbecome_root();
  
        /* Ensure we cache this enumeration. */
-       set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
+       set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
  
        DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
                r->in.name->string));
diff --combined source3/utils/net_rpc.c
index 2651a8d034e136d2d07227275f37f246b635cc0a,0b662819aeb0d810fa011c00c5f019db83e64c44..5dd3df9a6908c9bd6da4b7fe4146df6fc5b5f47e
@@@ -22,7 -22,6 +22,7 @@@
  
  #include "includes.h"
  #include "utils/net.h"
 +#include "../libcli/auth/libcli_auth.h"
  
  static int net_mode_share;
  static bool sync_files(struct copy_clistate *cp_clistate, const char *mask);
@@@ -121,6 -120,7 +121,7 @@@ int run_rpc_command(struct net_context 
        NTSTATUS nt_status;
        DOM_SID *domain_sid;
        const char *domain_name;
+       int ret = -1;
  
        /* make use of cli_state handed over as an argument, if possible */
        if (!cli_arg) {
  
        if (!(mem_ctx = talloc_init("run_rpc_command"))) {
                DEBUG(0, ("talloc_init() failed\n"));
-               cli_shutdown(cli);
-               return -1;
+               goto fail;
        }
  
        nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
                                              &domain_name);
        if (!NT_STATUS_IS_OK(nt_status)) {
-               cli_shutdown(cli);
-               return -1;
+               goto fail;
        }
  
        if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
                        if (!NT_STATUS_IS_OK(nt_status)) {
                                DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
                                        nt_errstr(nt_status) ));
-                               cli_shutdown(cli);
-                               return -1;
+                               goto fail;
                        }
                } else {
                        if (conn_flags & NET_FLAGS_SEAL) {
                                DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
                                        get_pipe_name_from_iface(interface),
                                        nt_errstr(nt_status) ));
-                               cli_shutdown(cli);
-                               return -1;
+                               goto fail;
                        }
                }
        }
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
        } else {
+               ret = 0;
                DEBUG(5, ("rpc command function succedded\n"));
        }
  
                }
        }
  
+ fail:
        /* close the connection only if it was opened here */
        if (!cli_arg) {
                cli_shutdown(cli);
        }
  
        talloc_destroy(mem_ctx);
-       return (!NT_STATUS_IS_OK(nt_status));
+       return ret;
  }
  
  /**
@@@ -5739,8 -5737,7 +5738,8 @@@ static NTSTATUS vampire_trusted_domain(
        NTSTATUS nt_status;
        union lsa_TrustedDomainInfo *info = NULL;
        char *cleartextpwd = NULL;
 -      uint8_t nt_hash[16];
 +      uint8_t session_key[16];
 +      DATA_BLOB session_key_blob;
        DATA_BLOB data;
  
        nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd, mem_ctx,
        data = data_blob(info->password.password->data,
                         info->password.password->length);
  
 -      if (!rpccli_get_pwd_hash(pipe_hnd, nt_hash)) {
 +      if (!rpccli_get_pwd_hash(pipe_hnd, session_key)) {
                DEBUG(0, ("Could not retrieve password hash\n"));
                goto done;
        }
  
 -      cleartextpwd = decrypt_trustdom_secret(nt_hash, &data);
 +      session_key_blob = data_blob_const(session_key, sizeof(session_key));
 +      cleartextpwd = sess_decrypt_string(mem_ctx, &data, &session_key_blob);
  
        if (cleartextpwd == NULL) {
                DEBUG(0,("retrieved NULL password\n"));
@@@ -6105,7 -6101,7 +6104,7 @@@ static int rpc_trustdom_list(struct net
        /* SamrConnect2 */
        nt_status = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
                                         pipe_hnd->desthost,
-                                        SAMR_ACCESS_OPEN_DOMAIN,
+                                        SAMR_ACCESS_LOOKUP_DOMAIN,
                                         &connect_hnd);
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
index 1587793bdc0f7028d6125e9b5da8c6d43abc5d4d,1fec1401240c1d322a86e1059d0d96042d22588f..78bbce3dfc02830ed2184df799d2bf09ccc1e6e7
@@@ -20,7 -20,6 +20,7 @@@
  
  #include "includes.h"
  #include "utils/net.h"
 +#include "../libcli/auth/libcli_auth.h"
  
  /* Macro for checking RPC error codes to make things more readable */
  
@@@ -102,7 -101,7 +102,7 @@@ NTSTATUS net_rpc_join_ok(struct net_con
  
        ntret = cli_rpc_pipe_open_schannel_with_key(
                cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
 -              domain, netlogon_pipe->dc, &pipe_hnd);
 +              domain, &netlogon_pipe->dc, &pipe_hnd);
  
        if (!NT_STATUS_IS_OK(ntret)) {
                DEBUG(0,("net_rpc_join_ok: failed to open schannel session "
@@@ -245,7 -244,7 +245,7 @@@ int net_rpc_join_newstyle(struct net_co
        CHECK_RPC_ERR(rpccli_samr_Connect2(pipe_hnd, mem_ctx,
                                           pipe_hnd->desthost,
                                           SAMR_ACCESS_ENUM_DOMAINS
-                                          | SAMR_ACCESS_OPEN_DOMAIN,
+                                          | SAMR_ACCESS_LOOKUP_DOMAIN,
                                           &sam_pol),
                      "could not connect to SAM database");
  
index 7b4e85195bef9342757ed6f957b8ab33438b36b0,9c867fd5e41e71c125e9332e027d3fa253a2d0ac..9483ae2a9ad8e96da00238b2420b88a36686046f
@@@ -2632,7 -2632,7 +2632,7 @@@ static bool test_QueryUserInfo_pwdlasts
  static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
                                struct cli_credentials *machine_credentials,
                                struct cli_credentials *test_credentials,
 -                              struct creds_CredentialState *creds,
 +                              struct netlogon_creds_CredentialState *creds,
                                NTSTATUS expected_result)
  {
        NTSTATUS status;
        d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
  
        ZERO_STRUCT(auth2);
 -      creds_client_authenticator(creds, &auth);
 +      netlogon_creds_client_authenticator(creds, &auth);
  
        r.in.validation_level = 2;
  
                torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
        }
  
 -      torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred),
 +      torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
                        "Credential chaining failed");
  
        return true;
@@@ -2724,7 -2724,7 +2724,7 @@@ static bool test_SamLogon(struct tortur
                          struct cli_credentials *test_credentials,
                          NTSTATUS expected_result)
  {
 -      struct creds_CredentialState *creds;
 +      struct netlogon_creds_CredentialState *creds;
  
        if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
                return false;
@@@ -5664,7 -5664,9 +5664,9 @@@ static bool test_OpenDomain(struct dcer
                }
                break;
        case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
-               ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
+               if (!torture_setting_bool(tctx, "samba3", false)) {
+                       ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
+               }
                ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials);
                if (!ret) {
                        printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));