samr: for correctness, rename samr_RidTypeArray to samr_RidAttrArray.
[samba.git] / source3 / rpc_server / srv_samr_nt.c
index 5e786a0404b1c564ed7c2f5c26737dbd0000395a..c8c5572b57537c0fcd07cb40a7c5848b9c78f514 100644 (file)
 #include "../libcli/auth/libcli_auth.h"
 #include "../librpc/gen_ndr/srv_samr.h"
 #include "rpc_server/srv_samr_util.h"
+#include "../lib/crypto/arcfour.h"
+#include "secrets.h"
+#include "rpc_client/init_lsa.h"
+#include "../libcli/security/dom_sid.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
@@ -74,7 +78,7 @@ struct samr_alias_info {
 };
 
 typedef struct disp_info {
-       DOM_SID sid; /* identify which domain this is. */
+       struct dom_sid sid; /* identify which domain this is. */
        struct pdb_search *users; /* querydispinfo 1 and 4 */
        struct pdb_search *machines; /* querydispinfo 2 */
        struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
@@ -121,15 +125,15 @@ static const struct generic_mapping ali_generic_mapping = {
 /*******************************************************************
 *******************************************************************/
 
-static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
+static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
                                      const struct generic_mapping *map,
-                                    DOM_SID *sid, uint32 sid_access )
+                                    struct dom_sid *sid, uint32 sid_access )
 {
-       DOM_SID domadmin_sid;
-       SEC_ACE ace[5];         /* at most 5 entries */
+       struct dom_sid domadmin_sid;
+       struct security_ace ace[5];             /* at most 5 entries */
        size_t i = 0;
 
-       SEC_ACL *psa = NULL;
+       struct security_acl *psa = NULL;
 
        /* basic access for Everyone */
 
@@ -174,12 +178,20 @@ static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
 /*******************************************************************
  Checks if access to an object should be granted, and returns that
  level of access for further checks.
+
+ If the user has either of needed_priv_1 or needed_priv_2 then they
+ get the rights in rights_mask in addition to any calulated rights.
+
+ This handles the unusual case where we need to allow two different
+ privileges to obtain exactly the same rights, which occours only in
+ SAMR.
 ********************************************************************/
 
-NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token,
-                                          SE_PRIV *rights, uint32 rights_mask,
-                                          uint32 des_access, uint32 *acc_granted,
-                                         const char *debug )
+NTSTATUS access_check_object( struct security_descriptor *psd, struct security_token *token,
+                             enum sec_privilege needed_priv_1, enum sec_privilege needed_priv_2,
+                             uint32 rights_mask,
+                             uint32 des_access, uint32 *acc_granted,
+                             const char *debug )
 {
        NTSTATUS status = NT_STATUS_ACCESS_DENIED;
        uint32 saved_mask = 0;
@@ -188,9 +200,8 @@ NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token,
           by privileges (mostly having to do with creating/modifying/deleting
           users and groups) */
 
-       if (rights && !se_priv_equal(rights, &se_priv_none) &&
-                       user_has_any_privilege(token, rights)) {
-
+       if ((needed_priv_1 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_1)) ||
+           (needed_priv_2 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_2))) {
                saved_mask = (des_access & rights_mask);
                des_access &= ~saved_mask;
 
@@ -238,7 +249,7 @@ done:
  Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
 ********************************************************************/
 
-void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
+void map_max_allowed_access(const struct security_token *nt_token,
                            const struct unix_user_token *unix_token,
                            uint32_t *pacc_requested)
 {
@@ -266,7 +277,7 @@ void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
 
        /* Full access for DOMAIN\Domain Admins. */
        if ( IS_DC ) {
-               DOM_SID domadmin_sid;
+               struct dom_sid domadmin_sid;
                sid_compose(&domadmin_sid, get_global_sam_sid(),
                            DOMAIN_RID_ADMINS);
                if (is_sid_in_token(nt_token, &domadmin_sid)) {
@@ -320,8 +331,7 @@ static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
                 * Necessary only once, but it does not really hurt.
                 */
                if (builtin_dispinfo == NULL) {
-                       builtin_dispinfo = talloc_zero(
-                               talloc_autofree_context(), struct disp_info);
+                       builtin_dispinfo = talloc_zero(NULL, struct disp_info);
                        if (builtin_dispinfo == NULL) {
                                return NULL;
                        }
@@ -336,8 +346,7 @@ static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
                 * Necessary only once, but it does not really hurt.
                 */
                if (domain_dispinfo == NULL) {
-                       domain_dispinfo = talloc_zero(
-                               talloc_autofree_context(), struct disp_info);
+                       domain_dispinfo = talloc_zero(NULL, struct disp_info);
                        if (domain_dispinfo == NULL) {
                                return NULL;
                        }
@@ -406,7 +415,7 @@ static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromno
                  (unsigned int)secs_fromnow ));
 
        disp_info->cache_timeout_event = event_add_timed(
-               smbd_event_context(), NULL,
+               server_event_context(), NULL,
                timeval_current_ofs(secs_fromnow, 0),
                disp_info_cache_idle_timeout_handler, (void *)disp_info);
 }
@@ -516,7 +525,7 @@ static uint32 count_sam_aliases(struct disp_info *info)
  _samr_Close
  ********************************************************************/
 
-NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
+NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
 {
        if (!close_policy_hnd(p, r->in.handle)) {
                return NT_STATUS_INVALID_HANDLE;
@@ -531,18 +540,17 @@ NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
  _samr_OpenDomain
  ********************************************************************/
 
-NTSTATUS _samr_OpenDomain(pipes_struct *p,
+NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
                          struct samr_OpenDomain *r)
 {
        struct samr_connect_info *cinfo;
        struct samr_domain_info *dinfo;
-       SEC_DESC *psd = NULL;
+       struct security_descriptor *psd = NULL;
        uint32    acc_granted;
        uint32    des_access = r->in.access_mask;
        NTSTATUS  status;
        size_t    sd_size;
        uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
-       SE_PRIV se_rights;
 
        /* find the connection policy handle. */
 
@@ -560,18 +568,11 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
        make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
        se_map_generic( &des_access, &dom_generic_mapping );
 
-       /*
-        * Users with SeMachineAccount or SeAddUser get additional
-        * SAMR_DOMAIN_ACCESS_CREATE_USER access.
-        */
-       se_priv_copy( &se_rights, &se_machine_account );
-       se_priv_add( &se_rights, &se_add_users );
-
        /*
         * Users with SeAddUser get the ability to manipulate groups
         * and aliases.
         */
-       if (user_has_any_privilege(p->server_info->ptok, &se_add_users)) {
+       if (security_token_has_privilege(p->server_info->ptok, SEC_PRIV_ADD_USERS)) {
                extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
                                SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
                                SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
@@ -579,9 +580,15 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
                                SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
        }
 
+       /*
+        * Users with SeMachineAccount or SeAddUser get additional
+        * SAMR_DOMAIN_ACCESS_CREATE_USER access.
+        */
+
        status = access_check_object( psd, p->server_info->ptok,
-               &se_rights, extra_access, des_access,
-               &acc_granted, "_samr_OpenDomain" );
+                                     SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
+                                     extra_access, des_access,
+                                     &acc_granted, "_samr_OpenDomain" );
 
        if ( !NT_STATUS_IS_OK(status) )
                return status;
@@ -608,7 +615,7 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
  _samr_GetUserPwInfo
  ********************************************************************/
 
-NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
+NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
                             struct samr_GetUserPwInfo *r)
 {
        struct samr_user_info *uinfo;
@@ -668,12 +675,12 @@ NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
  _samr_SetSecurity
  ********************************************************************/
 
-NTSTATUS _samr_SetSecurity(pipes_struct *p,
+NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
                           struct samr_SetSecurity *r)
 {
        struct samr_user_info *uinfo;
        uint32 i;
-       SEC_ACL *dacl;
+       struct security_acl *dacl;
        bool ret;
        struct samu *sampass=NULL;
        NTSTATUS status;
@@ -704,7 +711,7 @@ NTSTATUS _samr_SetSecurity(pipes_struct *p,
 
        dacl = r->in.sdbuf->sd->dacl;
        for (i=0; i < dacl->num_aces; i++) {
-               if (sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
+               if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
                        ret = pdb_set_pass_can_change(sampass,
                                (dacl->aces[i].access_mask &
                                 SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
@@ -730,7 +737,7 @@ NTSTATUS _samr_SetSecurity(pipes_struct *p,
 /*******************************************************************
   build correct perms based on policies and password times for _samr_query_sec_obj
 *******************************************************************/
-static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
+static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
 {
        struct samu *sampass=NULL;
        bool ret;
@@ -765,7 +772,7 @@ static bool check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
  _samr_QuerySecurity
  ********************************************************************/
 
-NTSTATUS _samr_QuerySecurity(pipes_struct *p,
+NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
                             struct samr_QuerySecurity *r)
 {
        struct samr_connect_info *cinfo;
@@ -774,11 +781,11 @@ NTSTATUS _samr_QuerySecurity(pipes_struct *p,
        struct samr_group_info *ginfo;
        struct samr_alias_info *ainfo;
        NTSTATUS status;
-       SEC_DESC * psd = NULL;
+       struct security_descriptor * psd = NULL;
        size_t sd_size = 0;
 
        cinfo = policy_handle_find(p, r->in.handle,
-                                  STD_RIGHT_READ_CONTROL_ACCESS, NULL,
+                                  SEC_STD_READ_CONTROL, NULL,
                                   struct samr_connect_info, &status);
        if (NT_STATUS_IS_OK(status)) {
                DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
@@ -788,7 +795,7 @@ NTSTATUS _samr_QuerySecurity(pipes_struct *p,
        }
 
        dinfo = policy_handle_find(p, r->in.handle,
-                                  STD_RIGHT_READ_CONTROL_ACCESS, NULL,
+                                  SEC_STD_READ_CONTROL, NULL,
                                   struct samr_domain_info, &status);
        if (NT_STATUS_IS_OK(status)) {
                DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
@@ -803,7 +810,7 @@ NTSTATUS _samr_QuerySecurity(pipes_struct *p,
        }
 
        uinfo = policy_handle_find(p, r->in.handle,
-                                  STD_RIGHT_READ_CONTROL_ACCESS, NULL,
+                                  SEC_STD_READ_CONTROL, NULL,
                                   struct samr_user_info, &status);
        if (NT_STATUS_IS_OK(status)) {
                DEBUG(10,("_samr_QuerySecurity: querying security on user "
@@ -824,7 +831,7 @@ NTSTATUS _samr_QuerySecurity(pipes_struct *p,
        }
 
        ginfo = policy_handle_find(p, r->in.handle,
-                                  STD_RIGHT_READ_CONTROL_ACCESS, NULL,
+                                  SEC_STD_READ_CONTROL, NULL,
                                   struct samr_group_info, &status);
        if (NT_STATUS_IS_OK(status)) {
                /*
@@ -842,7 +849,7 @@ NTSTATUS _samr_QuerySecurity(pipes_struct *p,
        }
 
        ainfo = policy_handle_find(p, r->in.handle,
-                                  STD_RIGHT_READ_CONTROL_ACCESS, NULL,
+                                  SEC_STD_READ_CONTROL, NULL,
                                   struct samr_alias_info, &status);
        if (NT_STATUS_IS_OK(status)) {
                /*
@@ -921,7 +928,7 @@ static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
  _samr_EnumDomainUsers
  ********************************************************************/
 
-NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
+NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
                               struct samr_EnumDomainUsers *r)
 {
        NTSTATUS status;
@@ -1060,7 +1067,7 @@ static void make_group_sam_entry_list(TALLOC_CTX *ctx,
  _samr_EnumDomainGroups
  ********************************************************************/
 
-NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
+NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
                                struct samr_EnumDomainGroups *r)
 {
        NTSTATUS status;
@@ -1137,7 +1144,7 @@ NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
  _samr_EnumDomainAliases
  ********************************************************************/
 
-NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
+NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
                                 struct samr_EnumDomainAliases *r)
 {
        NTSTATUS status;
@@ -1404,7 +1411,7 @@ static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
  _samr_QueryDisplayInfo
  ********************************************************************/
 
-NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
+NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
                                struct samr_QueryDisplayInfo *r)
 {
        NTSTATUS status;
@@ -1617,7 +1624,7 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
  _samr_QueryDisplayInfo2
 ****************************************************************/
 
-NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
+NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
                                 struct samr_QueryDisplayInfo2 *r)
 {
        struct samr_QueryDisplayInfo q;
@@ -1639,7 +1646,7 @@ NTSTATUS _samr_QueryDisplayInfo2(pipes_struct *p,
  _samr_QueryDisplayInfo3
 ****************************************************************/
 
-NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
+NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
                                 struct samr_QueryDisplayInfo3 *r)
 {
        struct samr_QueryDisplayInfo q;
@@ -1661,7 +1668,7 @@ NTSTATUS _samr_QueryDisplayInfo3(pipes_struct *p,
  _samr_QueryAliasInfo
  ********************************************************************/
 
-NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
+NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
                              struct samr_QueryAliasInfo *r)
 {
        struct samr_alias_info *ainfo;
@@ -1723,7 +1730,7 @@ NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
  _samr_LookupNames
  ********************************************************************/
 
-NTSTATUS _samr_LookupNames(pipes_struct *p,
+NTSTATUS _samr_LookupNames(struct pipes_struct *p,
                           struct samr_LookupNames *r)
 {
        struct samr_domain_info *dinfo;
@@ -1793,7 +1800,11 @@ NTSTATUS _samr_LookupNames(pipes_struct *p,
        rids.ids = rid;
 
        types.count = num_rids;
-       types.ids = type;
+       types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
+       NT_STATUS_HAVE_NO_MEMORY(type);
+       for (i = 0; i < num_rids; i++) {
+               types.ids[i] = (type[i] & 0xffffffff);
+       }
 
        *r->out.rids = rids;
        *r->out.types = types;
@@ -1807,7 +1818,7 @@ NTSTATUS _samr_LookupNames(pipes_struct *p,
  _samr_ChangePasswordUser
 ****************************************************************/
 
-NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
+NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
                                  struct samr_ChangePasswordUser *r)
 {
        NTSTATUS status;
@@ -1918,10 +1929,9 @@ NTSTATUS _samr_ChangePasswordUser(pipes_struct *p,
  _samr_ChangePasswordUser2
  ********************************************************************/
 
-NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
+NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
                                   struct samr_ChangePasswordUser2 *r)
 {
-       struct smbd_server_connection *sconn = smbd_server_conn;
        NTSTATUS status;
        fstring user_name;
        fstring wks;
@@ -1938,7 +1948,7 @@ NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
         * function.
         */
 
-       (void)map_username(sconn, user_name);
+       (void)map_username(user_name);
 
        /*
         * UNIX username case mangling not required, pass_oem_change
@@ -1946,6 +1956,7 @@ NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
         */
 
        status = pass_oem_change(user_name,
+                                p->client_id->name,
                                 r->in.lm_password->data,
                                 r->in.lm_verifier->hash,
                                 r->in.nt_password->data,
@@ -1965,10 +1976,9 @@ NTSTATUS _samr_ChangePasswordUser2(pipes_struct *p,
  _samr_OemChangePasswordUser2
 ****************************************************************/
 
-NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
+NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
                                      struct samr_OemChangePasswordUser2 *r)
 {
-       struct smbd_server_connection *sconn = smbd_server_conn;
        NTSTATUS status;
        fstring user_name;
        const char *wks = NULL;
@@ -1987,7 +1997,7 @@ NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
         * function.
         */
 
-       (void)map_username(sconn, user_name);
+       (void)map_username(user_name);
 
        /*
         * UNIX username case mangling not required, pass_oem_change
@@ -1999,6 +2009,7 @@ NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
        }
 
        status = pass_oem_change(user_name,
+                                p->client_id->name,
                                 r->in.password->data,
                                 r->in.hash->hash,
                                 0,
@@ -2018,10 +2029,9 @@ NTSTATUS _samr_OemChangePasswordUser2(pipes_struct *p,
  _samr_ChangePasswordUser3
  ********************************************************************/
 
-NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
+NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
                                   struct samr_ChangePasswordUser3 *r)
 {
-       struct smbd_server_connection *sconn = smbd_server_conn;
        NTSTATUS status;
        fstring user_name;
        const char *wks = NULL;
@@ -2044,7 +2054,7 @@ NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
         * function.
         */
 
-       (void)map_username(sconn, user_name);
+       (void)map_username(user_name);
 
        /*
         * UNIX username case mangling not required, pass_oem_change
@@ -2052,6 +2062,7 @@ NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
         */
 
        status = pass_oem_change(user_name,
+                                p->client_id->name,
                                 r->in.lm_password->data,
                                 r->in.lm_verifier->hash,
                                 r->in.nt_password->data,
@@ -2153,7 +2164,7 @@ static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
  _samr_LookupRids
  ********************************************************************/
 
-NTSTATUS _samr_LookupRids(pipes_struct *p,
+NTSTATUS _samr_LookupRids(struct pipes_struct *p,
                          struct samr_LookupRids *r)
 {
        struct samr_domain_info *dinfo;
@@ -2232,21 +2243,25 @@ NTSTATUS _samr_LookupRids(pipes_struct *p,
  _samr_OpenUser
 ********************************************************************/
 
-NTSTATUS _samr_OpenUser(pipes_struct *p,
+NTSTATUS _samr_OpenUser(struct pipes_struct *p,
                        struct samr_OpenUser *r)
 {
        struct samu *sampass=NULL;
-       DOM_SID sid;
+       struct dom_sid sid;
        struct samr_domain_info *dinfo;
        struct samr_user_info *uinfo;
-       SEC_DESC *psd = NULL;
+       struct security_descriptor *psd = NULL;
        uint32    acc_granted;
        uint32    des_access = r->in.access_mask;
        uint32_t extra_access = 0;
        size_t    sd_size;
        bool ret;
        NTSTATUS nt_status;
-       SE_PRIV se_rights;
+
+       /* These two privileges, if != SEC_PRIV_INVALID, indicate
+        * privileges that the user must have to complete this
+        * operation in defience of the fixed ACL */
+       enum sec_privilege needed_priv_1, needed_priv_2;
        NTSTATUS status;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
@@ -2283,8 +2298,8 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
        ret=pdb_getsampwsid(sampass, &sid);
        unbecome_root();
 
-       se_priv_copy(&se_rights, &se_priv_none);
-
+       needed_priv_1 = SEC_PRIV_INVALID;
+       needed_priv_2 = SEC_PRIV_INVALID;
        /*
         * We do the override access checks on *open*, not at
         * SetUserInfo time.
@@ -2292,37 +2307,27 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
        if (ret) {
                uint32_t acb_info = pdb_get_acct_ctrl(sampass);
 
-               if ((acb_info & ACB_WSTRUST) &&
-                               user_has_any_privilege(p->server_info->ptok,
-                                               &se_machine_account)) {
+               if (acb_info & ACB_WSTRUST) {
                        /*
                         * SeMachineAccount is needed to add
                         * GENERIC_RIGHTS_USER_WRITE to a machine
                         * account.
                         */
-                       se_priv_add(&se_rights, &se_machine_account);
-                       DEBUG(10,("_samr_OpenUser: adding machine account "
-                               "rights to handle for user %s\n",
-                               pdb_get_username(sampass) ));
+                       needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
                }
-               if ((acb_info & ACB_NORMAL) &&
-                               user_has_any_privilege(p->server_info->ptok,
-                                               &se_add_users)) {
+               if (acb_info & ACB_NORMAL) {
                        /*
                         * SeAddUsers is needed to add
                         * GENERIC_RIGHTS_USER_WRITE to a normal
                         * account.
                         */
-                       se_priv_add(&se_rights, &se_add_users);
-                       DEBUG(10,("_samr_OpenUser: adding add user "
-                               "rights to handle for user %s\n",
-                               pdb_get_username(sampass) ));
+                       needed_priv_1 = SEC_PRIV_ADD_USERS;
                }
                /*
-                * Cheat - allow GENERIC_RIGHTS_USER_WRITE if pipe user is
-                * in DOMAIN_RID_ADMINS. This is almost certainly not
-                * what Windows does but is a hack for people who haven't
-                * set up privileges on groups in Samba.
+                * Cheat - we have not set a specific privilege for
+                * server (BDC) or domain trust account, so allow
+                * GENERIC_RIGHTS_USER_WRITE if pipe user is in
+                * DOMAIN_RID_ADMINS.
                 */
                if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
                        if (lp_enable_privileges() && nt_token_check_domain_rid(p->server_info->ptok,
@@ -2339,8 +2344,9 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
        TALLOC_FREE(sampass);
 
        nt_status = access_check_object(psd, p->server_info->ptok,
-               &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
-               &acc_granted, "_samr_OpenUser");
+                                       needed_priv_1, needed_priv_2,
+                                       GENERIC_RIGHTS_USER_WRITE, des_access,
+                                       &acc_granted, "_samr_OpenUser");
 
        if ( !NT_STATUS_IS_OK(nt_status) )
                return nt_status;
@@ -2398,6 +2404,32 @@ static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
+/*************************************************************************
+ *************************************************************************/
+
+static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
+                                                      struct samu *pw)
+{
+       struct samr_LogonHours hours;
+       const int units_per_week = 168;
+
+       ZERO_STRUCT(hours);
+       hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
+       if (!hours.bits) {
+               return hours;
+       }
+
+       hours.units_per_week = units_per_week;
+       memset(hours.bits, 0xFF, units_per_week);
+
+       if (pdb_get_hours(pw)) {
+               memcpy(hours.bits, pdb_get_hours(pw),
+                      MIN(pdb_get_hours_len(pw), units_per_week));
+       }
+
+       return hours;
+}
+
 /*************************************************************************
  get_user_info_1.
  *************************************************************************/
@@ -2405,9 +2437,9 @@ static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
 static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
                                struct samr_UserInfo1 *r,
                                struct samu *pw,
-                               DOM_SID *domain_sid)
+                               struct dom_sid *domain_sid)
 {
-       const DOM_SID *sid_group;
+       const struct dom_sid *sid_group;
        uint32_t primary_gid;
 
        become_root();
@@ -2440,7 +2472,7 @@ static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
                                struct samu *pw)
 {
        r->comment.string               = talloc_strdup(mem_ctx, pdb_get_comment(pw));
-       r->unknown.string               = NULL;
+       r->reserved.string              = NULL;
        r->country_code                 = 0;
        r->code_page                    = 0;
 
@@ -2454,9 +2486,9 @@ static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
 static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
                                struct samr_UserInfo3 *r,
                                struct samu *pw,
-                               DOM_SID *domain_sid)
+                               struct dom_sid *domain_sid)
 {
-       const DOM_SID *sid_user, *sid_group;
+       const struct dom_sid *sid_user, *sid_group;
        uint32_t rid, primary_gid;
 
        sid_user = pdb_get_user_sid(pw);
@@ -2525,9 +2557,9 @@ static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
 static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
                                struct samr_UserInfo5 *r,
                                struct samu *pw,
-                               DOM_SID *domain_sid)
+                               struct dom_sid *domain_sid)
 {
-       const DOM_SID *sid_user, *sid_group;
+       const struct dom_sid *sid_user, *sid_group;
        uint32_t rid, primary_gid;
 
        sid_user = pdb_get_user_sid(pw);
@@ -2730,17 +2762,25 @@ static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
  user. JRA.
  *************************************************************************/
 
-static NTSTATUS get_user_info_18(pipes_struct *p,
+static NTSTATUS get_user_info_18(struct pipes_struct *p,
                                 TALLOC_CTX *mem_ctx,
                                 struct samr_UserInfo18 *r,
-                                DOM_SID *user_sid)
+                                struct dom_sid *user_sid)
 {
        struct samu *smbpass=NULL;
        bool ret;
+       const uint8_t *nt_pass = NULL;
+       const uint8_t *lm_pass = NULL;
 
        ZERO_STRUCTP(r);
 
-       if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
+       if (p->server_info->system) {
+               goto query;
+       }
+
+       if ((p->auth.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) ||
+           (p->auth.auth_type != DCERPC_AUTH_TYPE_KRB5) ||
+           (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO)) {
                return NT_STATUS_ACCESS_DENIED;
        }
 
@@ -2748,6 +2788,7 @@ static NTSTATUS get_user_info_18(pipes_struct *p,
                return NT_STATUS_ACCESS_DENIED;
        }
 
+ query:
        /*
         * Do *NOT* do become_root()/unbecome_root() here ! JRA.
         */
@@ -2771,10 +2812,17 @@ static NTSTATUS get_user_info_18(pipes_struct *p,
                return NT_STATUS_ACCOUNT_DISABLED;
        }
 
-       r->lm_pwd_active = true;
-       r->nt_pwd_active = true;
-       memcpy(r->lm_pwd.hash, pdb_get_lanman_passwd(smbpass), 16);
-       memcpy(r->nt_pwd.hash, pdb_get_nt_passwd(smbpass), 16);
+       lm_pass = pdb_get_lanman_passwd(smbpass);
+       if (lm_pass != NULL) {
+               memcpy(r->lm_pwd.hash, lm_pass, 16);
+               r->lm_pwd_active = true;
+       }
+
+       nt_pass = pdb_get_nt_passwd(smbpass);
+       if (nt_pass != NULL) {
+               memcpy(r->nt_pwd.hash, nt_pass, 16);
+               r->nt_pwd_active = true;
+       }
        r->password_expired = 0; /* FIXME */
 
        TALLOC_FREE(smbpass);
@@ -2827,11 +2875,11 @@ static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
                                 struct samr_UserInfo21 *r,
                                 struct samu *pw,
-                                DOM_SID *domain_sid,
+                                struct dom_sid *domain_sid,
                                 uint32_t acc_granted)
 {
        NTSTATUS status;
-       const DOM_SID *sid_user, *sid_group;
+       const struct dom_sid *sid_user, *sid_group;
        uint32_t rid, primary_gid;
        NTTIME force_password_change;
        time_t must_change_time;
@@ -2938,13 +2986,13 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
  _samr_QueryUserInfo
  ********************************************************************/
 
-NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
+NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
                             struct samr_QueryUserInfo *r)
 {
        NTSTATUS status;
        union samr_UserInfo *user_info = NULL;
        struct samr_user_info *uinfo;
-       DOM_SID domain_sid;
+       struct dom_sid domain_sid;
        uint32 rid;
        bool ret = false;
        struct samu *pwd = NULL;
@@ -3140,7 +3188,7 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
+NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
                              struct samr_QueryUserInfo2 *r)
 {
        struct samr_QueryUserInfo u;
@@ -3156,12 +3204,12 @@ NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
  _samr_GetGroupsForUser
  ********************************************************************/
 
-NTSTATUS _samr_GetGroupsForUser(pipes_struct *p,
+NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
                                struct samr_GetGroupsForUser *r)
 {
        struct samr_user_info *uinfo;
        struct samu *sam_pass=NULL;
-       DOM_SID *sids;
+       struct dom_sid *sids;
        struct samr_RidWithAttribute dom_gid;
        struct samr_RidWithAttribute *gids = NULL;
        uint32 primary_group_rid;
@@ -3372,7 +3420,7 @@ static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
        r->primary.string               = global_myname();
        r->sequence_num                 = seq_num;
        r->domain_server_state          = DOMAIN_SERVER_ENABLED;
-       r->role                         = samr_get_server_role();
+       r->role                         = (enum samr_Role) samr_get_server_role();
        r->unknown3                     = 1;
 
        return NT_STATUS_OK;
@@ -3447,7 +3495,7 @@ static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
 static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
                                 struct samr_DomInfo7 *r)
 {
-       r->role = samr_get_server_role();
+       r->role = (enum samr_Role) samr_get_server_role();
 
        return NT_STATUS_OK;
 }
@@ -3597,7 +3645,7 @@ static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
  _samr_QueryDomainInfo
  ********************************************************************/
 
-NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
+NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
                               struct samr_QueryDomainInfo *r)
 {
        NTSTATUS status = NT_STATUS_OK;
@@ -3743,22 +3791,24 @@ static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
  _samr_CreateUser2
  ********************************************************************/
 
-NTSTATUS _samr_CreateUser2(pipes_struct *p,
+NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
                           struct samr_CreateUser2 *r)
 {
        const char *account = NULL;
-       DOM_SID sid;
+       struct dom_sid sid;
        uint32_t acb_info = r->in.acct_flags;
        struct samr_domain_info *dinfo;
        struct samr_user_info *uinfo;
        NTSTATUS nt_status;
        uint32 acc_granted;
-       SEC_DESC *psd;
+       struct security_descriptor *psd;
        size_t    sd_size;
        /* check this, when giving away 'add computer to domain' privs */
        uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
        bool can_add_account = False;
-       SE_PRIV se_rights;
+
+       /* Which privilege is needed to override the ACL? */
+       enum sec_privilege needed_priv = SEC_PRIV_INVALID;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
                                   SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
@@ -3792,24 +3842,20 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
        /* determine which user right we need to check based on the acb_info */
 
        if (geteuid() == sec_initial_uid()) {
-               se_priv_copy(&se_rights, &se_priv_none);
                can_add_account = true;
        } else if (acb_info & ACB_WSTRUST) {
-               se_priv_copy(&se_rights, &se_machine_account);
-               can_add_account = user_has_privileges(
-                       p->server_info->ptok, &se_rights );
+               needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
+               can_add_account = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_MACHINE_ACCOUNT);
        } else if (acb_info & ACB_NORMAL &&
                  (account[strlen(account)-1] != '$')) {
                /* usrmgr.exe (and net rpc trustdom grant) creates a normal user
                   account for domain trusts and changes the ACB flags later */
-               se_priv_copy(&se_rights, &se_add_users);
-               can_add_account = user_has_privileges(
-                       p->server_info->ptok, &se_rights );
+               needed_priv = SEC_PRIV_ADD_USERS;
+               can_add_account = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_ADD_USERS);
        } else if (lp_enable_privileges()) {
                /* implicit assumption of a BDC or domain trust account here
                 * (we already check the flags earlier) */
                /* only Domain Admins can add a BDC or domain trust */
-               se_priv_copy(&se_rights, &se_priv_none);
                can_add_account = nt_token_check_domain_rid(
                        p->server_info->ptok,
                        DOMAIN_RID_ADMINS );
@@ -3857,7 +3903,8 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
         */
 
        nt_status = access_check_object(psd, p->server_info->ptok,
-               &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
+                                       needed_priv, SEC_PRIV_INVALID,
+                                       GENERIC_RIGHTS_USER_WRITE, des_access,
                &acc_granted, "_samr_CreateUser2");
 
        if ( !NT_STATUS_IS_OK(nt_status) ) {
@@ -3882,7 +3929,7 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_CreateUser(pipes_struct *p,
+NTSTATUS _samr_CreateUser(struct pipes_struct *p,
                          struct samr_CreateUser *r)
 {
        struct samr_CreateUser2 c;
@@ -3903,7 +3950,7 @@ NTSTATUS _samr_CreateUser(pipes_struct *p,
  _samr_Connect
  ********************************************************************/
 
-NTSTATUS _samr_Connect(pipes_struct *p,
+NTSTATUS _samr_Connect(struct pipes_struct *p,
                       struct samr_Connect *r)
 {
        struct samr_connect_info *info;
@@ -3949,19 +3996,19 @@ NTSTATUS _samr_Connect(pipes_struct *p,
  _samr_Connect2
  ********************************************************************/
 
-NTSTATUS _samr_Connect2(pipes_struct *p,
+NTSTATUS _samr_Connect2(struct pipes_struct *p,
                        struct samr_Connect2 *r)
 {
        struct samr_connect_info *info = NULL;
        struct policy_handle hnd;
-       SEC_DESC *psd = NULL;
+       struct security_descriptor *psd = NULL;
        uint32    acc_granted;
        uint32    des_access = r->in.access_mask;
        NTSTATUS  nt_status;
        size_t    sd_size;
        const char *fn = "_samr_Connect2";
 
-       switch (p->hdr_req.opnum) {
+       switch (p->opnum) {
        case NDR_SAMR_CONNECT2:
                fn = "_samr_Connect2";
                break;
@@ -3993,7 +4040,8 @@ NTSTATUS _samr_Connect2(pipes_struct *p,
        se_map_generic(&des_access, &sam_generic_mapping);
 
        nt_status = access_check_object(psd, p->server_info->ptok,
-               NULL, 0, des_access, &acc_granted, fn);
+                                       SEC_PRIV_INVALID, SEC_PRIV_INVALID,
+                                       0, des_access, &acc_granted, fn);
 
        if ( !NT_STATUS_IS_OK(nt_status) )
                return nt_status;
@@ -4014,7 +4062,7 @@ NTSTATUS _samr_Connect2(pipes_struct *p,
  _samr_Connect3
 ****************************************************************/
 
-NTSTATUS _samr_Connect3(pipes_struct *p,
+NTSTATUS _samr_Connect3(struct pipes_struct *p,
                        struct samr_Connect3 *r)
 {
        struct samr_Connect2 c;
@@ -4030,7 +4078,7 @@ NTSTATUS _samr_Connect3(pipes_struct *p,
  _samr_Connect4
  ********************************************************************/
 
-NTSTATUS _samr_Connect4(pipes_struct *p,
+NTSTATUS _samr_Connect4(struct pipes_struct *p,
                        struct samr_Connect4 *r)
 {
        struct samr_Connect2 c;
@@ -4046,7 +4094,7 @@ NTSTATUS _samr_Connect4(pipes_struct *p,
  _samr_Connect5
  ********************************************************************/
 
-NTSTATUS _samr_Connect5(pipes_struct *p,
+NTSTATUS _samr_Connect5(struct pipes_struct *p,
                        struct samr_Connect5 *r)
 {
        NTSTATUS status;
@@ -4076,13 +4124,13 @@ NTSTATUS _samr_Connect5(pipes_struct *p,
  _samr_LookupDomain
  **********************************************************************/
 
-NTSTATUS _samr_LookupDomain(pipes_struct *p,
+NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
                            struct samr_LookupDomain *r)
 {
        NTSTATUS status;
        struct samr_connect_info *info;
        const char *domain_name;
-       DOM_SID *sid = NULL;
+       struct dom_sid *sid = NULL;
 
        /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
           Reverted that change so we will work with RAS servers again */
@@ -4125,7 +4173,7 @@ NTSTATUS _samr_LookupDomain(pipes_struct *p,
  _samr_EnumDomains
  **********************************************************************/
 
-NTSTATUS _samr_EnumDomains(pipes_struct *p,
+NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
                           struct samr_EnumDomains *r)
 {
        NTSTATUS status;
@@ -4172,19 +4220,18 @@ NTSTATUS _samr_EnumDomains(pipes_struct *p,
  _samr_OpenAlias
  ********************************************************************/
 
-NTSTATUS _samr_OpenAlias(pipes_struct *p,
+NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
                         struct samr_OpenAlias *r)
 {
-       DOM_SID sid;
+       struct dom_sid sid;
        uint32 alias_rid = r->in.rid;
        struct samr_alias_info *ainfo;
        struct samr_domain_info *dinfo;
-       SEC_DESC *psd = NULL;
+       struct security_descriptor *psd = NULL;
        uint32    acc_granted;
        uint32    des_access = r->in.access_mask;
        size_t    sd_size;
        NTSTATUS  status;
-       SE_PRIV se_rights;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
                                   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
@@ -4207,11 +4254,10 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
        se_map_generic(&des_access,&ali_generic_mapping);
 
-       se_priv_copy( &se_rights, &se_add_users );
-
        status = access_check_object(psd, p->server_info->ptok,
-               &se_rights, GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
-               des_access, &acc_granted, "_samr_OpenAlias");
+                                    SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
+                                    GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
+                                    des_access, &acc_granted, "_samr_OpenAlias");
 
        if ( !NT_STATUS_IS_OK(status) )
                return status;
@@ -4703,6 +4749,7 @@ static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
 
 static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
                                 struct samr_UserInfo23 *id23,
+                                const char *rhost,
                                 struct samu *pwd)
 {
        char *plaintext_buf = NULL;
@@ -4765,7 +4812,8 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
                                DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
                        }
 
-                       if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
+                       if(!chgpasswd(pdb_get_username(pwd), rhost,
+                                     passwd, "", plaintext_buf, True)) {
                                return NT_STATUS_ACCESS_DENIED;
                        }
                        TALLOC_FREE(passwd);
@@ -4793,7 +4841,7 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
  set_user_info_pw
  ********************************************************************/
 
-static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
+static bool set_user_info_pw(uint8 *pass, const char *rhost, struct samu *pwd)
 {
        size_t len = 0;
        char *plaintext_buf = NULL;
@@ -4836,7 +4884,8 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
                                DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
                        }
 
-                       if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
+                       if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
+                                     "", plaintext_buf, True)) {
                                return False;
                        }
                        TALLOC_FREE(passwd);
@@ -4855,6 +4904,7 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
  ********************************************************************/
 
 static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
+                                const char *rhost,
                                 struct samr_UserInfo24 *id24,
                                 struct samu *pwd)
 {
@@ -4865,7 +4915,7 @@ static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (!set_user_info_pw(id24->password.data, pwd)) {
+       if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
                return NT_STATUS_WRONG_PASSWORD;
        }
 
@@ -4884,6 +4934,7 @@ static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
  ********************************************************************/
 
 static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
+                                const char *rhost,
                                 struct samr_UserInfo25 *id25,
                                 struct samu *pwd)
 {
@@ -4905,7 +4956,7 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
        if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
            (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
 
-               if (!set_user_info_pw(id25->password.data, pwd)) {
+               if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
                        return NT_STATUS_WRONG_PASSWORD;
                }
        }
@@ -4940,6 +4991,7 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
  ********************************************************************/
 
 static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
+                                const char *rhost,
                                 struct samr_UserInfo26 *id26,
                                 struct samu *pwd)
 {
@@ -4950,7 +5002,7 @@ static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (!set_user_info_pw(id26->password.data, pwd)) {
+       if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
                return NT_STATUS_WRONG_PASSWORD;
        }
 
@@ -5036,7 +5088,7 @@ static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
  samr_SetUserInfo
  ********************************************************************/
 
-NTSTATUS _samr_SetUserInfo(pipes_struct *p,
+NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
                           struct samr_SetUserInfo *r)
 {
        struct samr_user_info *uinfo;
@@ -5226,7 +5278,9 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
                        dump_data(100, info->info23.password.data, 516);
 
                        status = set_user_info_23(p->mem_ctx,
-                                                 &info->info23, pwd);
+                                                 &info->info23,
+                                                 p->client_id->name,
+                                                 pwd);
                        break;
 
                case 24:
@@ -5240,6 +5294,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
                        dump_data(100, info->info24.password.data, 516);
 
                        status = set_user_info_24(p->mem_ctx,
+                                                 p->client_id->name,
                                                  &info->info24, pwd);
                        break;
 
@@ -5254,6 +5309,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
                        dump_data(100, info->info25.password.data, 532);
 
                        status = set_user_info_25(p->mem_ctx,
+                                                 p->client_id->name,
                                                  &info->info25, pwd);
                        break;
 
@@ -5268,6 +5324,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
                        dump_data(100, info->info26.password.data, 516);
 
                        status = set_user_info_26(p->mem_ctx,
+                                                 p->client_id->name,
                                                  &info->info26, pwd);
                        break;
 
@@ -5292,7 +5349,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
  _samr_SetUserInfo2
  ********************************************************************/
 
-NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
+NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
                            struct samr_SetUserInfo2 *r)
 {
        struct samr_SetUserInfo q;
@@ -5308,7 +5365,7 @@ NTSTATUS _samr_SetUserInfo2(pipes_struct *p,
  _samr_GetAliasMembership
 *********************************************************************/
 
-NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
+NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
                                  struct samr_GetAliasMembership *r)
 {
        size_t num_alias_rids;
@@ -5318,7 +5375,7 @@ NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
 
        NTSTATUS status;
 
-       DOM_SID *members;
+       struct dom_sid *members;
 
        DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
 
@@ -5335,7 +5392,7 @@ NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
                return NT_STATUS_OBJECT_TYPE_MISMATCH;
 
        if (r->in.sids->num_sids) {
-               members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, r->in.sids->num_sids);
+               members = TALLOC_ARRAY(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
 
                if (members == NULL)
                        return NT_STATUS_NO_MEMORY;
@@ -5377,7 +5434,7 @@ NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
  _samr_GetMembersInAlias
 *********************************************************************/
 
-NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
+NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
                                 struct samr_GetMembersInAlias *r)
 {
        struct samr_alias_info *ainfo;
@@ -5385,7 +5442,7 @@ NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
        size_t i;
        size_t num_sids = 0;
        struct lsa_SidPtr *sids = NULL;
-       DOM_SID *pdb_sids = NULL;
+       struct dom_sid *pdb_sids = NULL;
 
        ainfo = policy_handle_find(p, r->in.alias_handle,
                                   SAMR_ALIAS_ACCESS_GET_MEMBERS, NULL,
@@ -5414,7 +5471,7 @@ NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
        }
 
        for (i = 0; i < num_sids; i++) {
-               sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]);
+               sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
                if (!sids[i].sid) {
                        TALLOC_FREE(pdb_sids);
                        return NT_STATUS_NO_MEMORY;
@@ -5433,7 +5490,7 @@ NTSTATUS _samr_GetMembersInAlias(pipes_struct *p,
  _samr_QueryGroupMember
 *********************************************************************/
 
-NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
+NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
                                struct samr_QueryGroupMember *r)
 {
        struct samr_group_info *ginfo;
@@ -5443,7 +5500,7 @@ NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
        uint32 *attr=NULL;
 
        NTSTATUS status;
-       struct samr_RidTypeArray *rids = NULL;
+       struct samr_RidAttrArray *rids = NULL;
 
        ginfo = policy_handle_find(p, r->in.group_handle,
                                   SAMR_GROUP_ACCESS_GET_MEMBERS, NULL,
@@ -5452,7 +5509,7 @@ NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
                return status;
        }
 
-       rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidTypeArray);
+       rids = TALLOC_ZERO_P(p->mem_ctx, struct samr_RidAttrArray);
        if (!rids) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -5484,11 +5541,14 @@ NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
                attr = NULL;
        }
 
-       for (i=0; i<num_members; i++)
-               attr[i] = SID_NAME_USER;
+       for (i=0; i<num_members; i++) {
+               attr[i] = SE_GROUP_MANDATORY |
+                         SE_GROUP_ENABLED_BY_DEFAULT |
+                         SE_GROUP_ENABLED;
+       }
 
        rids->count = num_members;
-       rids->types = attr;
+       rids->attributes = attr;
        rids->rids = rid;
 
        *r->out.rids = rids;
@@ -5500,7 +5560,7 @@ NTSTATUS _samr_QueryGroupMember(pipes_struct *p,
  _samr_AddAliasMember
 *********************************************************************/
 
-NTSTATUS _samr_AddAliasMember(pipes_struct *p,
+NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
                              struct samr_AddAliasMember *r)
 {
        struct samr_alias_info *ainfo;
@@ -5534,7 +5594,7 @@ NTSTATUS _samr_AddAliasMember(pipes_struct *p,
  _samr_DeleteAliasMember
 *********************************************************************/
 
-NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
+NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
                                 struct samr_DeleteAliasMember *r)
 {
        struct samr_alias_info *ainfo;
@@ -5569,7 +5629,7 @@ NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
  _samr_AddGroupMember
 *********************************************************************/
 
-NTSTATUS _samr_AddGroupMember(pipes_struct *p,
+NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
                              struct samr_AddGroupMember *r)
 {
        struct samr_group_info *ginfo;
@@ -5607,7 +5667,7 @@ NTSTATUS _samr_AddGroupMember(pipes_struct *p,
  _samr_DeleteGroupMember
 *********************************************************************/
 
-NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
+NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
                                 struct samr_DeleteGroupMember *r)
 
 {
@@ -5650,7 +5710,7 @@ NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
  _samr_DeleteUser
 *********************************************************************/
 
-NTSTATUS _samr_DeleteUser(pipes_struct *p,
+NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
                          struct samr_DeleteUser *r)
 {
        struct samr_user_info *uinfo;
@@ -5661,7 +5721,7 @@ NTSTATUS _samr_DeleteUser(pipes_struct *p,
        DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
 
        uinfo = policy_handle_find(p, r->in.user_handle,
-                                  STD_RIGHT_DELETE_ACCESS, NULL,
+                                  SEC_STD_DELETE, NULL,
                                   struct samr_user_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -5719,7 +5779,7 @@ NTSTATUS _samr_DeleteUser(pipes_struct *p,
  _samr_DeleteDomainGroup
 *********************************************************************/
 
-NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
+NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
                                 struct samr_DeleteDomainGroup *r)
 {
        struct samr_group_info *ginfo;
@@ -5729,7 +5789,7 @@ NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
        DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
 
        ginfo = policy_handle_find(p, r->in.group_handle,
-                                  STD_RIGHT_DELETE_ACCESS, NULL,
+                                  SEC_STD_DELETE, NULL,
                                   struct samr_group_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -5770,7 +5830,7 @@ NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
  _samr_DeleteDomAlias
 *********************************************************************/
 
-NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
+NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
                              struct samr_DeleteDomAlias *r)
 {
        struct samr_alias_info *ainfo;
@@ -5779,7 +5839,7 @@ NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
        DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
 
        ainfo = policy_handle_find(p, r->in.alias_handle,
-                                  STD_RIGHT_DELETE_ACCESS, NULL,
+                                  SEC_STD_DELETE, NULL,
                                   struct samr_alias_info, &status);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -5822,7 +5882,7 @@ NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
  _samr_CreateDomainGroup
 *********************************************************************/
 
-NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
+NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
                                 struct samr_CreateDomainGroup *r)
 
 {
@@ -5883,10 +5943,10 @@ NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
  _samr_CreateDomAlias
 *********************************************************************/
 
-NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
+NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
                              struct samr_CreateDomAlias *r)
 {
-       DOM_SID info_sid;
+       struct dom_sid info_sid;
        const char *name = NULL;
        struct samr_domain_info *dinfo;
        struct samr_alias_info *ainfo;
@@ -5957,7 +6017,7 @@ NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
  _samr_QueryGroupInfo
 *********************************************************************/
 
-NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
+NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
                              struct samr_QueryGroupInfo *r)
 {
        struct samr_group_info *ginfo;
@@ -6060,7 +6120,7 @@ NTSTATUS _samr_QueryGroupInfo(pipes_struct *p,
  _samr_SetGroupInfo
 *********************************************************************/
 
-NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
+NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
                            struct samr_SetGroupInfo *r)
 {
        struct samr_group_info *ginfo;
@@ -6113,7 +6173,7 @@ NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
  _samr_SetAliasInfo
 *********************************************************************/
 
-NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
+NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
                            struct samr_SetAliasInfo *r)
 {
        struct samr_alias_info *ainfo;
@@ -6202,7 +6262,7 @@ NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
  _samr_GetDomPwInfo
 ****************************************************************/
 
-NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
+NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
                            struct samr_GetDomPwInfo *r)
 {
        uint32_t min_password_length = 0;
@@ -6238,21 +6298,20 @@ NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
  _samr_OpenGroup
 *********************************************************************/
 
-NTSTATUS _samr_OpenGroup(pipes_struct *p,
+NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
                         struct samr_OpenGroup *r)
 
 {
-       DOM_SID info_sid;
+       struct dom_sid info_sid;
        GROUP_MAP map;
        struct samr_domain_info *dinfo;
        struct samr_group_info *ginfo;
-       SEC_DESC         *psd = NULL;
+       struct security_descriptor         *psd = NULL;
        uint32            acc_granted;
        uint32            des_access = r->in.access_mask;
        size_t            sd_size;
        NTSTATUS          status;
        bool ret;
-       SE_PRIV se_rights;
 
        dinfo = policy_handle_find(p, r->in.domain_handle,
                                   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
@@ -6269,11 +6328,9 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p,
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
        se_map_generic(&des_access,&grp_generic_mapping);
 
-       se_priv_copy( &se_rights, &se_add_users );
-
        status = access_check_object(psd, p->server_info->ptok,
-               &se_rights, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
-               des_access, &acc_granted, "_samr_OpenGroup");
+                                    SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
+                                    des_access, &acc_granted, "_samr_OpenGroup");
 
        if ( !NT_STATUS_IS_OK(status) )
                return status;
@@ -6311,7 +6368,7 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p,
  _samr_RemoveMemberFromForeignDomain
 *********************************************************************/
 
-NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
+NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
                                             struct samr_RemoveMemberFromForeignDomain *r)
 {
        struct samr_domain_info *dinfo;
@@ -6366,7 +6423,7 @@ NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
  _samr_QueryDomainInfo2
  ********************************************************************/
 
-NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
+NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
                                struct samr_QueryDomainInfo2 *r)
 {
        struct samr_QueryDomainInfo q;
@@ -6444,7 +6501,7 @@ static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
  _samr_SetDomainInfo
  ********************************************************************/
 
-NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
+NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
                             struct samr_SetDomainInfo *r)
 {
        struct samr_domain_info *dinfo;
@@ -6518,7 +6575,7 @@ NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
  _samr_GetDisplayEnumerationIndex
 ****************************************************************/
 
-NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
+NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
                                          struct samr_GetDisplayEnumerationIndex *r)
 {
        struct samr_domain_info *dinfo;
@@ -6644,7 +6701,7 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
  _samr_GetDisplayEnumerationIndex2
 ****************************************************************/
 
-NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
+NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
                                           struct samr_GetDisplayEnumerationIndex2 *r)
 {
        struct samr_GetDisplayEnumerationIndex q;
@@ -6662,7 +6719,7 @@ NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p,
  _samr_RidToSid
 ****************************************************************/
 
-NTSTATUS _samr_RidToSid(pipes_struct *p,
+NTSTATUS _samr_RidToSid(struct pipes_struct *p,
                        struct samr_RidToSid *r)
 {
        struct samr_domain_info *dinfo;
@@ -6680,7 +6737,7 @@ NTSTATUS _samr_RidToSid(pipes_struct *p,
                return NT_STATUS_NO_MEMORY;
        }
 
-       *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid);
+       *r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
        if (!*r->out.sid) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -6752,7 +6809,7 @@ static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ct
  _samr_ValidatePassword
 ****************************************************************/
 
-NTSTATUS _samr_ValidatePassword(pipes_struct *p,
+NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
                                struct samr_ValidatePassword *r)
 {
        union samr_ValidatePasswordRep *rep;
@@ -6811,7 +6868,7 @@ NTSTATUS _samr_ValidatePassword(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_Shutdown(pipes_struct *p,
+NTSTATUS _samr_Shutdown(struct pipes_struct *p,
                        struct samr_Shutdown *r)
 {
        p->rng_fault_state = true;
@@ -6821,7 +6878,7 @@ NTSTATUS _samr_Shutdown(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
+NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
                                          struct samr_SetMemberAttributesOfGroup *r)
 {
        p->rng_fault_state = true;
@@ -6831,7 +6888,7 @@ NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
+NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
                                          struct samr_TestPrivateFunctionsDomain *r)
 {
        return NT_STATUS_NOT_IMPLEMENTED;
@@ -6840,7 +6897,7 @@ NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
+NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
                                        struct samr_TestPrivateFunctionsUser *r)
 {
        return NT_STATUS_NOT_IMPLEMENTED;
@@ -6849,7 +6906,7 @@ NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
+NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
                                         struct samr_AddMultipleMembersToAlias *r)
 {
        p->rng_fault_state = true;
@@ -6859,7 +6916,7 @@ NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
+NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
                                              struct samr_RemoveMultipleMembersFromAlias *r)
 {
        p->rng_fault_state = true;
@@ -6869,7 +6926,7 @@ NTSTATUS _samr_RemoveMultipleMembersFromAlias(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
+NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
                                     struct samr_SetBootKeyInformation *r)
 {
        p->rng_fault_state = true;
@@ -6879,7 +6936,7 @@ NTSTATUS _samr_SetBootKeyInformation(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
+NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
                                     struct samr_GetBootKeyInformation *r)
 {
        p->rng_fault_state = true;
@@ -6889,7 +6946,7 @@ NTSTATUS _samr_GetBootKeyInformation(pipes_struct *p,
 /****************************************************************
 ****************************************************************/
 
-NTSTATUS _samr_SetDsrmPassword(pipes_struct *p,
+NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
                               struct samr_SetDsrmPassword *r)
 {
        p->rng_fault_state = true;