LCOV - code coverage report
Current view: top level - source3/rpc_server/samr - srv_samr_nt.c (source / functions) Hit Total Coverage
Test: coverage report for support-claim-type-attributes 6b5c566e Lines: 2624 3618 72.5 %
Date: 2023-11-21 12:31:41 Functions: 149 161 92.5 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines
       4             :  *  Copyright (C) Andrew Tridgell                   1992-1997,
       5             :  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
       6             :  *  Copyright (C) Paul Ashton                       1997,
       7             :  *  Copyright (C) Marc Jacobsen                     1999,
       8             :  *  Copyright (C) Jeremy Allison                    2001-2008,
       9             :  *  Copyright (C) Jean François Micouleau           1998-2001,
      10             :  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
      11             :  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
      12             :  *  Copyright (C) Simo Sorce                        2003.
      13             :  *  Copyright (C) Volker Lendecke                   2005.
      14             :  *  Copyright (C) Guenther Deschner                 2008.
      15             :  *
      16             :  *  This program is free software; you can redistribute it and/or modify
      17             :  *  it under the terms of the GNU General Public License as published by
      18             :  *  the Free Software Foundation; either version 3 of the License, or
      19             :  *  (at your option) any later version.
      20             :  *
      21             :  *  This program is distributed in the hope that it will be useful,
      22             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      23             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      24             :  *  GNU General Public License for more details.
      25             :  *
      26             :  *  You should have received a copy of the GNU General Public License
      27             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      28             :  */
      29             : 
      30             : /*
      31             :  * This is the implementation of the SAMR code.
      32             :  */
      33             : 
      34             : #include "includes.h"
      35             : #include "system/passwd.h"
      36             : #include "../libcli/auth/libcli_auth.h"
      37             : #include "ntdomain.h"
      38             : #include "librpc/rpc/dcesrv_core.h"
      39             : #include "../librpc/gen_ndr/ndr_samr.h"
      40             : #include "../librpc/gen_ndr/ndr_samr_scompat.h"
      41             : #include "rpc_server/samr/srv_samr_util.h"
      42             : #include "secrets.h"
      43             : #include "rpc_client/init_lsa.h"
      44             : #include "../libcli/security/security.h"
      45             : #include "passdb.h"
      46             : #include "auth.h"
      47             : #include "rpc_server/srv_access_check.h"
      48             : #include "../lib/tsocket/tsocket.h"
      49             : #include "lib/util/base64.h"
      50             : #include "param/param.h"
      51             : #include "librpc/rpc/dcerpc_helper.h"
      52             : #include "librpc/rpc/dcerpc_samr.h"
      53             : 
      54             : #include "lib/crypto/gnutls_helpers.h"
      55             : #include <gnutls/gnutls.h>
      56             : #include <gnutls/crypto.h>
      57             : #include "lib/global_contexts.h"
      58             : #include "nsswitch/winbind_client.h"
      59             : 
      60             : #undef DBGC_CLASS
      61             : #define DBGC_CLASS DBGC_RPC_SRV
      62             : 
      63             : #define SAMR_USR_RIGHTS_WRITE_PW \
      64             :                 ( READ_CONTROL_ACCESS           | \
      65             :                   SAMR_USER_ACCESS_CHANGE_PASSWORD      | \
      66             :                   SAMR_USER_ACCESS_SET_LOC_COM)
      67             : #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
      68             :                 ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM )
      69             : 
      70             : #define DISP_INFO_CACHE_TIMEOUT 10
      71             : 
      72             : #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
      73             : #define MAX_SAM_ENTRIES_W95 50
      74             : 
      75             : enum samr_handle {
      76             :         SAMR_HANDLE_CONNECT,
      77             :         SAMR_HANDLE_DOMAIN,
      78             :         SAMR_HANDLE_USER,
      79             :         SAMR_HANDLE_GROUP,
      80             :         SAMR_HANDLE_ALIAS
      81             : };
      82             : 
      83             : struct samr_info {
      84             :         uint32_t access_granted;
      85             :         struct dom_sid sid;
      86             :         struct disp_info *disp_info;
      87             : };
      88             : 
      89             : typedef struct disp_info {
      90             :         struct dom_sid sid; /* identify which domain this is. */
      91             :         struct pdb_search *users; /* querydispinfo 1 and 4 */
      92             :         struct pdb_search *machines; /* querydispinfo 2 */
      93             :         struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
      94             :         struct pdb_search *aliases; /* enumaliases */
      95             : 
      96             :         uint32_t enum_acb_mask;
      97             :         struct pdb_search *enum_users; /* enumusers with a mask */
      98             : 
      99             :         struct tevent_timer *cache_timeout_event; /* cache idle timeout
     100             :                                                   * handler. */
     101             : } DISP_INFO;
     102             : 
     103             : static const struct generic_mapping sam_generic_mapping = {
     104             :         GENERIC_RIGHTS_SAM_READ,
     105             :         GENERIC_RIGHTS_SAM_WRITE,
     106             :         GENERIC_RIGHTS_SAM_EXECUTE,
     107             :         GENERIC_RIGHTS_SAM_ALL_ACCESS};
     108             : static const struct generic_mapping dom_generic_mapping = {
     109             :         GENERIC_RIGHTS_DOMAIN_READ,
     110             :         GENERIC_RIGHTS_DOMAIN_WRITE,
     111             :         GENERIC_RIGHTS_DOMAIN_EXECUTE,
     112             :         GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
     113             : static const struct generic_mapping usr_generic_mapping = {
     114             :         GENERIC_RIGHTS_USER_READ,
     115             :         GENERIC_RIGHTS_USER_WRITE,
     116             :         GENERIC_RIGHTS_USER_EXECUTE,
     117             :         GENERIC_RIGHTS_USER_ALL_ACCESS};
     118             : static const struct generic_mapping usr_nopwchange_generic_mapping = {
     119             :         GENERIC_RIGHTS_USER_READ,
     120             :         GENERIC_RIGHTS_USER_WRITE,
     121             :         GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD,
     122             :         GENERIC_RIGHTS_USER_ALL_ACCESS};
     123             : static const struct generic_mapping grp_generic_mapping = {
     124             :         GENERIC_RIGHTS_GROUP_READ,
     125             :         GENERIC_RIGHTS_GROUP_WRITE,
     126             :         GENERIC_RIGHTS_GROUP_EXECUTE,
     127             :         GENERIC_RIGHTS_GROUP_ALL_ACCESS};
     128             : static const struct generic_mapping ali_generic_mapping = {
     129             :         GENERIC_RIGHTS_ALIAS_READ,
     130             :         GENERIC_RIGHTS_ALIAS_WRITE,
     131             :         GENERIC_RIGHTS_ALIAS_EXECUTE,
     132             :         GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
     133             : 
     134             : /*******************************************************************
     135             : *******************************************************************/
     136        5754 : static NTSTATUS create_samr_policy_handle(TALLOC_CTX *mem_ctx,
     137             :                                           struct pipes_struct *p,
     138             :                                           enum samr_handle type,
     139             :                                           uint32_t acc_granted,
     140             :                                           struct dom_sid *sid,
     141             :                                           struct disp_info *disp_info,
     142             :                                           struct policy_handle *handle)
     143             : {
     144        5754 :         struct samr_info *info = NULL;
     145           0 :         bool ok;
     146             : 
     147        5754 :         ZERO_STRUCTP(handle);
     148             : 
     149        5754 :         info = talloc_zero(mem_ctx, struct samr_info);
     150        5754 :         if (info == NULL) {
     151           0 :                 return NT_STATUS_NO_MEMORY;
     152             :         }
     153             : 
     154        5754 :         info->access_granted = acc_granted;
     155             : 
     156        5754 :         if (sid != NULL) {
     157        5001 :                 sid_copy(&info->sid, sid);
     158             :         }
     159             : 
     160        5754 :         if (disp_info != NULL) {
     161         536 :                 info->disp_info = disp_info;
     162             :         }
     163             : 
     164        5754 :         ok = create_policy_hnd(p, handle, type, info);
     165        5754 :         if (!ok) {
     166           0 :                 talloc_free(info);
     167           0 :                 ZERO_STRUCTP(handle);
     168           0 :                 return NT_STATUS_NO_MEMORY;
     169             :         }
     170             : 
     171        5754 :         return NT_STATUS_OK;
     172             : }
     173             : 
     174       19044 : static NTSTATUS samr_handle_access_check(uint32_t access_granted,
     175             :                                          uint32_t access_required,
     176             :                                          uint32_t *paccess_granted)
     177             : {
     178       19044 :         if ((access_required & access_granted) != access_required) {
     179           4 :                 if (root_mode()) {
     180           2 :                         DBG_INFO("ACCESS should be DENIED (granted: "
     181             :                                  "%#010x; required: %#010x) but overwritten "
     182             :                                  "by euid == 0\n", access_granted,
     183             :                                  access_required);
     184           2 :                         goto okay;
     185             :                 }
     186           2 :                 DBG_NOTICE("ACCESS DENIED (granted: %#010x; required: "
     187             :                            "%#010x)\n", access_granted, access_required);
     188           2 :                 return NT_STATUS_ACCESS_DENIED;
     189             :         }
     190             : 
     191       19040 : okay:
     192       19042 :         if (paccess_granted != NULL) {
     193        1868 :                 *paccess_granted = access_granted;
     194             :         }
     195       19042 :         return NT_STATUS_OK;
     196             : }
     197             : 
     198       19056 : static void *samr_policy_handle_find(struct pipes_struct *p,
     199             :                                      const struct policy_handle *handle,
     200             :                                      uint8_t handle_type,
     201             :                                      uint32_t access_required,
     202             :                                      uint32_t *access_granted,
     203             :                                      NTSTATUS *pstatus)
     204             : {
     205       19056 :         struct samr_info *info = NULL;
     206           0 :         NTSTATUS status;
     207             : 
     208       19056 :         info = find_policy_by_hnd(p,
     209             :                                   handle,
     210             :                                   handle_type,
     211             :                                   struct samr_info,
     212           0 :                                   &status);
     213       19056 :         if (!NT_STATUS_IS_OK(status)) {
     214          12 :                 *pstatus = NT_STATUS_INVALID_HANDLE;
     215          12 :                 return NULL;
     216             :         }
     217             : 
     218       19044 :         status = samr_handle_access_check(info->access_granted,
     219             :                                           access_required,
     220             :                                           access_granted);
     221       19044 :         if (!NT_STATUS_IS_OK(status)) {
     222           2 :                 *pstatus = status;
     223           2 :                 return NULL;
     224             :         }
     225             : 
     226       19042 :         *pstatus = NT_STATUS_OK;
     227       19042 :         return info;
     228             : }
     229             : 
     230        4927 : static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, struct security_descriptor **psd, size_t *sd_size,
     231             :                                      const struct generic_mapping *map,
     232             :                                      struct dom_sid *sid, uint32_t sid_access )
     233             : {
     234           0 :         struct dom_sid domadmin_sid;
     235           0 :         struct security_ace ace[5];             /* at most 5 entries */
     236        4927 :         size_t i = 0;
     237             : 
     238        4927 :         struct security_acl *psa = NULL;
     239             : 
     240             :         /* basic access for Everyone */
     241             : 
     242        4927 :         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
     243        4927 :                         map->generic_execute | map->generic_read, 0);
     244             : 
     245             :         /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
     246             : 
     247        4927 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
     248        4927 :                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
     249        4927 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
     250        4927 :                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
     251             : 
     252             :         /* Add Full Access for Domain Admins if we are a DC */
     253             : 
     254        4927 :         if ( IS_DC ) {
     255        4790 :                 sid_compose(&domadmin_sid, get_global_sam_sid(),
     256             :                             DOMAIN_RID_ADMINS);
     257        4790 :                 init_sec_ace(&ace[i++], &domadmin_sid,
     258        4790 :                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
     259             :         }
     260             : 
     261             :         /* if we have a sid, give it some special access */
     262             : 
     263        4927 :         if ( sid ) {
     264        2939 :                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
     265             :         }
     266             : 
     267             :         /* create the security descriptor */
     268             : 
     269        4927 :         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
     270           0 :                 return NT_STATUS_NO_MEMORY;
     271             : 
     272        4927 :         if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
     273             :                                   SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
     274             :                                   psa, sd_size)) == NULL)
     275           0 :                 return NT_STATUS_NO_MEMORY;
     276             : 
     277        4927 :         return NT_STATUS_OK;
     278             : }
     279             : 
     280             : /*******************************************************************
     281             :  Fetch or create a dispinfo struct.
     282             : ********************************************************************/
     283             : 
     284        2166 : static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
     285             : {
     286             :         /*
     287             :          * We do a static cache for DISP_INFO's here. Explanation can be found
     288             :          * in Jeremy's checkin message to r11793:
     289             :          *
     290             :          * Fix the SAMR cache so it works across completely insane
     291             :          * client behaviour (ie.:
     292             :          * open pipe/open SAMR handle/enumerate 0 - 1024
     293             :          * close SAMR handle, close pipe.
     294             :          * open pipe/open SAMR handle/enumerate 1024 - 2048...
     295             :          * close SAMR handle, close pipe.
     296             :          * And on ad-nausium. Amazing.... probably object-oriented
     297             :          * client side programming in action yet again.
     298             :          * This change should *massively* improve performance when
     299             :          * enumerating users from an LDAP database.
     300             :          * Jeremy.
     301             :          *
     302             :          * "Our" and the builtin domain are the only ones where we ever
     303             :          * enumerate stuff, so just cache 2 entries.
     304             :          */
     305             : 
     306           0 :         static struct disp_info *builtin_dispinfo;
     307           0 :         static struct disp_info *domain_dispinfo;
     308             : 
     309             :         /* There are two cases to consider here:
     310             :            1) The SID is a domain SID and we look for an equality match, or
     311             :            2) This is an account SID and so we return the DISP_INFO* for our
     312             :               domain */
     313             : 
     314        2166 :         if (psid == NULL) {
     315           0 :                 return NULL;
     316             :         }
     317             : 
     318        2166 :         if (sid_check_is_builtin(psid) || sid_check_is_in_builtin(psid)) {
     319             :                 /*
     320             :                  * Necessary only once, but it does not really hurt.
     321             :                  */
     322         104 :                 if (builtin_dispinfo == NULL) {
     323          40 :                         builtin_dispinfo = talloc_zero(NULL, struct disp_info);
     324          40 :                         if (builtin_dispinfo == NULL) {
     325           0 :                                 return NULL;
     326             :                         }
     327             :                 }
     328         104 :                 sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
     329             : 
     330         104 :                 return builtin_dispinfo;
     331             :         }
     332             : 
     333        2062 :         if (sid_check_is_our_sam(psid) || sid_check_is_in_our_sam(psid)) {
     334             :                 /*
     335             :                  * Necessary only once, but it does not really hurt.
     336             :                  */
     337        2062 :                 if (domain_dispinfo == NULL) {
     338          63 :                         domain_dispinfo = talloc_zero(NULL, struct disp_info);
     339          63 :                         if (domain_dispinfo == NULL) {
     340           0 :                                 return NULL;
     341             :                         }
     342             :                 }
     343        2062 :                 sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
     344             : 
     345        2062 :                 return domain_dispinfo;
     346             :         }
     347             : 
     348           0 :         return NULL;
     349             : }
     350             : 
     351             : /*******************************************************************
     352             :  Function to free the per SID data.
     353             :  ********************************************************************/
     354             : 
     355          37 : static void free_samr_cache(DISP_INFO *disp_info)
     356             : {
     357           0 :         struct dom_sid_buf buf;
     358             : 
     359          37 :         DEBUG(10, ("free_samr_cache: deleting cache for SID %s\n",
     360             :                    dom_sid_str_buf(&disp_info->sid, &buf)));
     361             : 
     362             :         /* We need to become root here because the paged search might have to
     363             :          * tell the LDAP server we're not interested in the rest anymore. */
     364             : 
     365          37 :         become_root();
     366             : 
     367          37 :         TALLOC_FREE(disp_info->users);
     368          37 :         TALLOC_FREE(disp_info->machines);
     369          37 :         TALLOC_FREE(disp_info->groups);
     370          37 :         TALLOC_FREE(disp_info->aliases);
     371          37 :         TALLOC_FREE(disp_info->enum_users);
     372             : 
     373          37 :         unbecome_root();
     374          37 : }
     375             : 
     376             : /*******************************************************************
     377             :  Idle event handler. Throw away the disp info cache.
     378             :  ********************************************************************/
     379             : 
     380          24 : static void disp_info_cache_idle_timeout_handler(struct tevent_context *ev_ctx,
     381             :                                                  struct tevent_timer *te,
     382             :                                                  struct timeval now,
     383             :                                                  void *private_data)
     384             : {
     385          24 :         DISP_INFO *disp_info = (DISP_INFO *)private_data;
     386             : 
     387          24 :         TALLOC_FREE(disp_info->cache_timeout_event);
     388             : 
     389          24 :         DEBUG(10, ("disp_info_cache_idle_timeout_handler: caching timed "
     390             :                    "out\n"));
     391          24 :         free_samr_cache(disp_info);
     392          24 : }
     393             : 
     394             : /*******************************************************************
     395             :  Setup cache removal idle event handler.
     396             :  ********************************************************************/
     397             : 
     398         216 : static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
     399             : {
     400           0 :         struct dom_sid_buf buf;
     401             : 
     402             :         /* Remove any pending timeout and update. */
     403             : 
     404         216 :         TALLOC_FREE(disp_info->cache_timeout_event);
     405             : 
     406         216 :         DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for "
     407             :                   "SID %s for %u seconds\n",
     408             :                   dom_sid_str_buf(&disp_info->sid, &buf),
     409             :                   (unsigned int)secs_fromnow ));
     410             : 
     411         216 :         disp_info->cache_timeout_event = tevent_add_timer(
     412             :                 global_event_context(), NULL,
     413             :                 timeval_current_ofs(secs_fromnow, 0),
     414             :                 disp_info_cache_idle_timeout_handler, (void *)disp_info);
     415         216 : }
     416             : 
     417             : /*******************************************************************
     418             :  Force flush any cache. We do this on any samr_set_xxx call.
     419             :  We must also remove the timeout handler.
     420             :  ********************************************************************/
     421             : 
     422        1630 : static void force_flush_samr_cache(const struct dom_sid *sid)
     423             : {
     424        1630 :         struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
     425             : 
     426        1630 :         if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
     427        1617 :                 return;
     428             :         }
     429             : 
     430          13 :         DEBUG(10,("force_flush_samr_cache: clearing idle event\n"));
     431          13 :         TALLOC_FREE(disp_info->cache_timeout_event);
     432          13 :         free_samr_cache(disp_info);
     433             : }
     434             : 
     435             : /*******************************************************************
     436             :  Ensure password info is never given out. Paranioa... JRA.
     437             :  ********************************************************************/
     438             : 
     439        1868 : static void samr_clear_sam_passwd(struct samu *sam_pass)
     440             : {
     441             : 
     442        1868 :         if (!sam_pass)
     443           0 :                 return;
     444             : 
     445             :         /* These now zero out the old password */
     446             : 
     447        1868 :         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
     448        1868 :         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
     449             : }
     450             : 
     451          36 : static uint32_t count_sam_users(struct disp_info *info, uint32_t acct_flags)
     452             : {
     453           0 :         struct samr_displayentry *entry;
     454             : 
     455          36 :         if (sid_check_is_builtin(&info->sid)) {
     456             :                 /* No users in builtin. */
     457          17 :                 return 0;
     458             :         }
     459             : 
     460          19 :         if (info->users == NULL) {
     461           9 :                 info->users = pdb_search_users(info, acct_flags);
     462           9 :                 if (info->users == NULL) {
     463           0 :                         return 0;
     464             :                 }
     465             :         }
     466             :         /* Fetch the last possible entry, thus trigger an enumeration */
     467          19 :         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
     468             : 
     469             :         /* Ensure we cache this enumeration. */
     470          19 :         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
     471             : 
     472          19 :         return info->users->num_entries;
     473             : }
     474             : 
     475          36 : static uint32_t count_sam_groups(struct disp_info *info)
     476             : {
     477           0 :         struct samr_displayentry *entry;
     478             : 
     479          36 :         if (sid_check_is_builtin(&info->sid)) {
     480             :                 /* No groups in builtin. */
     481          17 :                 return 0;
     482             :         }
     483             : 
     484          19 :         if (info->groups == NULL) {
     485           8 :                 info->groups = pdb_search_groups(info);
     486           8 :                 if (info->groups == NULL) {
     487           0 :                         return 0;
     488             :                 }
     489             :         }
     490             :         /* Fetch the last possible entry, thus trigger an enumeration */
     491          19 :         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
     492             : 
     493             :         /* Ensure we cache this enumeration. */
     494          19 :         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
     495             : 
     496          19 :         return info->groups->num_entries;
     497             : }
     498             : 
     499          36 : static uint32_t count_sam_aliases(struct disp_info *info)
     500             : {
     501           0 :         struct samr_displayentry *entry;
     502             : 
     503          36 :         if (info->aliases == NULL) {
     504          17 :                 info->aliases = pdb_search_aliases(info, &info->sid);
     505          17 :                 if (info->aliases == NULL) {
     506           0 :                         return 0;
     507             :                 }
     508             :         }
     509             :         /* Fetch the last possible entry, thus trigger an enumeration */
     510          36 :         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
     511             : 
     512             :         /* Ensure we cache this enumeration. */
     513          36 :         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
     514             : 
     515          36 :         return info->aliases->num_entries;
     516             : }
     517             : 
     518             : /*******************************************************************
     519             :  _samr_Close
     520             :  ********************************************************************/
     521             : 
     522        5211 : NTSTATUS _samr_Close(struct pipes_struct *p, struct samr_Close *r)
     523             : {
     524        5211 :         if (!close_policy_hnd(p, r->in.handle)) {
     525           0 :                 return NT_STATUS_INVALID_HANDLE;
     526             :         }
     527             : 
     528        5211 :         ZERO_STRUCTP(r->out.handle);
     529             : 
     530        5211 :         return NT_STATUS_OK;
     531             : }
     532             : 
     533             : /*******************************************************************
     534             :  _samr_OpenDomain
     535             :  ********************************************************************/
     536             : 
     537         538 : NTSTATUS _samr_OpenDomain(struct pipes_struct *p,
     538             :                           struct samr_OpenDomain *r)
     539             : {
     540         538 :         struct dcesrv_call_state *dce_call = p->dce_call;
     541           0 :         struct auth_session_info *session_info =
     542         538 :                 dcesrv_call_session_info(dce_call);
     543         538 :         struct security_descriptor *psd = NULL;
     544           0 :         uint32_t    acc_granted;
     545         538 :         uint32_t    des_access = r->in.access_mask;
     546           0 :         NTSTATUS  status;
     547           0 :         size_t    sd_size;
     548         538 :         uint32_t extra_access = SAMR_DOMAIN_ACCESS_CREATE_USER;
     549         538 :         struct disp_info *disp_info = NULL;
     550             : 
     551             :         /* find the connection policy handle. */
     552         538 :         (void)samr_policy_handle_find(p,
     553         538 :                                       r->in.connect_handle,
     554             :                                       SAMR_HANDLE_CONNECT,
     555             :                                       0,
     556             :                                       NULL,
     557             :                                       &status);
     558         538 :         if (!NT_STATUS_IS_OK(status)) {
     559           2 :                 return status;
     560             :         }
     561             : 
     562             :         /*check if access can be granted as requested by client. */
     563         536 :         map_max_allowed_access(session_info->security_token,
     564         536 :                                session_info->unix_token,
     565             :                                &des_access);
     566             : 
     567         536 :         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
     568         536 :         se_map_generic( &des_access, &dom_generic_mapping );
     569             : 
     570             :         /*
     571             :          * Users with SeAddUser get the ability to manipulate groups
     572             :          * and aliases.
     573             :          */
     574         536 :         if (security_token_has_privilege(
     575         536 :                     session_info->security_token, SEC_PRIV_ADD_USERS)) {
     576         274 :                 extra_access |= (SAMR_DOMAIN_ACCESS_CREATE_GROUP |
     577             :                                 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
     578             :                                 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
     579             :                                 SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS |
     580             :                                 SAMR_DOMAIN_ACCESS_CREATE_ALIAS);
     581             :         }
     582             : 
     583             :         /*
     584             :          * Users with SeMachineAccount or SeAddUser get additional
     585             :          * SAMR_DOMAIN_ACCESS_CREATE_USER access.
     586             :          */
     587             : 
     588         536 :         status = access_check_object( psd, session_info->security_token,
     589             :                                       SEC_PRIV_MACHINE_ACCOUNT, SEC_PRIV_ADD_USERS,
     590             :                                       extra_access, des_access,
     591             :                                       &acc_granted, "_samr_OpenDomain" );
     592             : 
     593         536 :         if ( !NT_STATUS_IS_OK(status) )
     594           0 :                 return status;
     595             : 
     596         536 :         if (!sid_check_is_our_sam(r->in.sid) &&
     597         102 :             !sid_check_is_builtin(r->in.sid)) {
     598           0 :                 return NT_STATUS_NO_SUCH_DOMAIN;
     599             :         }
     600             : 
     601         536 :         disp_info = get_samr_dispinfo_by_sid(r->in.sid);
     602             : 
     603         536 :         status = create_samr_policy_handle(p->mem_ctx,
     604             :                                            p,
     605             :                                            SAMR_HANDLE_DOMAIN,
     606             :                                            acc_granted,
     607             :                                            r->in.sid,
     608             :                                            disp_info,
     609             :                                            r->out.domain_handle);
     610         536 :         if (!NT_STATUS_IS_OK(status)) {
     611           0 :                 return status;
     612             :         }
     613             : 
     614         536 :         DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
     615             : 
     616         536 :         return NT_STATUS_OK;
     617             : }
     618             : 
     619             : /*******************************************************************
     620             :  _samr_GetUserPwInfo
     621             :  ********************************************************************/
     622             : 
     623         322 : NTSTATUS _samr_GetUserPwInfo(struct pipes_struct *p,
     624             :                              struct samr_GetUserPwInfo *r)
     625             : {
     626           0 :         const struct loadparm_substitution *lp_sub =
     627         322 :                 loadparm_s3_global_substitution();
     628           0 :         struct samr_info *uinfo;
     629           0 :         enum lsa_SidType sid_type;
     630         322 :         uint32_t min_password_length = 0;
     631         322 :         uint32_t password_properties = 0;
     632         322 :         bool ret = false;
     633           0 :         NTSTATUS status;
     634             : 
     635         322 :         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
     636             : 
     637         322 :         uinfo = samr_policy_handle_find(p, r->in.user_handle,
     638             :                                         SAMR_HANDLE_USER,
     639             :                                         SAMR_USER_ACCESS_GET_ATTRIBUTES,
     640             :                                         NULL,
     641             :                                         &status);
     642         322 :         if (!NT_STATUS_IS_OK(status)) {
     643           0 :                 return status;
     644             :         }
     645             : 
     646         322 :         if (!sid_check_is_in_our_sam(&uinfo->sid)) {
     647           0 :                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
     648             :         }
     649             : 
     650         322 :         become_root();
     651         322 :         ret = lookup_sid(p->mem_ctx, &uinfo->sid, NULL, NULL, &sid_type);
     652         322 :         unbecome_root();
     653         322 :         if (ret == false) {
     654           0 :                 return NT_STATUS_NO_SUCH_USER;
     655             :         }
     656             : 
     657         322 :         switch (sid_type) {
     658         322 :                 case SID_NAME_USER:
     659         322 :                         become_root();
     660         322 :                         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
     661             :                                                &min_password_length);
     662         322 :                         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
     663             :                                                &password_properties);
     664         322 :                         unbecome_root();
     665             : 
     666         322 :                         if (lp_check_password_script(talloc_tos(), lp_sub)
     667         322 :                             && *lp_check_password_script(talloc_tos(), lp_sub)) {
     668           0 :                                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
     669             :                         }
     670             : 
     671         322 :                         break;
     672           0 :                 default:
     673           0 :                         break;
     674             :         }
     675             : 
     676         322 :         r->out.info->min_password_length = min_password_length;
     677         322 :         r->out.info->password_properties = password_properties;
     678             : 
     679         322 :         DEBUG(5,("_samr_GetUserPwInfo: %d\n", __LINE__));
     680             : 
     681         322 :         return NT_STATUS_OK;
     682             : }
     683             : 
     684             : /*******************************************************************
     685             :  _samr_SetSecurity
     686             :  ********************************************************************/
     687             : 
     688           2 : NTSTATUS _samr_SetSecurity(struct pipes_struct *p,
     689             :                            struct samr_SetSecurity *r)
     690             : {
     691           0 :         struct samr_info *uinfo;
     692           0 :         uint32_t i;
     693           0 :         struct security_acl *dacl;
     694           0 :         bool ret;
     695           2 :         struct samu *sampass=NULL;
     696           0 :         NTSTATUS status;
     697             : 
     698           2 :         uinfo = samr_policy_handle_find(p,
     699           2 :                                         r->in.handle,
     700             :                                         SAMR_HANDLE_USER,
     701             :                                         SAMR_USER_ACCESS_SET_ATTRIBUTES,
     702             :                                         NULL,
     703             :                                         &status);
     704           2 :         if (!NT_STATUS_IS_OK(status)) {
     705           0 :                 return status;
     706             :         }
     707             : 
     708           2 :         if (!(sampass = samu_new( p->mem_ctx))) {
     709           0 :                 DEBUG(0,("No memory!\n"));
     710           0 :                 return NT_STATUS_NO_MEMORY;
     711             :         }
     712             : 
     713             :         /* get the user record */
     714           2 :         become_root();
     715           2 :         ret = pdb_getsampwsid(sampass, &uinfo->sid);
     716           2 :         unbecome_root();
     717             : 
     718           2 :         if (!ret) {
     719           0 :                 struct dom_sid_buf buf;
     720           0 :                 DEBUG(4, ("User %s not found\n",
     721             :                           dom_sid_str_buf(&uinfo->sid, &buf)));
     722           0 :                 TALLOC_FREE(sampass);
     723           0 :                 return NT_STATUS_INVALID_HANDLE;
     724             :         }
     725             : 
     726           2 :         dacl = r->in.sdbuf->sd->dacl;
     727          10 :         for (i=0; i < dacl->num_aces; i++) {
     728          10 :                 if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) {
     729           2 :                         ret = pdb_set_pass_can_change(sampass,
     730           2 :                                 (dacl->aces[i].access_mask &
     731             :                                  SAMR_USER_ACCESS_CHANGE_PASSWORD) ?
     732           2 :                                                       True: False);
     733           2 :                         break;
     734             :                 }
     735             :         }
     736             : 
     737           2 :         if (!ret) {
     738           0 :                 TALLOC_FREE(sampass);
     739           0 :                 return NT_STATUS_ACCESS_DENIED;
     740             :         }
     741             : 
     742           2 :         become_root();
     743           2 :         status = pdb_update_sam_account(sampass);
     744           2 :         unbecome_root();
     745             : 
     746           2 :         TALLOC_FREE(sampass);
     747             : 
     748           2 :         return status;
     749             : }
     750             : 
     751             : /*******************************************************************
     752             :   build correct perms based on policies and password times for _samr_query_sec_obj
     753             : *******************************************************************/
     754           4 : static bool check_change_pw_access(TALLOC_CTX *mem_ctx, struct dom_sid *user_sid)
     755             : {
     756           4 :         struct samu *sampass=NULL;
     757           0 :         bool ret;
     758             : 
     759           4 :         if ( !(sampass = samu_new( mem_ctx )) ) {
     760           0 :                 DEBUG(0,("No memory!\n"));
     761           0 :                 return False;
     762             :         }
     763             : 
     764           4 :         become_root();
     765           4 :         ret = pdb_getsampwsid(sampass, user_sid);
     766           4 :         unbecome_root();
     767             : 
     768           4 :         if (ret == False) {
     769           0 :                 struct dom_sid_buf buf;
     770           0 :                 DEBUG(4,("User %s not found\n",
     771             :                          dom_sid_str_buf(user_sid, &buf)));
     772           0 :                 TALLOC_FREE(sampass);
     773           0 :                 return False;
     774             :         }
     775             : 
     776           4 :         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
     777             : 
     778           4 :         if (pdb_get_pass_can_change(sampass)) {
     779           4 :                 TALLOC_FREE(sampass);
     780           4 :                 return True;
     781             :         }
     782           0 :         TALLOC_FREE(sampass);
     783           0 :         return False;
     784             : }
     785             : 
     786             : 
     787             : /*******************************************************************
     788             :  _samr_QuerySecurity
     789             :  ********************************************************************/
     790             : 
     791           4 : NTSTATUS _samr_QuerySecurity(struct pipes_struct *p,
     792             :                              struct samr_QuerySecurity *r)
     793             : {
     794           0 :         struct samr_info *info;
     795           0 :         NTSTATUS status;
     796           4 :         struct security_descriptor * psd = NULL;
     797           4 :         size_t sd_size = 0;
     798           0 :         struct dom_sid_buf buf;
     799             : 
     800           4 :         info = samr_policy_handle_find(p,
     801           4 :                                        r->in.handle,
     802             :                                        SAMR_HANDLE_CONNECT,
     803             :                                        SEC_STD_READ_CONTROL,
     804             :                                        NULL,
     805             :                                        &status);
     806           4 :         if (NT_STATUS_IS_OK(status)) {
     807           0 :                 DEBUG(5,("_samr_QuerySecurity: querying security on SAM\n"));
     808           0 :                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
     809             :                                              &sam_generic_mapping, NULL, 0);
     810           0 :                 goto done;
     811             :         }
     812             : 
     813           4 :         info = samr_policy_handle_find(p,
     814           4 :                                        r->in.handle,
     815             :                                        SAMR_HANDLE_DOMAIN,
     816             :                                        SEC_STD_READ_CONTROL,
     817             :                                        NULL,
     818             :                                        &status);
     819           4 :         if (NT_STATUS_IS_OK(status)) {
     820           0 :                 DEBUG(5,("_samr_QuerySecurity: querying security on Domain "
     821             :                          "with SID: %s\n",
     822             :                          dom_sid_str_buf(&info->sid, &buf)));
     823             :                 /*
     824             :                  * TODO: Builtin probably needs a different SD with restricted
     825             :                  * write access
     826             :                  */
     827           0 :                 status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size,
     828             :                                              &dom_generic_mapping, NULL, 0);
     829           0 :                 goto done;
     830             :         }
     831             : 
     832           4 :         info = samr_policy_handle_find(p,
     833           4 :                                        r->in.handle,
     834             :                                        SAMR_HANDLE_USER,
     835             :                                        SEC_STD_READ_CONTROL,
     836             :                                        NULL,
     837             :                                        &status);
     838           4 :         if (NT_STATUS_IS_OK(status)) {
     839           4 :                 DEBUG(10,("_samr_QuerySecurity: querying security on user "
     840             :                           "Object with SID: %s\n",
     841             :                           dom_sid_str_buf(&info->sid, &buf)));
     842           4 :                 if (check_change_pw_access(p->mem_ctx, &info->sid)) {
     843           4 :                         status = make_samr_object_sd(
     844             :                                 p->mem_ctx, &psd, &sd_size,
     845             :                                 &usr_generic_mapping,
     846             :                                 &info->sid, SAMR_USR_RIGHTS_WRITE_PW);
     847             :                 } else {
     848           0 :                         status = make_samr_object_sd(
     849             :                                 p->mem_ctx, &psd, &sd_size,
     850             :                                 &usr_nopwchange_generic_mapping,
     851             :                                 &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
     852             :                 }
     853           4 :                 goto done;
     854             :         }
     855             : 
     856           0 :         info = samr_policy_handle_find(p,
     857           0 :                                        r->in.handle,
     858             :                                        SAMR_HANDLE_GROUP,
     859             :                                        SEC_STD_READ_CONTROL,
     860             :                                        NULL,
     861             :                                        &status);
     862           0 :         if (NT_STATUS_IS_OK(status)) {
     863             :                 /*
     864             :                  * TODO: different SDs have to be generated for aliases groups
     865             :                  * and users.  Currently all three get a default user SD
     866             :                  */
     867           0 :                 DEBUG(10,("_samr_QuerySecurity: querying security on group "
     868             :                           "Object with SID: %s\n",
     869             :                           dom_sid_str_buf(&info->sid, &buf)));
     870           0 :                 status = make_samr_object_sd(
     871             :                         p->mem_ctx, &psd, &sd_size,
     872             :                         &usr_nopwchange_generic_mapping,
     873             :                         &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
     874           0 :                 goto done;
     875             :         }
     876             : 
     877           0 :         info = samr_policy_handle_find(p,
     878           0 :                                        r->in.handle,
     879             :                                        SAMR_HANDLE_ALIAS,
     880             :                                        SEC_STD_READ_CONTROL,
     881             :                                        NULL,
     882             :                                        &status);
     883           0 :         if (NT_STATUS_IS_OK(status)) {
     884             :                 /*
     885             :                  * TODO: different SDs have to be generated for aliases groups
     886             :                  * and users.  Currently all three get a default user SD
     887             :                  */
     888           0 :                 DEBUG(10,("_samr_QuerySecurity: querying security on alias "
     889             :                           "Object with SID: %s\n",
     890             :                           dom_sid_str_buf(&info->sid, &buf)));
     891           0 :                 status = make_samr_object_sd(
     892             :                         p->mem_ctx, &psd, &sd_size,
     893             :                         &usr_nopwchange_generic_mapping,
     894             :                         &info->sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
     895           0 :                 goto done;
     896             :         }
     897             : 
     898           0 :         return NT_STATUS_OBJECT_TYPE_MISMATCH;
     899           4 : done:
     900           4 :         if ((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
     901           0 :                 return NT_STATUS_NO_MEMORY;
     902             : 
     903           4 :         return status;
     904             : }
     905             : 
     906             : /*******************************************************************
     907             : makes a SAM_ENTRY / UNISTR2* structure from a user list.
     908             : ********************************************************************/
     909             : 
     910          21 : static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx,
     911             :                                          struct samr_SamEntry **sam_pp,
     912             :                                          uint32_t num_entries,
     913             :                                          uint32_t start_idx,
     914             :                                          struct samr_displayentry *entries)
     915             : {
     916           0 :         uint32_t i;
     917           0 :         struct samr_SamEntry *sam;
     918             : 
     919          21 :         *sam_pp = NULL;
     920             : 
     921          21 :         if (num_entries == 0) {
     922           0 :                 return NT_STATUS_OK;
     923             :         }
     924             : 
     925          21 :         sam = talloc_zero_array(ctx, struct samr_SamEntry, num_entries);
     926          21 :         if (sam == NULL) {
     927           0 :                 DEBUG(0, ("make_user_sam_entry_list: TALLOC_ZERO failed!\n"));
     928           0 :                 return NT_STATUS_NO_MEMORY;
     929             :         }
     930             : 
     931        2790 :         for (i = 0; i < num_entries; i++) {
     932             : #if 0
     933             :                 /*
     934             :                  * usrmgr expects a non-NULL terminated string with
     935             :                  * trust relationships
     936             :                  */
     937             :                 if (entries[i].acct_flags & ACB_DOMTRUST) {
     938             :                         init_unistr2(&uni_temp_name, entries[i].account_name,
     939             :                                      UNI_FLAGS_NONE);
     940             :                 } else {
     941             :                         init_unistr2(&uni_temp_name, entries[i].account_name,
     942             :                                      UNI_STR_TERMINATE);
     943             :                 }
     944             : #endif
     945        2769 :                 init_lsa_String(&sam[i].name, entries[i].account_name);
     946        2769 :                 sam[i].idx = entries[i].rid;
     947             :         }
     948             : 
     949          21 :         *sam_pp = sam;
     950             : 
     951          21 :         return NT_STATUS_OK;
     952             : }
     953             : 
     954             : #define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
     955             : 
     956             : /*******************************************************************
     957             :  _samr_EnumDomainUsers
     958             :  ********************************************************************/
     959             : 
     960          37 : NTSTATUS _samr_EnumDomainUsers(struct pipes_struct *p,
     961             :                                struct samr_EnumDomainUsers *r)
     962             : {
     963           0 :         NTSTATUS status;
     964           0 :         struct samr_info *dinfo;
     965           0 :         uint32_t num_account;
     966          37 :         uint32_t enum_context = *r->in.resume_handle;
     967          37 :         enum remote_arch_types ra_type = get_remote_arch();
     968          37 :         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
     969          37 :         uint32_t max_entries = max_sam_entries;
     970          37 :         struct samr_displayentry *entries = NULL;
     971          37 :         struct samr_SamArray *samr_array = NULL;
     972          37 :         struct samr_SamEntry *samr_entries = NULL;
     973             : 
     974          37 :         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
     975             : 
     976          37 :         dinfo = samr_policy_handle_find(p,
     977          37 :                                         r->in.domain_handle,
     978             :                                         SAMR_HANDLE_DOMAIN,
     979             :                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
     980             :                                         NULL,
     981             :                                         &status);
     982          37 :         if (!NT_STATUS_IS_OK(status)) {
     983           0 :                 return status;
     984             :         }
     985             : 
     986          37 :         samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
     987          37 :         if (!samr_array) {
     988           0 :                 return NT_STATUS_NO_MEMORY;
     989             :         }
     990          37 :         *r->out.sam = samr_array;
     991             : 
     992          37 :         if (sid_check_is_builtin(&dinfo->sid)) {
     993             :                 /* No users in builtin. */
     994          10 :                 *r->out.resume_handle = *r->in.resume_handle;
     995          10 :                 DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
     996          10 :                 return status;
     997             :         }
     998             : 
     999          27 :         become_root();
    1000             : 
    1001             :         /* AS ROOT !!!! */
    1002             : 
    1003          27 :         if ((dinfo->disp_info->enum_users != NULL) &&
    1004          17 :             (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
    1005           7 :                 TALLOC_FREE(dinfo->disp_info->enum_users);
    1006             :         }
    1007             : 
    1008          27 :         if (dinfo->disp_info->enum_users == NULL) {
    1009          34 :                 dinfo->disp_info->enum_users = pdb_search_users(
    1010          17 :                         dinfo->disp_info, r->in.acct_flags);
    1011          17 :                 dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
    1012             :         }
    1013             : 
    1014          27 :         if (dinfo->disp_info->enum_users == NULL) {
    1015             :                 /* END AS ROOT !!!! */
    1016           0 :                 unbecome_root();
    1017           0 :                 return NT_STATUS_ACCESS_DENIED;
    1018             :         }
    1019             : 
    1020          27 :         num_account = pdb_search_entries(dinfo->disp_info->enum_users,
    1021             :                                          enum_context, max_entries,
    1022             :                                          &entries);
    1023             : 
    1024             :         /* END AS ROOT !!!! */
    1025             : 
    1026          27 :         unbecome_root();
    1027             : 
    1028          27 :         if (num_account == 0) {
    1029           6 :                 DEBUG(5, ("_samr_EnumDomainUsers: enumeration handle over "
    1030             :                           "total entries\n"));
    1031           6 :                 *r->out.resume_handle = *r->in.resume_handle;
    1032           6 :                 return NT_STATUS_OK;
    1033             :         }
    1034             : 
    1035          21 :         status = make_user_sam_entry_list(p->mem_ctx, &samr_entries,
    1036             :                                           num_account, enum_context,
    1037             :                                           entries);
    1038          21 :         if (!NT_STATUS_IS_OK(status)) {
    1039           0 :                 return status;
    1040             :         }
    1041             : 
    1042          21 :         if (max_entries <= num_account) {
    1043           0 :                 status = STATUS_MORE_ENTRIES;
    1044             :         } else {
    1045          21 :                 status = NT_STATUS_OK;
    1046             :         }
    1047             : 
    1048             :         /* Ensure we cache this enumeration. */
    1049          21 :         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
    1050             : 
    1051          21 :         DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
    1052             : 
    1053          21 :         samr_array->count = num_account;
    1054          21 :         samr_array->entries = samr_entries;
    1055             : 
    1056          21 :         *r->out.resume_handle = *r->in.resume_handle + num_account;
    1057          21 :         *r->out.num_entries = num_account;
    1058             : 
    1059          21 :         DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
    1060             : 
    1061          21 :         return status;
    1062             : }
    1063             : 
    1064             : /*******************************************************************
    1065             : makes a SAM_ENTRY / UNISTR2* structure from a group list.
    1066             : ********************************************************************/
    1067             : 
    1068          51 : static void make_group_sam_entry_list(TALLOC_CTX *ctx,
    1069             :                                       struct samr_SamEntry **sam_pp,
    1070             :                                       uint32_t num_sam_entries,
    1071             :                                       struct samr_displayentry *entries)
    1072             : {
    1073           0 :         struct samr_SamEntry *sam;
    1074           0 :         uint32_t i;
    1075             : 
    1076          51 :         *sam_pp = NULL;
    1077             : 
    1078          51 :         if (num_sam_entries == 0) {
    1079           2 :                 return;
    1080             :         }
    1081             : 
    1082          49 :         sam = talloc_zero_array(ctx, struct samr_SamEntry, num_sam_entries);
    1083          49 :         if (sam == NULL) {
    1084           0 :                 return;
    1085             :         }
    1086             : 
    1087        2711 :         for (i = 0; i < num_sam_entries; i++) {
    1088             :                 /*
    1089             :                  * JRA. I think this should include the null. TNG does not.
    1090             :                  */
    1091        2662 :                 init_lsa_String(&sam[i].name, entries[i].account_name);
    1092        2662 :                 sam[i].idx = entries[i].rid;
    1093             :         }
    1094             : 
    1095          49 :         *sam_pp = sam;
    1096             : }
    1097             : 
    1098             : /*******************************************************************
    1099             :  _samr_EnumDomainGroups
    1100             :  ********************************************************************/
    1101             : 
    1102          15 : NTSTATUS _samr_EnumDomainGroups(struct pipes_struct *p,
    1103             :                                 struct samr_EnumDomainGroups *r)
    1104             : {
    1105           0 :         NTSTATUS status;
    1106           0 :         struct samr_info *dinfo;
    1107           0 :         struct samr_displayentry *groups;
    1108           0 :         uint32_t num_groups;
    1109          15 :         struct samr_SamArray *samr_array = NULL;
    1110          15 :         struct samr_SamEntry *samr_entries = NULL;
    1111             : 
    1112          15 :         dinfo = samr_policy_handle_find(p,
    1113          15 :                                         r->in.domain_handle,
    1114             :                                         SAMR_HANDLE_DOMAIN,
    1115             :                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
    1116             :                                         NULL,
    1117             :                                         &status);
    1118          15 :         if (!NT_STATUS_IS_OK(status)) {
    1119           0 :                 return status;
    1120             :         }
    1121             : 
    1122          15 :         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
    1123             : 
    1124          15 :         samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
    1125          15 :         if (!samr_array) {
    1126           0 :                 return NT_STATUS_NO_MEMORY;
    1127             :         }
    1128          15 :         *r->out.sam = samr_array;
    1129             : 
    1130          15 :         if (sid_check_is_builtin(&dinfo->sid)) {
    1131             :                 /* No groups in builtin. */
    1132           4 :                 *r->out.resume_handle = *r->in.resume_handle;
    1133           4 :                 DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
    1134           4 :                 return status;
    1135             :         }
    1136             : 
    1137             :         /* the domain group array is being allocated in the function below */
    1138             : 
    1139          11 :         become_root();
    1140             : 
    1141          11 :         if (dinfo->disp_info->groups == NULL) {
    1142           6 :                 dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
    1143             : 
    1144           6 :                 if (dinfo->disp_info->groups == NULL) {
    1145           0 :                         unbecome_root();
    1146           0 :                         return NT_STATUS_ACCESS_DENIED;
    1147             :                 }
    1148             :         }
    1149             : 
    1150          11 :         num_groups = pdb_search_entries(dinfo->disp_info->groups,
    1151          11 :                                         *r->in.resume_handle,
    1152             :                                         MAX_SAM_ENTRIES, &groups);
    1153          11 :         unbecome_root();
    1154             : 
    1155             :         /* Ensure we cache this enumeration. */
    1156          11 :         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
    1157             : 
    1158          11 :         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
    1159             :                                   num_groups, groups);
    1160             : 
    1161          11 :         if (MAX_SAM_ENTRIES <= num_groups) {
    1162           0 :                 status = STATUS_MORE_ENTRIES;
    1163             :         } else {
    1164          11 :                 status = NT_STATUS_OK;
    1165             :         }
    1166             : 
    1167          11 :         samr_array->count = num_groups;
    1168          11 :         samr_array->entries = samr_entries;
    1169             : 
    1170          11 :         *r->out.num_entries = num_groups;
    1171          11 :         *r->out.resume_handle = num_groups + *r->in.resume_handle;
    1172             : 
    1173          11 :         DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
    1174             : 
    1175          11 :         return status;
    1176             : }
    1177             : 
    1178             : /*******************************************************************
    1179             :  _samr_EnumDomainAliases
    1180             :  ********************************************************************/
    1181             : 
    1182          40 : NTSTATUS _samr_EnumDomainAliases(struct pipes_struct *p,
    1183             :                                  struct samr_EnumDomainAliases *r)
    1184             : {
    1185           0 :         NTSTATUS status;
    1186           0 :         struct samr_info *dinfo;
    1187           0 :         struct samr_displayentry *aliases;
    1188          40 :         uint32_t num_aliases = 0;
    1189          40 :         struct samr_SamArray *samr_array = NULL;
    1190          40 :         struct samr_SamEntry *samr_entries = NULL;
    1191           0 :         struct dom_sid_buf buf;
    1192             : 
    1193          40 :         dinfo = samr_policy_handle_find(p,
    1194          40 :                                         r->in.domain_handle,
    1195             :                                         SAMR_HANDLE_DOMAIN,
    1196             :                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
    1197             :                                         NULL,
    1198             :                                         &status);
    1199          40 :         if (!NT_STATUS_IS_OK(status)) {
    1200           0 :                 return status;
    1201             :         }
    1202             : 
    1203          40 :         DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
    1204             :                  dom_sid_str_buf(&dinfo->sid, &buf)));
    1205             : 
    1206          40 :         samr_array = talloc_zero(p->mem_ctx, struct samr_SamArray);
    1207          40 :         if (!samr_array) {
    1208           0 :                 return NT_STATUS_NO_MEMORY;
    1209             :         }
    1210             : 
    1211          40 :         become_root();
    1212             : 
    1213          40 :         if (dinfo->disp_info->aliases == NULL) {
    1214          26 :                 dinfo->disp_info->aliases = pdb_search_aliases(
    1215          13 :                         dinfo->disp_info, &dinfo->sid);
    1216          13 :                 if (dinfo->disp_info->aliases == NULL) {
    1217           0 :                         unbecome_root();
    1218           0 :                         return NT_STATUS_ACCESS_DENIED;
    1219             :                 }
    1220             :         }
    1221             : 
    1222          40 :         num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
    1223          40 :                                          *r->in.resume_handle,
    1224             :                                          MAX_SAM_ENTRIES, &aliases);
    1225          40 :         unbecome_root();
    1226             : 
    1227             :         /* Ensure we cache this enumeration. */
    1228          40 :         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
    1229             : 
    1230          40 :         make_group_sam_entry_list(p->mem_ctx, &samr_entries,
    1231             :                                   num_aliases, aliases);
    1232             : 
    1233          40 :         DEBUG(5,("_samr_EnumDomainAliases: %d\n", __LINE__));
    1234             : 
    1235          40 :         if (MAX_SAM_ENTRIES <= num_aliases) {
    1236           0 :                 status = STATUS_MORE_ENTRIES;
    1237             :         } else {
    1238          40 :                 status = NT_STATUS_OK;
    1239             :         }
    1240             : 
    1241          40 :         samr_array->count = num_aliases;
    1242          40 :         samr_array->entries = samr_entries;
    1243             : 
    1244          40 :         *r->out.sam = samr_array;
    1245          40 :         *r->out.num_entries = num_aliases;
    1246          40 :         *r->out.resume_handle = num_aliases + *r->in.resume_handle;
    1247             : 
    1248          40 :         return status;
    1249             : }
    1250             : 
    1251             : /*******************************************************************
    1252             :  inits a samr_DispInfoGeneral structure.
    1253             : ********************************************************************/
    1254             : 
    1255          24 : static NTSTATUS init_samr_dispinfo_1(TALLOC_CTX *ctx,
    1256             :                                      struct samr_DispInfoGeneral *r,
    1257             :                                      uint32_t num_entries,
    1258             :                                      uint32_t start_idx,
    1259             :                                      struct samr_displayentry *entries)
    1260             : {
    1261           0 :         uint32_t i;
    1262             : 
    1263          24 :         DEBUG(10, ("init_samr_dispinfo_1: num_entries: %d\n", num_entries));
    1264             : 
    1265          24 :         if (num_entries == 0) {
    1266           1 :                 return NT_STATUS_OK;
    1267             :         }
    1268             : 
    1269          23 :         r->count = num_entries;
    1270             : 
    1271          23 :         r->entries = talloc_zero_array(ctx, struct samr_DispEntryGeneral, num_entries);
    1272          23 :         if (!r->entries) {
    1273           0 :                 return NT_STATUS_NO_MEMORY;
    1274             :         }
    1275             : 
    1276         707 :         for (i = 0; i < num_entries ; i++) {
    1277             : 
    1278         684 :                 init_lsa_String(&r->entries[i].account_name,
    1279         684 :                                 entries[i].account_name);
    1280             : 
    1281         684 :                 init_lsa_String(&r->entries[i].description,
    1282         684 :                                 entries[i].description);
    1283             : 
    1284         684 :                 init_lsa_String(&r->entries[i].full_name,
    1285         684 :                                 entries[i].fullname);
    1286             : 
    1287         684 :                 r->entries[i].rid = entries[i].rid;
    1288         684 :                 r->entries[i].acct_flags = entries[i].acct_flags;
    1289         684 :                 r->entries[i].idx = start_idx+i+1;
    1290             :         }
    1291             : 
    1292          23 :         return NT_STATUS_OK;
    1293             : }
    1294             : 
    1295             : /*******************************************************************
    1296             :  inits a samr_DispInfoFull structure.
    1297             : ********************************************************************/
    1298             : 
    1299           3 : static NTSTATUS init_samr_dispinfo_2(TALLOC_CTX *ctx,
    1300             :                                      struct samr_DispInfoFull *r,
    1301             :                                      uint32_t num_entries,
    1302             :                                      uint32_t start_idx,
    1303             :                                      struct samr_displayentry *entries)
    1304             : {
    1305           0 :         uint32_t i;
    1306             : 
    1307           3 :         DEBUG(10, ("init_samr_dispinfo_2: num_entries: %d\n", num_entries));
    1308             : 
    1309           3 :         if (num_entries == 0) {
    1310           0 :                 return NT_STATUS_OK;
    1311             :         }
    1312             : 
    1313           3 :         r->count = num_entries;
    1314             : 
    1315           3 :         r->entries = talloc_zero_array(ctx, struct samr_DispEntryFull, num_entries);
    1316           3 :         if (!r->entries) {
    1317           0 :                 return NT_STATUS_NO_MEMORY;
    1318             :         }
    1319             : 
    1320           6 :         for (i = 0; i < num_entries ; i++) {
    1321             : 
    1322           3 :                 init_lsa_String(&r->entries[i].account_name,
    1323           3 :                                 entries[i].account_name);
    1324             : 
    1325           3 :                 init_lsa_String(&r->entries[i].description,
    1326           3 :                                 entries[i].description);
    1327             : 
    1328           3 :                 r->entries[i].rid = entries[i].rid;
    1329           3 :                 r->entries[i].acct_flags = entries[i].acct_flags;
    1330           3 :                 r->entries[i].idx = start_idx+i+1;
    1331             :         }
    1332             : 
    1333           3 :         return NT_STATUS_OK;
    1334             : }
    1335             : 
    1336             : /*******************************************************************
    1337             :  inits a samr_DispInfoFullGroups structure.
    1338             : ********************************************************************/
    1339             : 
    1340           6 : static NTSTATUS init_samr_dispinfo_3(TALLOC_CTX *ctx,
    1341             :                                      struct samr_DispInfoFullGroups *r,
    1342             :                                      uint32_t num_entries,
    1343             :                                      uint32_t start_idx,
    1344             :                                      struct samr_displayentry *entries)
    1345             : {
    1346           0 :         uint32_t i;
    1347             : 
    1348           6 :         DEBUG(5, ("init_samr_dispinfo_3: num_entries: %d\n", num_entries));
    1349             : 
    1350           6 :         if (num_entries == 0) {
    1351           1 :                 return NT_STATUS_OK;
    1352             :         }
    1353             : 
    1354           5 :         r->count = num_entries;
    1355             : 
    1356           5 :         r->entries = talloc_zero_array(ctx, struct samr_DispEntryFullGroup, num_entries);
    1357           5 :         if (!r->entries) {
    1358           0 :                 return NT_STATUS_NO_MEMORY;
    1359             :         }
    1360             : 
    1361         317 :         for (i = 0; i < num_entries ; i++) {
    1362             : 
    1363         312 :                 init_lsa_String(&r->entries[i].account_name,
    1364         312 :                                 entries[i].account_name);
    1365             : 
    1366         312 :                 init_lsa_String(&r->entries[i].description,
    1367         312 :                                 entries[i].description);
    1368             : 
    1369         312 :                 r->entries[i].rid = entries[i].rid;
    1370         312 :                 r->entries[i].acct_flags = entries[i].acct_flags;
    1371         312 :                 r->entries[i].idx = start_idx+i+1;
    1372             :         }
    1373             : 
    1374           5 :         return NT_STATUS_OK;
    1375             : }
    1376             : 
    1377             : /*******************************************************************
    1378             :  inits a samr_DispInfoAscii structure.
    1379             : ********************************************************************/
    1380             : 
    1381           8 : static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx,
    1382             :                                      struct samr_DispInfoAscii *r,
    1383             :                                      uint32_t num_entries,
    1384             :                                      uint32_t start_idx,
    1385             :                                      struct samr_displayentry *entries)
    1386             : {
    1387           0 :         uint32_t i;
    1388             : 
    1389           8 :         DEBUG(5, ("init_samr_dispinfo_4: num_entries: %d\n", num_entries));
    1390             : 
    1391           8 :         if (num_entries == 0) {
    1392           0 :                 return NT_STATUS_OK;
    1393             :         }
    1394             : 
    1395           8 :         r->count = num_entries;
    1396             : 
    1397           8 :         r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
    1398           8 :         if (!r->entries) {
    1399           0 :                 return NT_STATUS_NO_MEMORY;
    1400             :         }
    1401             : 
    1402          41 :         for (i = 0; i < num_entries ; i++) {
    1403             : 
    1404          33 :                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
    1405          33 :                                           entries[i].account_name);
    1406             : 
    1407          33 :                 r->entries[i].idx = start_idx+i+1;
    1408             :         }
    1409             : 
    1410           8 :         return NT_STATUS_OK;
    1411             : }
    1412             : 
    1413             : /*******************************************************************
    1414             :  inits a samr_DispInfoAscii structure.
    1415             : ********************************************************************/
    1416             : 
    1417           5 : static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx,
    1418             :                                      struct samr_DispInfoAscii *r,
    1419             :                                      uint32_t num_entries,
    1420             :                                      uint32_t start_idx,
    1421             :                                      struct samr_displayentry *entries)
    1422             : {
    1423           0 :         uint32_t i;
    1424             : 
    1425           5 :         DEBUG(5, ("init_samr_dispinfo_5: num_entries: %d\n", num_entries));
    1426             : 
    1427           5 :         if (num_entries == 0) {
    1428           1 :                 return NT_STATUS_OK;
    1429             :         }
    1430             : 
    1431           4 :         r->count = num_entries;
    1432             : 
    1433           4 :         r->entries = talloc_zero_array(ctx, struct samr_DispEntryAscii, num_entries);
    1434           4 :         if (!r->entries) {
    1435           0 :                 return NT_STATUS_NO_MEMORY;
    1436             :         }
    1437             : 
    1438          15 :         for (i = 0; i < num_entries ; i++) {
    1439             : 
    1440          11 :                 init_lsa_AsciiStringLarge(&r->entries[i].account_name,
    1441          11 :                                           entries[i].account_name);
    1442             : 
    1443          11 :                 r->entries[i].idx = start_idx+i+1;
    1444             :         }
    1445             : 
    1446           4 :         return NT_STATUS_OK;
    1447             : }
    1448             : 
    1449             : /*******************************************************************
    1450             :  _samr_QueryDisplayInfo
    1451             :  ********************************************************************/
    1452             : 
    1453          67 : NTSTATUS _samr_QueryDisplayInfo(struct pipes_struct *p,
    1454             :                                 struct samr_QueryDisplayInfo *r)
    1455             : {
    1456           0 :         NTSTATUS status;
    1457           0 :         struct samr_info *dinfo;
    1458          67 :         uint32_t struct_size=0x20; /* W2K always reply that, client doesn't care */
    1459             : 
    1460          67 :         uint32_t max_entries = r->in.max_entries;
    1461             : 
    1462          67 :         union samr_DispInfo *disp_info = r->out.info;
    1463             : 
    1464          67 :         uint32_t temp_size=0;
    1465          67 :         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
    1466          67 :         uint32_t num_account = 0;
    1467          67 :         enum remote_arch_types ra_type = get_remote_arch();
    1468          67 :         uint32_t max_sam_entries = (ra_type == RA_WIN95) ?
    1469          67 :                 MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
    1470          67 :         struct samr_displayentry *entries = NULL;
    1471             : 
    1472          67 :         DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
    1473             : 
    1474          67 :         dinfo = samr_policy_handle_find(p,
    1475          67 :                                         r->in.domain_handle,
    1476             :                                         SAMR_HANDLE_DOMAIN,
    1477             :                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
    1478             :                                         NULL,
    1479             :                                         &status);
    1480          67 :         if (!NT_STATUS_IS_OK(status)) {
    1481           0 :                 return status;
    1482             :         }
    1483             : 
    1484          67 :         if (sid_check_is_builtin(&dinfo->sid)) {
    1485          21 :                 DEBUG(5,("_samr_QueryDisplayInfo: no users in BUILTIN\n"));
    1486          21 :                 return NT_STATUS_OK;
    1487             :         }
    1488             : 
    1489             :         /*
    1490             :          * calculate how many entries we will return.
    1491             :          * based on
    1492             :          * - the number of entries the client asked
    1493             :          * - our limit on that
    1494             :          * - the starting point (enumeration context)
    1495             :          * - the buffer size the client will accept
    1496             :          */
    1497             : 
    1498             :         /*
    1499             :          * We are a lot more like W2K. Instead of reading the SAM
    1500             :          * each time to find the records we need to send back,
    1501             :          * we read it once and link that copy to the sam handle.
    1502             :          * For large user list (over the MAX_SAM_ENTRIES)
    1503             :          * it's a definitive win.
    1504             :          * second point to notice: between enumerations
    1505             :          * our sam is now the same as it's a snapshoot.
    1506             :          * third point: got rid of the static SAM_USER_21 struct
    1507             :          * no more intermediate.
    1508             :          * con: it uses much more memory, as a full copy is stored
    1509             :          * in memory.
    1510             :          *
    1511             :          * If you want to change it, think twice and think
    1512             :          * of the second point , that's really important.
    1513             :          *
    1514             :          * JFM, 12/20/2001
    1515             :          */
    1516             : 
    1517          46 :         if ((r->in.level < 1) || (r->in.level > 5)) {
    1518           0 :                 DEBUG(0,("_samr_QueryDisplayInfo: Unknown info level (%u)\n",
    1519             :                          (unsigned int)r->in.level ));
    1520           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    1521             :         }
    1522             : 
    1523             :         /* first limit the number of entries we will return */
    1524          46 :         if (r->in.max_entries > max_sam_entries) {
    1525           4 :                 DEBUG(5, ("_samr_QueryDisplayInfo: client requested %d "
    1526             :                           "entries, limiting to %d\n", r->in.max_entries,
    1527             :                           max_sam_entries));
    1528           4 :                 max_entries = max_sam_entries;
    1529             :         }
    1530             : 
    1531             :         /* calculate the size and limit on the number of entries we will
    1532             :          * return */
    1533             : 
    1534          46 :         temp_size=max_entries*struct_size;
    1535             : 
    1536          46 :         if (temp_size > r->in.buf_size) {
    1537           2 :                 max_entries = MIN((r->in.buf_size / struct_size),max_entries);
    1538           2 :                 DEBUG(5, ("_samr_QueryDisplayInfo: buffer size limits to "
    1539             :                           "only %d entries\n", max_entries));
    1540             :         }
    1541             : 
    1542          46 :         become_root();
    1543             : 
    1544             :         /* THe following done as ROOT. Don't return without unbecome_root(). */
    1545             : 
    1546          46 :         switch (r->in.level) {
    1547          32 :         case 1:
    1548             :         case 4:
    1549          32 :                 if (dinfo->disp_info->users == NULL) {
    1550           6 :                         dinfo->disp_info->users = pdb_search_users(
    1551           3 :                                 dinfo->disp_info, ACB_NORMAL);
    1552           3 :                         if (dinfo->disp_info->users == NULL) {
    1553           0 :                                 unbecome_root();
    1554           0 :                                 return NT_STATUS_ACCESS_DENIED;
    1555             :                         }
    1556           3 :                         DEBUG(10,("_samr_QueryDisplayInfo: starting user enumeration at index %u\n",
    1557             :                                 (unsigned  int)r->in.start_idx));
    1558             :                 } else {
    1559          29 :                         DEBUG(10,("_samr_QueryDisplayInfo: using cached user enumeration at index %u\n",
    1560             :                                 (unsigned  int)r->in.start_idx));
    1561             :                 }
    1562             : 
    1563          32 :                 num_account = pdb_search_entries(dinfo->disp_info->users,
    1564             :                                                  r->in.start_idx, max_entries,
    1565             :                                                  &entries);
    1566          32 :                 break;
    1567           3 :         case 2:
    1568           3 :                 if (dinfo->disp_info->machines == NULL) {
    1569           4 :                         dinfo->disp_info->machines = pdb_search_users(
    1570           2 :                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
    1571           2 :                         if (dinfo->disp_info->machines == NULL) {
    1572           0 :                                 unbecome_root();
    1573           0 :                                 return NT_STATUS_ACCESS_DENIED;
    1574             :                         }
    1575           2 :                         DEBUG(10,("_samr_QueryDisplayInfo: starting machine enumeration at index %u\n",
    1576             :                                 (unsigned  int)r->in.start_idx));
    1577             :                 } else {
    1578           1 :                         DEBUG(10,("_samr_QueryDisplayInfo: using cached machine enumeration at index %u\n",
    1579             :                                 (unsigned  int)r->in.start_idx));
    1580             :                 }
    1581             : 
    1582           3 :                 num_account = pdb_search_entries(dinfo->disp_info->machines,
    1583             :                                                  r->in.start_idx, max_entries,
    1584             :                                                  &entries);
    1585           3 :                 break;
    1586          11 :         case 3:
    1587             :         case 5:
    1588          11 :                 if (dinfo->disp_info->groups == NULL) {
    1589           0 :                         dinfo->disp_info->groups = pdb_search_groups(
    1590           0 :                                 dinfo->disp_info);
    1591           0 :                         if (dinfo->disp_info->groups == NULL) {
    1592           0 :                                 unbecome_root();
    1593           0 :                                 return NT_STATUS_ACCESS_DENIED;
    1594             :                         }
    1595           0 :                         DEBUG(10,("_samr_QueryDisplayInfo: starting group enumeration at index %u\n",
    1596             :                                 (unsigned  int)r->in.start_idx));
    1597             :                 } else {
    1598          11 :                         DEBUG(10,("_samr_QueryDisplayInfo: using cached group enumeration at index %u\n",
    1599             :                                 (unsigned  int)r->in.start_idx));
    1600             :                 }
    1601             : 
    1602          11 :                 num_account = pdb_search_entries(dinfo->disp_info->groups,
    1603             :                                                  r->in.start_idx, max_entries,
    1604             :                                                  &entries);
    1605          11 :                 break;
    1606           0 :         default:
    1607           0 :                 unbecome_root();
    1608           0 :                 smb_panic("info class changed");
    1609           0 :                 break;
    1610             :         }
    1611          46 :         unbecome_root();
    1612             : 
    1613             : 
    1614             :         /* Now create reply structure */
    1615          46 :         switch (r->in.level) {
    1616          24 :         case 1:
    1617          24 :                 disp_ret = init_samr_dispinfo_1(p->mem_ctx, &disp_info->info1,
    1618             :                                                 num_account, r->in.start_idx,
    1619             :                                                 entries);
    1620          24 :                 break;
    1621           3 :         case 2:
    1622           3 :                 disp_ret = init_samr_dispinfo_2(p->mem_ctx, &disp_info->info2,
    1623             :                                                 num_account, r->in.start_idx,
    1624             :                                                 entries);
    1625           3 :                 break;
    1626           6 :         case 3:
    1627           6 :                 disp_ret = init_samr_dispinfo_3(p->mem_ctx, &disp_info->info3,
    1628             :                                                 num_account, r->in.start_idx,
    1629             :                                                 entries);
    1630           6 :                 break;
    1631           8 :         case 4:
    1632           8 :                 disp_ret = init_samr_dispinfo_4(p->mem_ctx, &disp_info->info4,
    1633             :                                                 num_account, r->in.start_idx,
    1634             :                                                 entries);
    1635           8 :                 break;
    1636           5 :         case 5:
    1637           5 :                 disp_ret = init_samr_dispinfo_5(p->mem_ctx, &disp_info->info5,
    1638             :                                                 num_account, r->in.start_idx,
    1639             :                                                 entries);
    1640           5 :                 break;
    1641           0 :         default:
    1642           0 :                 smb_panic("info class changed");
    1643           0 :                 break;
    1644             :         }
    1645             : 
    1646          46 :         if (!NT_STATUS_IS_OK(disp_ret))
    1647           0 :                 return disp_ret;
    1648             : 
    1649          46 :         if (max_entries <= num_account) {
    1650          23 :                 status = STATUS_MORE_ENTRIES;
    1651             :         } else {
    1652          23 :                 status = NT_STATUS_OK;
    1653             :         }
    1654             : 
    1655             :         /* Ensure we cache this enumeration. */
    1656          46 :         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
    1657             : 
    1658          46 :         DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
    1659             : 
    1660          46 :         *r->out.total_size = num_account * struct_size;
    1661          46 :         *r->out.returned_size = num_account ? temp_size : 0;
    1662             : 
    1663          46 :         return status;
    1664             : }
    1665             : 
    1666             : /****************************************************************
    1667             :  _samr_QueryDisplayInfo2
    1668             : ****************************************************************/
    1669             : 
    1670          10 : NTSTATUS _samr_QueryDisplayInfo2(struct pipes_struct *p,
    1671             :                                  struct samr_QueryDisplayInfo2 *r)
    1672             : {
    1673           0 :         struct samr_QueryDisplayInfo q;
    1674             : 
    1675          10 :         q.in.domain_handle      = r->in.domain_handle;
    1676          10 :         q.in.level              = r->in.level;
    1677          10 :         q.in.start_idx          = r->in.start_idx;
    1678          10 :         q.in.max_entries        = r->in.max_entries;
    1679          10 :         q.in.buf_size           = r->in.buf_size;
    1680             : 
    1681          10 :         q.out.total_size        = r->out.total_size;
    1682          10 :         q.out.returned_size     = r->out.returned_size;
    1683          10 :         q.out.info              = r->out.info;
    1684             : 
    1685          10 :         return _samr_QueryDisplayInfo(p, &q);
    1686             : }
    1687             : 
    1688             : /****************************************************************
    1689             :  _samr_QueryDisplayInfo3
    1690             : ****************************************************************/
    1691             : 
    1692          10 : NTSTATUS _samr_QueryDisplayInfo3(struct pipes_struct *p,
    1693             :                                  struct samr_QueryDisplayInfo3 *r)
    1694             : {
    1695           0 :         struct samr_QueryDisplayInfo q;
    1696             : 
    1697          10 :         q.in.domain_handle      = r->in.domain_handle;
    1698          10 :         q.in.level              = r->in.level;
    1699          10 :         q.in.start_idx          = r->in.start_idx;
    1700          10 :         q.in.max_entries        = r->in.max_entries;
    1701          10 :         q.in.buf_size           = r->in.buf_size;
    1702             : 
    1703          10 :         q.out.total_size        = r->out.total_size;
    1704          10 :         q.out.returned_size     = r->out.returned_size;
    1705          10 :         q.out.info              = r->out.info;
    1706             : 
    1707          10 :         return _samr_QueryDisplayInfo(p, &q);
    1708             : }
    1709             : 
    1710             : /*******************************************************************
    1711             :  _samr_QueryAliasInfo
    1712             :  ********************************************************************/
    1713             : 
    1714          17 : NTSTATUS _samr_QueryAliasInfo(struct pipes_struct *p,
    1715             :                               struct samr_QueryAliasInfo *r)
    1716             : {
    1717           0 :         struct samr_info *ainfo;
    1718           0 :         struct acct_info *info;
    1719           0 :         NTSTATUS status;
    1720          17 :         union samr_AliasInfo *alias_info = NULL;
    1721          17 :         const char *alias_name = NULL;
    1722          17 :         const char *alias_description = NULL;
    1723             : 
    1724          17 :         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
    1725             : 
    1726          17 :         ainfo = samr_policy_handle_find(p,
    1727          17 :                                         r->in.alias_handle,
    1728             :                                         SAMR_HANDLE_ALIAS,
    1729             :                                         SAMR_ALIAS_ACCESS_LOOKUP_INFO,
    1730             :                                         NULL,
    1731             :                                         &status);
    1732          17 :         if (!NT_STATUS_IS_OK(status)) {
    1733           0 :                 return status;
    1734             :         }
    1735             : 
    1736          17 :         alias_info = talloc_zero(p->mem_ctx, union samr_AliasInfo);
    1737          17 :         if (!alias_info) {
    1738           0 :                 return NT_STATUS_NO_MEMORY;
    1739             :         }
    1740             : 
    1741          17 :         info = talloc_zero(p->mem_ctx, struct acct_info);
    1742          17 :         if (!info) {
    1743           0 :                 return NT_STATUS_NO_MEMORY;
    1744             :         }
    1745             : 
    1746          17 :         become_root();
    1747          17 :         status = pdb_get_aliasinfo(&ainfo->sid, info);
    1748          17 :         unbecome_root();
    1749             : 
    1750          17 :         if (!NT_STATUS_IS_OK(status)) {
    1751           0 :                 TALLOC_FREE(info);
    1752           0 :                 return status;
    1753             :         }
    1754             : 
    1755          17 :         alias_name = talloc_steal(r, info->acct_name);
    1756          17 :         alias_description = talloc_steal(r, info->acct_desc);
    1757          17 :         TALLOC_FREE(info);
    1758             : 
    1759          17 :         switch (r->in.level) {
    1760           5 :         case ALIASINFOALL:
    1761           5 :                 alias_info->all.name.string          = alias_name;
    1762           5 :                 alias_info->all.num_members          = 1; /* ??? */
    1763           5 :                 alias_info->all.description.string   = alias_description;
    1764           5 :                 break;
    1765           6 :         case ALIASINFONAME:
    1766           6 :                 alias_info->name.string                      = alias_name;
    1767           6 :                 break;
    1768           6 :         case ALIASINFODESCRIPTION:
    1769           6 :                 alias_info->description.string               = alias_description;
    1770           6 :                 break;
    1771           0 :         default:
    1772           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    1773             :         }
    1774             : 
    1775          17 :         *r->out.info = alias_info;
    1776             : 
    1777          17 :         DEBUG(5,("_samr_QueryAliasInfo: %d\n", __LINE__));
    1778             : 
    1779          17 :         return NT_STATUS_OK;
    1780             : }
    1781             : 
    1782             : /*******************************************************************
    1783             :  _samr_LookupNames
    1784             :  ********************************************************************/
    1785             : 
    1786        1046 : NTSTATUS _samr_LookupNames(struct pipes_struct *p,
    1787             :                            struct samr_LookupNames *r)
    1788             : {
    1789           0 :         struct samr_info *dinfo;
    1790           0 :         NTSTATUS status;
    1791           0 :         uint32_t *rid;
    1792           0 :         enum lsa_SidType *type;
    1793        1046 :         uint32_t i, num_rids = r->in.num_names;
    1794           0 :         struct samr_Ids rids, types;
    1795        1046 :         uint32_t num_mapped = 0;
    1796           0 :         struct dom_sid_buf buf;
    1797             : 
    1798        1046 :         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
    1799             : 
    1800        1046 :         dinfo = samr_policy_handle_find(p,
    1801        1046 :                                         r->in.domain_handle,
    1802             :                                         SAMR_HANDLE_DOMAIN,
    1803             :                                         0 /* Don't know the acc_bits yet */,
    1804             :                                         NULL,
    1805             :                                         &status);
    1806        1046 :         if (!NT_STATUS_IS_OK(status)) {
    1807           0 :                 return status;
    1808             :         }
    1809             : 
    1810        1046 :         if (num_rids > MAX_SAM_ENTRIES) {
    1811           0 :                 num_rids = MAX_SAM_ENTRIES;
    1812           0 :                 DEBUG(5,("_samr_LookupNames: truncating entries to %d\n", num_rids));
    1813             :         }
    1814             : 
    1815        1046 :         rid = talloc_array(p->mem_ctx, uint32_t, num_rids);
    1816        1046 :         NT_STATUS_HAVE_NO_MEMORY(rid);
    1817             : 
    1818        1046 :         type = talloc_array(p->mem_ctx, enum lsa_SidType, num_rids);
    1819        1046 :         NT_STATUS_HAVE_NO_MEMORY(type);
    1820             : 
    1821        1046 :         DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
    1822             :                  dom_sid_str_buf(&dinfo->sid, &buf)));
    1823             : 
    1824        2119 :         for (i = 0; i < num_rids; i++) {
    1825             : 
    1826        1073 :                 status = NT_STATUS_NONE_MAPPED;
    1827        1073 :                 type[i] = SID_NAME_UNKNOWN;
    1828             : 
    1829        1073 :                 rid[i] = 0xffffffff;
    1830             : 
    1831        1073 :                 if (sid_check_is_builtin(&dinfo->sid)) {
    1832           4 :                         if (lookup_builtin_name(r->in.names[i].string,
    1833           4 :                                                 &rid[i]))
    1834             :                         {
    1835           0 :                                 type[i] = SID_NAME_ALIAS;
    1836             :                         }
    1837             :                 } else {
    1838        1069 :                         lookup_global_sam_name(r->in.names[i].string, 0,
    1839        1069 :                                                &rid[i], &type[i]);
    1840             :                 }
    1841             : 
    1842        1073 :                 if (type[i] != SID_NAME_UNKNOWN) {
    1843         367 :                         num_mapped++;
    1844             :                 }
    1845             :         }
    1846             : 
    1847        1046 :         if (num_mapped == num_rids) {
    1848         368 :                 status = NT_STATUS_OK;
    1849         678 :         } else if (num_mapped == 0) {
    1850         650 :                 status = NT_STATUS_NONE_MAPPED;
    1851             :         } else {
    1852          28 :                 status = STATUS_SOME_UNMAPPED;
    1853             :         }
    1854             : 
    1855        1046 :         rids.count = num_rids;
    1856        1046 :         rids.ids = rid;
    1857             : 
    1858        1046 :         types.count = num_rids;
    1859        1046 :         types.ids = talloc_array(p->mem_ctx, uint32_t, num_rids);
    1860        1046 :         NT_STATUS_HAVE_NO_MEMORY(type);
    1861        2119 :         for (i = 0; i < num_rids; i++) {
    1862        1073 :                 types.ids[i] = (type[i] & 0xffffffff);
    1863             :         }
    1864             : 
    1865        1046 :         *r->out.rids = rids;
    1866        1046 :         *r->out.types = types;
    1867             : 
    1868        1046 :         DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
    1869             : 
    1870        1046 :         return status;
    1871             : }
    1872             : 
    1873             : /****************************************************************
    1874             :  _samr_ChangePasswordUser.
    1875             : 
    1876             :  So old it is just not worth implementing
    1877             :  because it does not supply a plaintext and so we can't do password
    1878             :  complexity checking and cannot update other services that use a
    1879             :  plaintext password via passwd chat/pam password change/ldap password
    1880             :  sync.
    1881             : ****************************************************************/
    1882             : 
    1883           2 : NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
    1884             :                                   struct samr_ChangePasswordUser *r)
    1885             : {
    1886           2 :         return NT_STATUS_NOT_IMPLEMENTED;
    1887             : }
    1888             : 
    1889             : /*******************************************************************
    1890             :  _samr_ChangePasswordUser2
    1891             :  ********************************************************************/
    1892             : 
    1893          11 : NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
    1894             :                                    struct samr_ChangePasswordUser2 *r)
    1895             : {
    1896          11 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1897          11 :         struct dcesrv_connection *dcesrv_conn = dce_call->conn;
    1898           0 :         const struct tsocket_address *remote_address =
    1899          11 :                 dcesrv_connection_get_remote_address(dcesrv_conn);
    1900           0 :         struct auth_session_info *session_info =
    1901          11 :                 dcesrv_call_session_info(dce_call);
    1902           0 :         NTSTATUS status;
    1903          11 :         char *user_name = NULL;
    1904           0 :         char *rhost;
    1905          11 :         const char *wks = NULL;
    1906           0 :         bool encrypted;
    1907             : 
    1908          11 :         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
    1909             : 
    1910          11 :         if (!r->in.account->string) {
    1911           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1912             :         }
    1913          11 :         if (r->in.server && r->in.server->string) {
    1914          11 :                 wks = r->in.server->string;
    1915             :         }
    1916             : 
    1917          11 :         DEBUG(5,("_samr_ChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
    1918             : 
    1919             :         /*
    1920             :          * Pass the user through the NT -> unix user mapping
    1921             :          * function.
    1922             :          */
    1923             : 
    1924          11 :         (void)map_username(talloc_tos(), r->in.account->string, &user_name);
    1925          11 :         if (!user_name) {
    1926           0 :                 return NT_STATUS_NO_MEMORY;
    1927             :         }
    1928             : 
    1929          11 :         rhost = tsocket_address_inet_addr_string(remote_address,
    1930             :                                                  talloc_tos());
    1931          11 :         if (rhost == NULL) {
    1932           0 :                 return NT_STATUS_NO_MEMORY;
    1933             :         }
    1934             : 
    1935          11 :         encrypted = dcerpc_is_transport_encrypted(session_info);
    1936          11 :         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
    1937           0 :             !encrypted) {
    1938           0 :                 return NT_STATUS_ACCESS_DENIED;
    1939             :         }
    1940             : 
    1941             :         /*
    1942             :          * UNIX username case mangling not required, pass_oem_change
    1943             :          * is case insensitive.
    1944             :          */
    1945             : 
    1946          11 :         status = pass_oem_change(user_name,
    1947             :                                  rhost,
    1948          11 :                                  r->in.lm_password->data,
    1949          11 :                                  r->in.lm_verifier->hash,
    1950          11 :                                  r->in.nt_password->data,
    1951          11 :                                  r->in.nt_verifier->hash,
    1952             :                                  NULL);
    1953             : 
    1954          11 :         DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
    1955             : 
    1956          11 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
    1957           0 :                 return NT_STATUS_WRONG_PASSWORD;
    1958             :         }
    1959             : 
    1960          11 :         return status;
    1961             : }
    1962             : 
    1963             : /****************************************************************
    1964             :  _samr_OemChangePasswordUser2
    1965             : ****************************************************************/
    1966             : 
    1967          16 : NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
    1968             :                                       struct samr_OemChangePasswordUser2 *r)
    1969             : {
    1970          16 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1971          16 :         struct dcesrv_connection *dcesrv_conn = dce_call->conn;
    1972           0 :         const struct tsocket_address *remote_address =
    1973          16 :                 dcesrv_connection_get_remote_address(dcesrv_conn);
    1974           0 :         struct auth_session_info *session_info =
    1975          16 :                 dcesrv_call_session_info(dce_call);
    1976           0 :         NTSTATUS status;
    1977          16 :         char *user_name = NULL;
    1978          16 :         const char *wks = NULL;
    1979           0 :         char *rhost;
    1980           0 :         bool encrypted;
    1981             : 
    1982          16 :         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
    1983             : 
    1984          16 :         if (!r->in.account->string) {
    1985           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1986             :         }
    1987          16 :         if (r->in.server && r->in.server->string) {
    1988          16 :                 wks = r->in.server->string;
    1989             :         }
    1990             : 
    1991          16 :         DEBUG(5,("_samr_OemChangePasswordUser2: user: %s wks: %s\n", user_name, wks));
    1992             : 
    1993             :         /*
    1994             :          * Pass the user through the NT -> unix user mapping
    1995             :          * function.
    1996             :          */
    1997             : 
    1998          16 :         (void)map_username(talloc_tos(), r->in.account->string, &user_name);
    1999          16 :         if (!user_name) {
    2000           0 :                 return NT_STATUS_NO_MEMORY;
    2001             :         }
    2002             : 
    2003             :         /*
    2004             :          * UNIX username case mangling not required, pass_oem_change
    2005             :          * is case insensitive.
    2006             :          */
    2007             : 
    2008          16 :         if (!r->in.hash || !r->in.password) {
    2009           6 :                 return NT_STATUS_INVALID_PARAMETER;
    2010             :         }
    2011             : 
    2012          10 :         rhost = tsocket_address_inet_addr_string(remote_address,
    2013             :                                                  talloc_tos());
    2014          10 :         if (rhost == NULL) {
    2015           0 :                 return NT_STATUS_NO_MEMORY;
    2016             :         }
    2017             : 
    2018          10 :         encrypted = dcerpc_is_transport_encrypted(session_info);
    2019          10 :         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
    2020           0 :             !encrypted) {
    2021           0 :                 return NT_STATUS_ACCESS_DENIED;
    2022             :         }
    2023             : 
    2024          10 :         status = pass_oem_change(user_name,
    2025             :                                  rhost,
    2026          10 :                                  r->in.password->data,
    2027          10 :                                  r->in.hash->hash,
    2028             :                                  0,
    2029             :                                  0,
    2030             :                                  NULL);
    2031             : 
    2032          10 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
    2033           2 :                 return NT_STATUS_WRONG_PASSWORD;
    2034             :         }
    2035             : 
    2036           8 :         DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
    2037             : 
    2038           8 :         return status;
    2039             : }
    2040             : 
    2041             : /*******************************************************************
    2042             :  _samr_ChangePasswordUser3
    2043             :  ********************************************************************/
    2044             : 
    2045         104 : NTSTATUS _samr_ChangePasswordUser3(struct pipes_struct *p,
    2046             :                                    struct samr_ChangePasswordUser3 *r)
    2047             : {
    2048         104 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2049         104 :         struct dcesrv_connection *dcesrv_conn = dce_call->conn;
    2050           0 :         const struct tsocket_address *remote_address =
    2051         104 :                 dcesrv_connection_get_remote_address(dcesrv_conn);
    2052           0 :         NTSTATUS status;
    2053         104 :         char *user_name = NULL;
    2054         104 :         const char *wks = NULL;
    2055           0 :         enum samPwdChangeReason reject_reason;
    2056         104 :         struct samr_DomInfo1 *dominfo = NULL;
    2057         104 :         struct userPwdChangeFailureInformation *reject = NULL;
    2058           0 :         const struct loadparm_substitution *lp_sub =
    2059         104 :                 loadparm_s3_global_substitution();
    2060           0 :         uint32_t tmp;
    2061           0 :         char *rhost;
    2062             : 
    2063         104 :         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
    2064             : 
    2065         104 :         if (!r->in.account->string) {
    2066           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2067             :         }
    2068         104 :         if (r->in.server && r->in.server->string) {
    2069         104 :                 wks = r->in.server->string;
    2070             :         }
    2071             : 
    2072         104 :         DEBUG(5,("_samr_ChangePasswordUser3: user: %s wks: %s\n", user_name, wks));
    2073             : 
    2074             :         /*
    2075             :          * Pass the user through the NT -> unix user mapping
    2076             :          * function.
    2077             :          */
    2078             : 
    2079         104 :         (void)map_username(talloc_tos(), r->in.account->string, &user_name);
    2080         104 :         if (!user_name) {
    2081           0 :                 return NT_STATUS_NO_MEMORY;
    2082             :         }
    2083             : 
    2084         104 :         rhost = tsocket_address_inet_addr_string(remote_address,
    2085             :                                                  talloc_tos());
    2086         104 :         if (rhost == NULL) {
    2087           0 :                 return NT_STATUS_NO_MEMORY;
    2088             :         }
    2089             : 
    2090             :         /*
    2091             :          * UNIX username case mangling not required, pass_oem_change
    2092             :          * is case insensitive.
    2093             :          */
    2094             : 
    2095         104 :         status = pass_oem_change(user_name,
    2096             :                                  rhost,
    2097         104 :                                  r->in.lm_password->data,
    2098         104 :                                  r->in.lm_verifier->hash,
    2099         104 :                                  r->in.nt_password->data,
    2100         104 :                                  r->in.nt_verifier->hash,
    2101             :                                  &reject_reason);
    2102         104 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
    2103          26 :                 return NT_STATUS_WRONG_PASSWORD;
    2104             :         }
    2105             : 
    2106          78 :         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) ||
    2107          76 :             NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_RESTRICTION)) {
    2108             : 
    2109           0 :                 time_t u_expire, u_min_age;
    2110           0 :                 uint32_t account_policy_temp;
    2111             : 
    2112           2 :                 dominfo = talloc_zero(p->mem_ctx, struct samr_DomInfo1);
    2113           2 :                 if (!dominfo) {
    2114           0 :                         return NT_STATUS_NO_MEMORY;
    2115             :                 }
    2116             : 
    2117           2 :                 reject = talloc_zero(p->mem_ctx,
    2118             :                                 struct userPwdChangeFailureInformation);
    2119           2 :                 if (!reject) {
    2120           0 :                         return NT_STATUS_NO_MEMORY;
    2121             :                 }
    2122             : 
    2123           2 :                 become_root();
    2124             : 
    2125             :                 /* AS ROOT !!! */
    2126             : 
    2127           2 :                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
    2128           2 :                 dominfo->min_password_length = tmp;
    2129             : 
    2130           2 :                 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
    2131           2 :                 dominfo->password_history_length = tmp;
    2132             : 
    2133           2 :                 pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
    2134             :                                        &dominfo->password_properties);
    2135             : 
    2136           2 :                 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
    2137           2 :                 u_expire = account_policy_temp;
    2138             : 
    2139           2 :                 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
    2140           2 :                 u_min_age = account_policy_temp;
    2141             : 
    2142             :                 /* !AS ROOT */
    2143             : 
    2144           2 :                 unbecome_root();
    2145             : 
    2146           2 :                 unix_to_nt_time_abs((NTTIME *)&dominfo->max_password_age, u_expire);
    2147           2 :                 unix_to_nt_time_abs((NTTIME *)&dominfo->min_password_age, u_min_age);
    2148             : 
    2149           2 :                 if (lp_check_password_script(talloc_tos(), lp_sub)
    2150           2 :                         && *lp_check_password_script(talloc_tos(), lp_sub)) {
    2151           0 :                         dominfo->password_properties |= DOMAIN_PASSWORD_COMPLEX;
    2152             :                 }
    2153             : 
    2154           2 :                 reject->extendedFailureReason = reject_reason;
    2155             : 
    2156           2 :                 *r->out.dominfo = dominfo;
    2157           2 :                 *r->out.reject = reject;
    2158             :         }
    2159             : 
    2160          78 :         DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__));
    2161             : 
    2162          78 :         return status;
    2163             : }
    2164             : 
    2165             : /*******************************************************************
    2166             : makes a SAMR_R_LOOKUP_RIDS structure.
    2167             : ********************************************************************/
    2168             : 
    2169        1265 : static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32_t num_names,
    2170             :                                   const char **names,
    2171             :                                   struct lsa_String **lsa_name_array_p)
    2172             : {
    2173        1265 :         struct lsa_String *lsa_name_array = NULL;
    2174           0 :         uint32_t i;
    2175             : 
    2176        1265 :         *lsa_name_array_p = NULL;
    2177             : 
    2178        1265 :         if (num_names != 0) {
    2179        1264 :                 lsa_name_array = talloc_zero_array(ctx, struct lsa_String, num_names);
    2180        1264 :                 if (!lsa_name_array) {
    2181           0 :                         return false;
    2182             :                 }
    2183             :         }
    2184             : 
    2185        2860 :         for (i = 0; i < num_names; i++) {
    2186        1595 :                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
    2187        1595 :                 init_lsa_String(&lsa_name_array[i], names[i]);
    2188             :         }
    2189             : 
    2190        1265 :         *lsa_name_array_p = lsa_name_array;
    2191             : 
    2192        1265 :         return true;
    2193             : }
    2194             : 
    2195             : /*******************************************************************
    2196             :  _samr_LookupRids
    2197             :  ********************************************************************/
    2198             : 
    2199        1265 : NTSTATUS _samr_LookupRids(struct pipes_struct *p,
    2200             :                           struct samr_LookupRids *r)
    2201             : {
    2202           0 :         struct samr_info *dinfo;
    2203           0 :         NTSTATUS status;
    2204           0 :         const char **names;
    2205        1265 :         enum lsa_SidType *attrs = NULL;
    2206        1265 :         uint32_t *wire_attrs = NULL;
    2207        1265 :         int num_rids = (int)r->in.num_rids;
    2208           0 :         int i;
    2209           0 :         struct lsa_Strings names_array;
    2210           0 :         struct samr_Ids types_array;
    2211        1265 :         struct lsa_String *lsa_names = NULL;
    2212             : 
    2213        1265 :         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
    2214             : 
    2215        1265 :         dinfo = samr_policy_handle_find(p,
    2216        1265 :                                         r->in.domain_handle,
    2217             :                                         SAMR_HANDLE_DOMAIN,
    2218             :                                         0 /* Don't know the acc_bits yet */,
    2219             :                                         NULL,
    2220             :                                         &status);
    2221        1265 :         if (!NT_STATUS_IS_OK(status)) {
    2222           0 :                 return status;
    2223             :         }
    2224             : 
    2225        1265 :         if (num_rids > 1000) {
    2226           0 :                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
    2227             :                           "to samba4 idl this is not possible\n", num_rids));
    2228           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2229             :         }
    2230             : 
    2231        1265 :         if (num_rids) {
    2232        1264 :                 names = talloc_zero_array(p->mem_ctx, const char *, num_rids);
    2233        1264 :                 attrs = talloc_zero_array(p->mem_ctx, enum lsa_SidType, num_rids);
    2234        1264 :                 wire_attrs = talloc_zero_array(p->mem_ctx, uint32_t, num_rids);
    2235             : 
    2236        1264 :                 if ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL))
    2237           0 :                         return NT_STATUS_NO_MEMORY;
    2238             :         } else {
    2239           1 :                 names = NULL;
    2240           1 :                 attrs = NULL;
    2241           1 :                 wire_attrs = NULL;
    2242             :         }
    2243             : 
    2244        1265 :         become_root();  /* lookup_sid can require root privs */
    2245        1265 :         status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
    2246             :                                  names, attrs);
    2247        1265 :         unbecome_root();
    2248             : 
    2249        1265 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) && (num_rids == 0)) {
    2250           1 :                 status = NT_STATUS_OK;
    2251             :         }
    2252             : 
    2253        1265 :         if (!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
    2254             :                                    &lsa_names)) {
    2255           0 :                 return NT_STATUS_NO_MEMORY;
    2256             :         }
    2257             : 
    2258             :         /* Convert from enum lsa_SidType to uint32_t for wire format. */
    2259        2860 :         for (i = 0; i < num_rids; i++) {
    2260        1595 :                 wire_attrs[i] = (uint32_t)attrs[i];
    2261             :         }
    2262             : 
    2263        1265 :         names_array.count = num_rids;
    2264        1265 :         names_array.names = lsa_names;
    2265             : 
    2266        1265 :         types_array.count = num_rids;
    2267        1265 :         types_array.ids = wire_attrs;
    2268             : 
    2269        1265 :         *r->out.names = names_array;
    2270        1265 :         *r->out.types = types_array;
    2271             : 
    2272        1265 :         DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
    2273             : 
    2274        1265 :         return status;
    2275             : }
    2276             : 
    2277             : /*******************************************************************
    2278             :  _samr_OpenUser
    2279             : ********************************************************************/
    2280             : 
    2281        2556 : NTSTATUS _samr_OpenUser(struct pipes_struct *p,
    2282             :                         struct samr_OpenUser *r)
    2283             : {
    2284        2556 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2285           0 :         struct auth_session_info *session_info =
    2286        2556 :                 dcesrv_call_session_info(dce_call);
    2287        2556 :         struct samu *sampass=NULL;
    2288           0 :         struct dom_sid sid;
    2289           0 :         struct samr_info *dinfo;
    2290        2556 :         struct security_descriptor *psd = NULL;
    2291           0 :         uint32_t    acc_granted;
    2292        2556 :         uint32_t    des_access = r->in.access_mask;
    2293        2556 :         uint32_t extra_access = 0;
    2294           0 :         size_t    sd_size;
    2295           0 :         bool ret;
    2296           0 :         NTSTATUS nt_status;
    2297             : 
    2298             :         /* These two privileges, if != SEC_PRIV_INVALID, indicate
    2299             :          * privileges that the user must have to complete this
    2300             :          * operation in defience of the fixed ACL */
    2301           0 :         enum sec_privilege needed_priv_1, needed_priv_2;
    2302           0 :         NTSTATUS status;
    2303             : 
    2304        2556 :         dinfo = samr_policy_handle_find(p,
    2305        2556 :                                         r->in.domain_handle,
    2306             :                                         SAMR_HANDLE_DOMAIN,
    2307             :                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
    2308             :                                         NULL,
    2309             :                                         &status);
    2310        2556 :         if (!NT_STATUS_IS_OK(status)) {
    2311           1 :                 return status;
    2312             :         }
    2313             : 
    2314        2555 :         if ( !(sampass = samu_new( p->mem_ctx )) ) {
    2315           0 :                 return NT_STATUS_NO_MEMORY;
    2316             :         }
    2317             : 
    2318             :         /* append the user's RID to it */
    2319             : 
    2320        2555 :         if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
    2321           0 :                 return NT_STATUS_NO_SUCH_USER;
    2322             : 
    2323             :         /* check if access can be granted as requested by client. */
    2324        2555 :         map_max_allowed_access(session_info->security_token,
    2325        2555 :                                session_info->unix_token,
    2326             :                                &des_access);
    2327             : 
    2328        2555 :         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
    2329        2555 :         se_map_generic(&des_access, &usr_generic_mapping);
    2330             : 
    2331             :         /*
    2332             :          * Get the sampass first as we need to check privileges
    2333             :          * based on what kind of user object this is.
    2334             :          * But don't reveal info too early if it didn't exist.
    2335             :          */
    2336             : 
    2337        2555 :         become_root();
    2338        2555 :         ret=pdb_getsampwsid(sampass, &sid);
    2339        2555 :         unbecome_root();
    2340             : 
    2341        2555 :         needed_priv_1 = SEC_PRIV_INVALID;
    2342        2555 :         needed_priv_2 = SEC_PRIV_INVALID;
    2343             :         /*
    2344             :          * We do the override access checks on *open*, not at
    2345             :          * SetUserInfo time.
    2346             :          */
    2347        2555 :         if (ret) {
    2348        2555 :                 uint32_t acb_info = pdb_get_acct_ctrl(sampass);
    2349             : 
    2350        2555 :                 if (acb_info & ACB_WSTRUST) {
    2351             :                         /*
    2352             :                          * SeMachineAccount is needed to add
    2353             :                          * GENERIC_RIGHTS_USER_WRITE to a machine
    2354             :                          * account.
    2355             :                          */
    2356          97 :                         needed_priv_1 = SEC_PRIV_MACHINE_ACCOUNT;
    2357             :                 }
    2358        2555 :                 if (acb_info & ACB_NORMAL) {
    2359             :                         /*
    2360             :                          * SeAddUsers is needed to add
    2361             :                          * GENERIC_RIGHTS_USER_WRITE to a normal
    2362             :                          * account.
    2363             :                          */
    2364        2386 :                         needed_priv_1 = SEC_PRIV_ADD_USERS;
    2365             :                 }
    2366             :                 /*
    2367             :                  * Cheat - we have not set a specific privilege for
    2368             :                  * server (BDC) or domain trust account, so allow
    2369             :                  * GENERIC_RIGHTS_USER_WRITE if pipe user is in
    2370             :                  * DOMAIN_RID_ADMINS.
    2371             :                  */
    2372        2555 :                 if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
    2373         144 :                         if (lp_enable_privileges() &&
    2374          72 :                             nt_token_check_domain_rid(
    2375             :                                     session_info->security_token,
    2376             :                                     DOMAIN_RID_ADMINS)) {
    2377           0 :                                 des_access &= ~GENERIC_RIGHTS_USER_WRITE;
    2378           0 :                                 extra_access = GENERIC_RIGHTS_USER_WRITE;
    2379           0 :                                 DEBUG(4,("_samr_OpenUser: Allowing "
    2380             :                                         "GENERIC_RIGHTS_USER_WRITE for "
    2381             :                                         "rid admins\n"));
    2382             :                         }
    2383             :                 }
    2384             :         }
    2385             : 
    2386        2555 :         TALLOC_FREE(sampass);
    2387             : 
    2388        2555 :         nt_status = access_check_object(psd, session_info->security_token,
    2389             :                                         needed_priv_1, needed_priv_2,
    2390             :                                         GENERIC_RIGHTS_USER_WRITE, des_access,
    2391             :                                         &acc_granted, "_samr_OpenUser");
    2392             : 
    2393        2555 :         if ( !NT_STATUS_IS_OK(nt_status) )
    2394           0 :                 return nt_status;
    2395             : 
    2396             :         /* check that the SID exists in our domain. */
    2397        2555 :         if (ret == False) {
    2398           0 :                 return NT_STATUS_NO_SUCH_USER;
    2399             :         }
    2400             : 
    2401             :         /* If we did the rid admins hack above, allow access. */
    2402        2555 :         acc_granted |= extra_access;
    2403             : 
    2404        2555 :         status = create_samr_policy_handle(p->mem_ctx,
    2405             :                                            p,
    2406             :                                            SAMR_HANDLE_USER,
    2407             :                                            acc_granted,
    2408             :                                            &sid,
    2409             :                                            NULL,
    2410             :                                            r->out.user_handle);
    2411        2555 :         if (!NT_STATUS_IS_OK(status)) {
    2412           0 :                 return status;
    2413             :         }
    2414             : 
    2415        2555 :         return NT_STATUS_OK;
    2416             : }
    2417             : 
    2418             : /*************************************************************************
    2419             :  *************************************************************************/
    2420             : 
    2421         614 : static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
    2422             :                                             DATA_BLOB *blob,
    2423             :                                             struct lsa_BinaryString **_r)
    2424             : {
    2425           0 :         struct lsa_BinaryString *r;
    2426             : 
    2427         614 :         if (!blob || !_r) {
    2428           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2429             :         }
    2430             : 
    2431         614 :         r = talloc_zero(mem_ctx, struct lsa_BinaryString);
    2432         614 :         if (!r) {
    2433           0 :                 return NT_STATUS_NO_MEMORY;
    2434             :         }
    2435             : 
    2436         614 :         r->array = talloc_zero_array(mem_ctx, uint16_t, blob->length/2);
    2437         614 :         if (!r->array) {
    2438           0 :                 return NT_STATUS_NO_MEMORY;
    2439             :         }
    2440         614 :         memcpy(r->array, blob->data, blob->length);
    2441         614 :         r->size = blob->length;
    2442         614 :         r->length = blob->length;
    2443             : 
    2444         614 :         if (!r->array) {
    2445           0 :                 return NT_STATUS_NO_MEMORY;
    2446             :         }
    2447             : 
    2448         614 :         *_r = r;
    2449             : 
    2450         614 :         return NT_STATUS_OK;
    2451             : }
    2452             : 
    2453             : /*************************************************************************
    2454             :  *************************************************************************/
    2455             : 
    2456         977 : static struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
    2457             :                                                        struct samu *pw)
    2458             : {
    2459           0 :         struct samr_LogonHours hours;
    2460         977 :         const int units_per_week = 168;
    2461             : 
    2462         977 :         ZERO_STRUCT(hours);
    2463         977 :         hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
    2464         977 :         if (!hours.bits) {
    2465           0 :                 return hours;
    2466             :         }
    2467             : 
    2468         977 :         hours.units_per_week = units_per_week;
    2469         977 :         memset(hours.bits, 0xFF, units_per_week);
    2470             : 
    2471         977 :         if (pdb_get_hours(pw)) {
    2472         977 :                 memcpy(hours.bits, pdb_get_hours(pw),
    2473         977 :                        MIN(pdb_get_hours_len(pw), units_per_week));
    2474             :         }
    2475             : 
    2476         977 :         return hours;
    2477             : }
    2478             : 
    2479             : /*************************************************************************
    2480             :  get_user_info_1.
    2481             :  *************************************************************************/
    2482             : 
    2483          48 : static NTSTATUS get_user_info_1(TALLOC_CTX *mem_ctx,
    2484             :                                 struct samr_UserInfo1 *r,
    2485             :                                 struct samu *pw,
    2486             :                                 struct dom_sid *domain_sid)
    2487             : {
    2488           0 :         const struct dom_sid *sid_group;
    2489           0 :         uint32_t primary_gid;
    2490             : 
    2491          48 :         become_root();
    2492          48 :         sid_group = pdb_get_group_sid(pw);
    2493          48 :         unbecome_root();
    2494             : 
    2495          48 :         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
    2496           0 :                 struct dom_sid_buf buf1, buf2;
    2497             : 
    2498           0 :                 DEBUG(0, ("get_user_info_1: User %s has Primary Group SID %s, \n"
    2499             :                           "which conflicts with the domain sid %s.  Failing operation.\n",
    2500             :                           pdb_get_username(pw),
    2501             :                           dom_sid_str_buf(sid_group, &buf1),
    2502             :                           dom_sid_str_buf(domain_sid, &buf2)));
    2503           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2504             :         }
    2505             : 
    2506          48 :         r->account_name.string               = talloc_strdup(mem_ctx, pdb_get_username(pw));
    2507          48 :         r->full_name.string          = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
    2508          48 :         r->primary_gid                       = primary_gid;
    2509          48 :         r->description.string                = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
    2510          48 :         r->comment.string            = talloc_strdup(mem_ctx, pdb_get_comment(pw));
    2511             : 
    2512          48 :         return NT_STATUS_OK;
    2513             : }
    2514             : 
    2515             : /*************************************************************************
    2516             :  get_user_info_2.
    2517             :  *************************************************************************/
    2518             : 
    2519           8 : static NTSTATUS get_user_info_2(TALLOC_CTX *mem_ctx,
    2520             :                                 struct samr_UserInfo2 *r,
    2521             :                                 struct samu *pw)
    2522             : {
    2523           8 :         r->comment.string            = talloc_strdup(mem_ctx, pdb_get_comment(pw));
    2524           8 :         r->reserved.string           = NULL;
    2525           8 :         r->country_code                      = pdb_get_country_code(pw);
    2526           8 :         r->code_page                 = pdb_get_code_page(pw);
    2527             : 
    2528           8 :         return NT_STATUS_OK;
    2529             : }
    2530             : 
    2531             : /*************************************************************************
    2532             :  get_user_info_3.
    2533             :  *************************************************************************/
    2534             : 
    2535         177 : static NTSTATUS get_user_info_3(TALLOC_CTX *mem_ctx,
    2536             :                                 struct samr_UserInfo3 *r,
    2537             :                                 struct samu *pw,
    2538             :                                 struct dom_sid *domain_sid)
    2539             : {
    2540           0 :         const struct dom_sid *sid_user, *sid_group;
    2541           0 :         uint32_t rid, primary_gid;
    2542           0 :         struct dom_sid_buf buf1, buf2;
    2543             : 
    2544         177 :         sid_user = pdb_get_user_sid(pw);
    2545             : 
    2546         177 :         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
    2547           0 :                 DEBUG(0, ("get_user_info_3: User %s has SID %s, \nwhich conflicts with "
    2548             :                           "the domain sid %s.  Failing operation.\n",
    2549             :                           pdb_get_username(pw),
    2550             :                           dom_sid_str_buf(sid_user, &buf1),
    2551             :                           dom_sid_str_buf(domain_sid, &buf2)));
    2552           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2553             :         }
    2554             : 
    2555         177 :         become_root();
    2556         177 :         sid_group = pdb_get_group_sid(pw);
    2557         177 :         unbecome_root();
    2558             : 
    2559         177 :         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
    2560           0 :                 DEBUG(0, ("get_user_info_3: User %s has Primary Group SID %s, \n"
    2561             :                           "which conflicts with the domain sid %s.  Failing operation.\n",
    2562             :                           pdb_get_username(pw),
    2563             :                           dom_sid_str_buf(sid_group, &buf1),
    2564             :                           dom_sid_str_buf(domain_sid, &buf2)));
    2565           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2566             :         }
    2567             : 
    2568         177 :         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
    2569         177 :         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
    2570         177 :         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
    2571         177 :         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
    2572         177 :         unix_to_nt_time(&r->force_password_change, pdb_get_pass_must_change_time(pw));
    2573             : 
    2574         177 :         r->account_name.string       = talloc_strdup(mem_ctx, pdb_get_username(pw));
    2575         177 :         r->full_name.string  = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
    2576         177 :         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
    2577         177 :         r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
    2578         177 :         r->logon_script.string       = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
    2579         177 :         r->profile_path.string       = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
    2580         177 :         r->workstations.string       = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
    2581             : 
    2582         177 :         r->logon_hours               = get_logon_hours_from_pdb(mem_ctx, pw);
    2583         177 :         r->rid                       = rid;
    2584         177 :         r->primary_gid               = primary_gid;
    2585         177 :         r->acct_flags                = pdb_get_acct_ctrl(pw);
    2586         177 :         r->bad_password_count        = pdb_get_bad_password_count(pw);
    2587         177 :         r->logon_count               = pdb_get_logon_count(pw);
    2588             : 
    2589         177 :         return NT_STATUS_OK;
    2590             : }
    2591             : 
    2592             : /*************************************************************************
    2593             :  get_user_info_4.
    2594             :  *************************************************************************/
    2595             : 
    2596          10 : static NTSTATUS get_user_info_4(TALLOC_CTX *mem_ctx,
    2597             :                                 struct samr_UserInfo4 *r,
    2598             :                                 struct samu *pw)
    2599             : {
    2600          10 :         r->logon_hours               = get_logon_hours_from_pdb(mem_ctx, pw);
    2601             : 
    2602          10 :         return NT_STATUS_OK;
    2603             : }
    2604             : 
    2605             : /*************************************************************************
    2606             :  get_user_info_5.
    2607             :  *************************************************************************/
    2608             : 
    2609         186 : static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
    2610             :                                 struct samr_UserInfo5 *r,
    2611             :                                 struct samu *pw,
    2612             :                                 struct dom_sid *domain_sid)
    2613             : {
    2614           0 :         const struct dom_sid *sid_user, *sid_group;
    2615           0 :         uint32_t rid, primary_gid;
    2616           0 :         struct dom_sid_buf buf1, buf2;
    2617             : 
    2618         186 :         sid_user = pdb_get_user_sid(pw);
    2619             : 
    2620         186 :         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
    2621           0 :                 DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
    2622             :                           "the domain sid %s.  Failing operation.\n",
    2623             :                           pdb_get_username(pw),
    2624             :                           dom_sid_str_buf(sid_user, &buf1),
    2625             :                           dom_sid_str_buf(domain_sid, &buf2)));
    2626           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2627             :         }
    2628             : 
    2629         186 :         become_root();
    2630         186 :         sid_group = pdb_get_group_sid(pw);
    2631         186 :         unbecome_root();
    2632             : 
    2633         186 :         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
    2634           0 :                 DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
    2635             :                           "which conflicts with the domain sid %s.  Failing operation.\n",
    2636             :                           pdb_get_username(pw),
    2637             :                           dom_sid_str_buf(sid_group, &buf1),
    2638             :                           dom_sid_str_buf(domain_sid, &buf2)));
    2639           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2640             :         }
    2641             : 
    2642         186 :         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
    2643         186 :         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
    2644         186 :         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
    2645         186 :         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
    2646             : 
    2647         186 :         r->account_name.string       = talloc_strdup(mem_ctx, pdb_get_username(pw));
    2648         186 :         r->full_name.string  = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
    2649         186 :         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
    2650         186 :         r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
    2651         186 :         r->logon_script.string       = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
    2652         186 :         r->profile_path.string       = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
    2653         186 :         r->description.string        = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
    2654         186 :         r->workstations.string       = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
    2655             : 
    2656         186 :         r->logon_hours               = get_logon_hours_from_pdb(mem_ctx, pw);
    2657         186 :         r->rid                       = rid;
    2658         186 :         r->primary_gid               = primary_gid;
    2659         186 :         r->acct_flags                = pdb_get_acct_ctrl(pw);
    2660         186 :         r->bad_password_count        = pdb_get_bad_password_count(pw);
    2661         186 :         r->logon_count               = pdb_get_logon_count(pw);
    2662             : 
    2663         186 :         return NT_STATUS_OK;
    2664             : }
    2665             : 
    2666             : /*************************************************************************
    2667             :  get_user_info_6.
    2668             :  *************************************************************************/
    2669             : 
    2670          30 : static NTSTATUS get_user_info_6(TALLOC_CTX *mem_ctx,
    2671             :                                 struct samr_UserInfo6 *r,
    2672             :                                 struct samu *pw)
    2673             : {
    2674          30 :         r->account_name.string       = talloc_strdup(mem_ctx, pdb_get_username(pw));
    2675          30 :         r->full_name.string  = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
    2676             : 
    2677          30 :         return NT_STATUS_OK;
    2678             : }
    2679             : 
    2680             : /*************************************************************************
    2681             :  get_user_info_7. Safe. Only gives out account_name.
    2682             :  *************************************************************************/
    2683             : 
    2684          10 : static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
    2685             :                                 struct samr_UserInfo7 *r,
    2686             :                                 struct samu *smbpass)
    2687             : {
    2688          10 :         r->account_name.string = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
    2689          10 :         if (!r->account_name.string) {
    2690           0 :                 return NT_STATUS_NO_MEMORY;
    2691             :         }
    2692             : 
    2693          10 :         return NT_STATUS_OK;
    2694             : }
    2695             : 
    2696             : /*************************************************************************
    2697             :  get_user_info_8.
    2698             :  *************************************************************************/
    2699             : 
    2700          10 : static NTSTATUS get_user_info_8(TALLOC_CTX *mem_ctx,
    2701             :                                 struct samr_UserInfo8 *r,
    2702             :                                 struct samu *pw)
    2703             : {
    2704          10 :         r->full_name.string  = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
    2705             : 
    2706          10 :         return NT_STATUS_OK;
    2707             : }
    2708             : 
    2709             : /*************************************************************************
    2710             :  get_user_info_9. Only gives out primary group SID.
    2711             :  *************************************************************************/
    2712             : 
    2713           4 : static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
    2714             :                                 struct samr_UserInfo9 *r,
    2715             :                                 struct samu *smbpass)
    2716             : {
    2717           4 :         r->primary_gid = pdb_get_group_rid(smbpass);
    2718             : 
    2719           4 :         return NT_STATUS_OK;
    2720             : }
    2721             : 
    2722             : /*************************************************************************
    2723             :  get_user_info_10.
    2724             :  *************************************************************************/
    2725             : 
    2726          18 : static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx,
    2727             :                                  struct samr_UserInfo10 *r,
    2728             :                                  struct samu *pw)
    2729             : {
    2730          18 :         r->home_directory.string= talloc_strdup(mem_ctx, pdb_get_homedir(pw));
    2731          18 :         r->home_drive.string = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
    2732             : 
    2733          18 :         return NT_STATUS_OK;
    2734             : }
    2735             : 
    2736             : /*************************************************************************
    2737             :  get_user_info_11.
    2738             :  *************************************************************************/
    2739             : 
    2740          10 : static NTSTATUS get_user_info_11(TALLOC_CTX *mem_ctx,
    2741             :                                  struct samr_UserInfo11 *r,
    2742             :                                  struct samu *pw)
    2743             : {
    2744          10 :         r->logon_script.string       = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
    2745             : 
    2746          10 :         return NT_STATUS_OK;
    2747             : }
    2748             : 
    2749             : /*************************************************************************
    2750             :  get_user_info_12.
    2751             :  *************************************************************************/
    2752             : 
    2753          11 : static NTSTATUS get_user_info_12(TALLOC_CTX *mem_ctx,
    2754             :                                  struct samr_UserInfo12 *r,
    2755             :                                  struct samu *pw)
    2756             : {
    2757          11 :         r->profile_path.string       = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
    2758             : 
    2759          11 :         return NT_STATUS_OK;
    2760             : }
    2761             : 
    2762             : /*************************************************************************
    2763             :  get_user_info_13.
    2764             :  *************************************************************************/
    2765             : 
    2766          10 : static NTSTATUS get_user_info_13(TALLOC_CTX *mem_ctx,
    2767             :                                  struct samr_UserInfo13 *r,
    2768             :                                  struct samu *pw)
    2769             : {
    2770          10 :         r->description.string        = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
    2771             : 
    2772          10 :         return NT_STATUS_OK;
    2773             : }
    2774             : 
    2775             : /*************************************************************************
    2776             :  get_user_info_14.
    2777             :  *************************************************************************/
    2778             : 
    2779          11 : static NTSTATUS get_user_info_14(TALLOC_CTX *mem_ctx,
    2780             :                                  struct samr_UserInfo14 *r,
    2781             :                                  struct samu *pw)
    2782             : {
    2783          11 :         r->workstations.string       = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
    2784             : 
    2785          11 :         return NT_STATUS_OK;
    2786             : }
    2787             : 
    2788             : /*************************************************************************
    2789             :  get_user_info_16. Safe. Only gives out acb bits.
    2790             :  *************************************************************************/
    2791             : 
    2792         569 : static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
    2793             :                                  struct samr_UserInfo16 *r,
    2794             :                                  struct samu *smbpass)
    2795             : {
    2796         569 :         r->acct_flags = pdb_get_acct_ctrl(smbpass);
    2797             : 
    2798         569 :         return NT_STATUS_OK;
    2799             : }
    2800             : 
    2801             : /*************************************************************************
    2802             :  get_user_info_17.
    2803             :  *************************************************************************/
    2804             : 
    2805           9 : static NTSTATUS get_user_info_17(TALLOC_CTX *mem_ctx,
    2806             :                                  struct samr_UserInfo17 *r,
    2807             :                                  struct samu *pw)
    2808             : {
    2809           9 :         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
    2810             : 
    2811           9 :         return NT_STATUS_OK;
    2812             : }
    2813             : 
    2814             : /*************************************************************************
    2815             :  get_user_info_18. OK - this is the killer as it gives out password info.
    2816             :  Ensure that this is only allowed on an encrypted connection with a root
    2817             :  user. JRA.
    2818             :  *************************************************************************/
    2819             : 
    2820         133 : static NTSTATUS get_user_info_18(struct pipes_struct *p,
    2821             :                                  TALLOC_CTX *mem_ctx,
    2822             :                                  struct samr_UserInfo18 *r,
    2823             :                                  struct dom_sid *user_sid)
    2824             : {
    2825         133 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2826           0 :         struct auth_session_info *session_info =
    2827         133 :                 dcesrv_call_session_info(dce_call);
    2828         133 :         struct samu *smbpass=NULL;
    2829           0 :         bool ret;
    2830         133 :         const uint8_t *nt_pass = NULL;
    2831         133 :         const uint8_t *lm_pass = NULL;
    2832             : 
    2833         133 :         ZERO_STRUCTP(r);
    2834             : 
    2835         133 :         if (p->transport != NCALRPC) {
    2836           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    2837             :         }
    2838             : 
    2839         133 :         if (!security_token_is_system(session_info->security_token)) {
    2840           0 :                 return NT_STATUS_ACCESS_DENIED;
    2841             :         }
    2842             : 
    2843             :         /*
    2844             :          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
    2845             :          */
    2846             : 
    2847         133 :         if ( !(smbpass = samu_new( mem_ctx )) ) {
    2848           0 :                 return NT_STATUS_NO_MEMORY;
    2849             :         }
    2850             : 
    2851         133 :         ret = pdb_getsampwsid(smbpass, user_sid);
    2852             : 
    2853         133 :         if (ret == False) {
    2854           0 :                 struct dom_sid_buf buf;
    2855           0 :                 DEBUG(4, ("User %s not found\n",
    2856             :                           dom_sid_str_buf(user_sid, &buf)));
    2857           0 :                 TALLOC_FREE(smbpass);
    2858           0 :                 return root_mode() ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
    2859             :         }
    2860             : 
    2861         133 :         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
    2862             : 
    2863         133 :         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
    2864           0 :                 TALLOC_FREE(smbpass);
    2865           0 :                 return NT_STATUS_ACCOUNT_DISABLED;
    2866             :         }
    2867             : 
    2868         133 :         lm_pass = pdb_get_lanman_passwd(smbpass);
    2869         133 :         if (lm_pass != NULL) {
    2870           2 :                 memcpy(r->lm_pwd.hash, lm_pass, 16);
    2871           2 :                 r->lm_pwd_active = true;
    2872             :         }
    2873             : 
    2874         133 :         nt_pass = pdb_get_nt_passwd(smbpass);
    2875         133 :         if (nt_pass != NULL) {
    2876         133 :                 memcpy(r->nt_pwd.hash, nt_pass, 16);
    2877         133 :                 r->nt_pwd_active = true;
    2878             :         }
    2879         133 :         r->password_expired = 0; /* FIXME */
    2880             : 
    2881         133 :         TALLOC_FREE(smbpass);
    2882             : 
    2883         133 :         return NT_STATUS_OK;
    2884             : }
    2885             : 
    2886             : /*************************************************************************
    2887             :  get_user_info_20
    2888             :  *************************************************************************/
    2889             : 
    2890          10 : static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
    2891             :                                  struct samr_UserInfo20 *r,
    2892             :                                  struct samu *sampass)
    2893             : {
    2894          10 :         const char *munged_dial = NULL;
    2895           0 :         DATA_BLOB blob;
    2896           0 :         NTSTATUS status;
    2897          10 :         struct lsa_BinaryString *parameters = NULL;
    2898             : 
    2899          10 :         ZERO_STRUCTP(r);
    2900             : 
    2901          10 :         munged_dial = pdb_get_munged_dial(sampass);
    2902             : 
    2903          10 :         DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
    2904             :                 munged_dial, (int)strlen(munged_dial)));
    2905             : 
    2906          10 :         if (munged_dial) {
    2907          10 :                 blob = base64_decode_data_blob(munged_dial);
    2908             :         } else {
    2909           0 :                 blob = data_blob_string_const_null("");
    2910             :         }
    2911             : 
    2912          10 :         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
    2913          10 :         data_blob_free(&blob);
    2914          10 :         if (!NT_STATUS_IS_OK(status)) {
    2915           0 :                 return status;
    2916             :         }
    2917             : 
    2918          10 :         r->parameters = *parameters;
    2919             : 
    2920          10 :         return NT_STATUS_OK;
    2921             : }
    2922             : 
    2923             : 
    2924             : /*************************************************************************
    2925             :  get_user_info_21
    2926             :  *************************************************************************/
    2927             : 
    2928         604 : static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
    2929             :                                  struct samr_UserInfo21 *r,
    2930             :                                  struct samu *pw,
    2931             :                                  struct dom_sid *domain_sid,
    2932             :                                  uint32_t acc_granted)
    2933             : {
    2934           0 :         NTSTATUS status;
    2935           0 :         const struct dom_sid *sid_user, *sid_group;
    2936           0 :         uint32_t rid, primary_gid;
    2937           0 :         NTTIME force_password_change;
    2938           0 :         time_t must_change_time;
    2939         604 :         struct lsa_BinaryString *parameters = NULL;
    2940         604 :         const char *munged_dial = NULL;
    2941           0 :         DATA_BLOB blob;
    2942           0 :         struct dom_sid_buf buf1, buf2;
    2943             : 
    2944         604 :         ZERO_STRUCTP(r);
    2945             : 
    2946         604 :         sid_user = pdb_get_user_sid(pw);
    2947             : 
    2948         604 :         if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
    2949           0 :                 DEBUG(0, ("get_user_info_21: User %s has SID %s, \nwhich conflicts with "
    2950             :                           "the domain sid %s.  Failing operation.\n",
    2951             :                           pdb_get_username(pw),
    2952             :                           dom_sid_str_buf(sid_user, &buf1),
    2953             :                           dom_sid_str_buf(domain_sid, &buf2)));
    2954           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2955             :         }
    2956             : 
    2957         604 :         become_root();
    2958         604 :         sid_group = pdb_get_group_sid(pw);
    2959         604 :         unbecome_root();
    2960             : 
    2961         604 :         if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
    2962           0 :                 DEBUG(0, ("get_user_info_21: User %s has Primary Group SID %s, \n"
    2963             :                           "which conflicts with the domain sid %s.  Failing operation.\n",
    2964             :                           pdb_get_username(pw),
    2965             :                           dom_sid_str_buf(sid_group, &buf1),
    2966             :                           dom_sid_str_buf(domain_sid, &buf2)));
    2967           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2968             :         }
    2969             : 
    2970         604 :         unix_to_nt_time(&r->last_logon, pdb_get_logon_time(pw));
    2971         604 :         unix_to_nt_time(&r->last_logoff, pdb_get_logoff_time(pw));
    2972         604 :         unix_to_nt_time(&r->acct_expiry, pdb_get_kickoff_time(pw));
    2973         604 :         unix_to_nt_time(&r->last_password_change, pdb_get_pass_last_set_time(pw));
    2974         604 :         unix_to_nt_time(&r->allow_password_change, pdb_get_pass_can_change_time(pw));
    2975             : 
    2976         604 :         must_change_time = pdb_get_pass_must_change_time(pw);
    2977         604 :         if (pdb_is_password_change_time_max(must_change_time)) {
    2978         140 :                 unix_to_nt_time_abs(&force_password_change, must_change_time);
    2979             :         } else {
    2980         464 :                 unix_to_nt_time(&force_password_change, must_change_time);
    2981             :         }
    2982             : 
    2983         604 :         munged_dial = pdb_get_munged_dial(pw);
    2984         604 :         if (munged_dial) {
    2985         604 :                 blob = base64_decode_data_blob(munged_dial);
    2986             :         } else {
    2987           0 :                 blob = data_blob_string_const_null("");
    2988             :         }
    2989             : 
    2990         604 :         status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
    2991         604 :         data_blob_free(&blob);
    2992         604 :         if (!NT_STATUS_IS_OK(status)) {
    2993           0 :                 return status;
    2994             :         }
    2995             : 
    2996         604 :         r->force_password_change     = force_password_change;
    2997             : 
    2998         604 :         r->account_name.string               = talloc_strdup(mem_ctx, pdb_get_username(pw));
    2999         604 :         r->full_name.string          = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
    3000         604 :         r->home_directory.string     = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
    3001         604 :         r->home_drive.string         = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
    3002         604 :         r->logon_script.string               = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
    3003         604 :         r->profile_path.string               = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
    3004         604 :         r->description.string                = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
    3005         604 :         r->workstations.string               = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
    3006         604 :         r->comment.string            = talloc_strdup(mem_ctx, pdb_get_comment(pw));
    3007             : 
    3008         604 :         r->logon_hours                       = get_logon_hours_from_pdb(mem_ctx, pw);
    3009         604 :         r->parameters                        = *parameters;
    3010         604 :         r->rid                               = rid;
    3011         604 :         r->primary_gid                       = primary_gid;
    3012         604 :         r->acct_flags                        = pdb_get_acct_ctrl(pw);
    3013         604 :         r->bad_password_count                = pdb_get_bad_password_count(pw);
    3014         604 :         r->logon_count                       = pdb_get_logon_count(pw);
    3015         604 :         r->fields_present            = pdb_build_fields_present(pw);
    3016         604 :         r->password_expired          = (pdb_get_pass_must_change_time(pw) == 0) ?
    3017         604 :                                                 PASS_MUST_CHANGE_AT_NEXT_LOGON : 0;
    3018         604 :         r->country_code                      = pdb_get_country_code(pw);
    3019         604 :         r->code_page                 = pdb_get_code_page(pw);
    3020         604 :         r->lm_password_set           = 0;
    3021         604 :         r->nt_password_set           = 0;
    3022             : 
    3023             : #if 0
    3024             : 
    3025             :         /*
    3026             :           Look at a user on a real NT4 PDC with usrmgr, press
    3027             :           'ok'. Then you will see that fields_present is set to
    3028             :           0x08f827fa. Look at the user immediately after that again,
    3029             :           and you will see that 0x00fffff is returned. This solves
    3030             :           the problem that you get access denied after having looked
    3031             :           at the user.
    3032             :           -- Volker
    3033             :         */
    3034             : 
    3035             : #endif
    3036             : 
    3037             : 
    3038         604 :         return NT_STATUS_OK;
    3039             : }
    3040             : 
    3041             : /*******************************************************************
    3042             :  _samr_QueryUserInfo
    3043             :  ********************************************************************/
    3044             : 
    3045        1868 : NTSTATUS _samr_QueryUserInfo(struct pipes_struct *p,
    3046             :                              struct samr_QueryUserInfo *r)
    3047             : {
    3048           0 :         NTSTATUS status;
    3049        1868 :         union samr_UserInfo *user_info = NULL;
    3050           0 :         struct samr_info *uinfo;
    3051           0 :         struct dom_sid domain_sid;
    3052           0 :         uint32_t rid;
    3053        1868 :         bool ret = false;
    3054        1868 :         struct samu *pwd = NULL;
    3055           0 :         uint32_t acc_required, acc_granted;
    3056           0 :         struct dom_sid_buf buf;
    3057             : 
    3058        1868 :         switch (r->in.level) {
    3059          48 :         case 1: /* UserGeneralInformation */
    3060             :                 /* USER_READ_GENERAL */
    3061          48 :                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
    3062          48 :                 break;
    3063           8 :         case 2: /* UserPreferencesInformation */
    3064             :                 /* USER_READ_PREFERENCES | USER_READ_GENERAL */
    3065           8 :                 acc_required = SAMR_USER_ACCESS_GET_LOCALE |
    3066             :                                SAMR_USER_ACCESS_GET_NAME_ETC;
    3067           8 :                 break;
    3068         177 :         case 3: /* UserLogonInformation */
    3069             :                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
    3070         177 :                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
    3071             :                                SAMR_USER_ACCESS_GET_LOCALE |
    3072             :                                SAMR_USER_ACCESS_GET_LOGONINFO |
    3073             :                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
    3074         177 :                 break;
    3075          10 :         case 4: /* UserLogonHoursInformation */
    3076             :                 /* USER_READ_LOGON */
    3077          10 :                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
    3078          10 :                 break;
    3079         186 :         case 5: /* UserAccountInformation */
    3080             :                 /* USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT */
    3081         186 :                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC |
    3082             :                                SAMR_USER_ACCESS_GET_LOCALE |
    3083             :                                SAMR_USER_ACCESS_GET_LOGONINFO |
    3084             :                                SAMR_USER_ACCESS_GET_ATTRIBUTES;
    3085         186 :                 break;
    3086          64 :         case 6: /* UserNameInformation */
    3087             :         case 7: /* UserAccountNameInformation */
    3088             :         case 8: /* UserFullNameInformation */
    3089             :         case 9: /* UserPrimaryGroupInformation */
    3090             :         case 13: /* UserAdminCommentInformation */
    3091             :                 /* USER_READ_GENERAL */
    3092          64 :                 acc_required = SAMR_USER_ACCESS_GET_NAME_ETC;
    3093          64 :                 break;
    3094          50 :         case 10: /* UserHomeInformation */
    3095             :         case 11: /* UserScriptInformation */
    3096             :         case 12: /* UserProfileInformation */
    3097             :         case 14: /* UserWorkStationsInformation */
    3098             :                 /* USER_READ_LOGON */
    3099          50 :                 acc_required = SAMR_USER_ACCESS_GET_LOGONINFO;
    3100          50 :                 break;
    3101         588 :         case 16: /* UserControlInformation */
    3102             :         case 17: /* UserExpiresInformation */
    3103             :         case 20: /* UserParametersInformation */
    3104             :                 /* USER_READ_ACCOUNT */
    3105         588 :                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
    3106         588 :                 break;
    3107         604 :         case 21: /* UserAllInformation */
    3108             :                 /* FIXME! - gd */
    3109         604 :                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
    3110         604 :                 break;
    3111         133 :         case 18: /* UserInternal1Information */
    3112             :                 /* FIXME! - gd */
    3113         133 :                 acc_required = SAMR_USER_ACCESS_GET_ATTRIBUTES;
    3114         133 :                 break;
    3115           0 :         case 23: /* UserInternal4Information */
    3116             :         case 24: /* UserInternal4InformationNew */
    3117             :         case 25: /* UserInternal4InformationNew */
    3118             :         case 26: /* UserInternal5InformationNew */
    3119             :         default:
    3120           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    3121           0 :                 break;
    3122             :         }
    3123             : 
    3124        1868 :         uinfo = samr_policy_handle_find(p,
    3125        1868 :                                         r->in.user_handle,
    3126             :                                         SAMR_HANDLE_USER,
    3127             :                                         acc_required,
    3128             :                                         &acc_granted,
    3129             :                                         &status);
    3130        1868 :         if (!NT_STATUS_IS_OK(status)) {
    3131           0 :                 return status;
    3132             :         }
    3133             : 
    3134        1868 :         domain_sid = uinfo->sid;
    3135             : 
    3136        1868 :         sid_split_rid(&domain_sid, &rid);
    3137             : 
    3138        1868 :         if (!sid_check_is_in_our_sam(&uinfo->sid))
    3139           0 :                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
    3140             : 
    3141        1868 :         DEBUG(5,("_samr_QueryUserInfo: sid:%s\n",
    3142             :                  dom_sid_str_buf(&uinfo->sid, &buf)));
    3143             : 
    3144        1868 :         user_info = talloc_zero(p->mem_ctx, union samr_UserInfo);
    3145        1868 :         if (!user_info) {
    3146           0 :                 return NT_STATUS_NO_MEMORY;
    3147             :         }
    3148             : 
    3149        1868 :         DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
    3150             : 
    3151        1868 :         if (!(pwd = samu_new(p->mem_ctx))) {
    3152           0 :                 return NT_STATUS_NO_MEMORY;
    3153             :         }
    3154             : 
    3155        1868 :         become_root();
    3156        1868 :         ret = pdb_getsampwsid(pwd, &uinfo->sid);
    3157        1868 :         unbecome_root();
    3158             : 
    3159        1868 :         if (ret == false) {
    3160           0 :                 DEBUG(4,("User %s not found\n",
    3161             :                          dom_sid_str_buf(&uinfo->sid, &buf)));
    3162           0 :                 TALLOC_FREE(pwd);
    3163           0 :                 return NT_STATUS_NO_SUCH_USER;
    3164             :         }
    3165             : 
    3166        1868 :         DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
    3167             : 
    3168        1868 :         samr_clear_sam_passwd(pwd);
    3169             : 
    3170        1868 :         switch (r->in.level) {
    3171          48 :         case 1:
    3172          48 :                 status = get_user_info_1(p->mem_ctx, &user_info->info1, pwd, &domain_sid);
    3173          48 :                 break;
    3174           8 :         case 2:
    3175           8 :                 status = get_user_info_2(p->mem_ctx, &user_info->info2, pwd);
    3176           8 :                 break;
    3177         177 :         case 3:
    3178         177 :                 status = get_user_info_3(p->mem_ctx, &user_info->info3, pwd, &domain_sid);
    3179         177 :                 break;
    3180          10 :         case 4:
    3181          10 :                 status = get_user_info_4(p->mem_ctx, &user_info->info4, pwd);
    3182          10 :                 break;
    3183         186 :         case 5:
    3184         186 :                 status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
    3185         186 :                 break;
    3186          30 :         case 6:
    3187          30 :                 status = get_user_info_6(p->mem_ctx, &user_info->info6, pwd);
    3188          30 :                 break;
    3189          10 :         case 7:
    3190          10 :                 status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
    3191          10 :                 break;
    3192          10 :         case 8:
    3193          10 :                 status = get_user_info_8(p->mem_ctx, &user_info->info8, pwd);
    3194          10 :                 break;
    3195           4 :         case 9:
    3196           4 :                 status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
    3197           4 :                 break;
    3198          18 :         case 10:
    3199          18 :                 status = get_user_info_10(p->mem_ctx, &user_info->info10, pwd);
    3200          18 :                 break;
    3201          10 :         case 11:
    3202          10 :                 status = get_user_info_11(p->mem_ctx, &user_info->info11, pwd);
    3203          10 :                 break;
    3204          11 :         case 12:
    3205          11 :                 status = get_user_info_12(p->mem_ctx, &user_info->info12, pwd);
    3206          11 :                 break;
    3207          10 :         case 13:
    3208          10 :                 status = get_user_info_13(p->mem_ctx, &user_info->info13, pwd);
    3209          10 :                 break;
    3210          11 :         case 14:
    3211          11 :                 status = get_user_info_14(p->mem_ctx, &user_info->info14, pwd);
    3212          11 :                 break;
    3213         569 :         case 16:
    3214         569 :                 status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
    3215         569 :                 break;
    3216           9 :         case 17:
    3217           9 :                 status = get_user_info_17(p->mem_ctx, &user_info->info17, pwd);
    3218           9 :                 break;
    3219         133 :         case 18:
    3220             :                 /* level 18 is special */
    3221         133 :                 status = get_user_info_18(p, p->mem_ctx, &user_info->info18,
    3222             :                                           &uinfo->sid);
    3223         133 :                 break;
    3224          10 :         case 20:
    3225          10 :                 status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
    3226          10 :                 break;
    3227         604 :         case 21:
    3228         604 :                 status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid, acc_granted);
    3229         604 :                 break;
    3230           0 :         default:
    3231           0 :                 status = NT_STATUS_INVALID_INFO_CLASS;
    3232           0 :                 break;
    3233             :         }
    3234             : 
    3235        1868 :         if (!NT_STATUS_IS_OK(status)) {
    3236           0 :                 goto done;
    3237             :         }
    3238             : 
    3239        1868 :         *r->out.info = user_info;
    3240             : 
    3241        1868 :  done:
    3242        1868 :         TALLOC_FREE(pwd);
    3243             : 
    3244        1868 :         DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
    3245             : 
    3246        1868 :         return status;
    3247             : }
    3248             : 
    3249             : /****************************************************************
    3250             : ****************************************************************/
    3251             : 
    3252         335 : NTSTATUS _samr_QueryUserInfo2(struct pipes_struct *p,
    3253             :                               struct samr_QueryUserInfo2 *r)
    3254             : {
    3255           0 :         struct samr_QueryUserInfo u;
    3256             : 
    3257         335 :         u.in.user_handle        = r->in.user_handle;
    3258         335 :         u.in.level              = r->in.level;
    3259         335 :         u.out.info              = r->out.info;
    3260             : 
    3261         335 :         return _samr_QueryUserInfo(p, &u);
    3262             : }
    3263             : 
    3264             : /*******************************************************************
    3265             :  _samr_GetGroupsForUser
    3266             :  ********************************************************************/
    3267             : 
    3268        2289 : NTSTATUS _samr_GetGroupsForUser(struct pipes_struct *p,
    3269             :                                 struct samr_GetGroupsForUser *r)
    3270             : {
    3271           0 :         struct samr_info *uinfo;
    3272        2289 :         struct samu *sam_pass=NULL;
    3273           0 :         struct dom_sid *sids;
    3274           0 :         struct samr_RidWithAttribute dom_gid;
    3275        2289 :         struct samr_RidWithAttribute *gids = NULL;
    3276           0 :         uint32_t primary_group_rid;
    3277        2289 :         uint32_t num_groups = 0;
    3278           0 :         gid_t *unix_gids;
    3279           0 :         uint32_t i, num_gids;
    3280           0 :         bool ret;
    3281           0 :         NTSTATUS result;
    3282        2289 :         bool success = False;
    3283           0 :         struct dom_sid_buf buf;
    3284             : 
    3285        2289 :         struct samr_RidWithAttributeArray *rids = NULL;
    3286             : 
    3287             :         /*
    3288             :          * from the SID in the request:
    3289             :          * we should send back the list of DOMAIN GROUPS
    3290             :          * the user is a member of
    3291             :          *
    3292             :          * and only the DOMAIN GROUPS
    3293             :          * no ALIASES !!! neither aliases of the domain
    3294             :          * nor aliases of the builtin SID
    3295             :          *
    3296             :          * JFM, 12/2/2001
    3297             :          */
    3298             : 
    3299        2289 :         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
    3300             : 
    3301        2289 :         uinfo = samr_policy_handle_find(p,
    3302        2289 :                                         r->in.user_handle,
    3303             :                                         SAMR_HANDLE_USER,
    3304             :                                         SAMR_USER_ACCESS_GET_GROUPS,
    3305             :                                         NULL,
    3306             :                                         &result);
    3307        2289 :         if (!NT_STATUS_IS_OK(result)) {
    3308           0 :                 return result;
    3309             :         }
    3310             : 
    3311        2289 :         rids = talloc_zero(p->mem_ctx, struct samr_RidWithAttributeArray);
    3312        2289 :         if (!rids) {
    3313           0 :                 return NT_STATUS_NO_MEMORY;
    3314             :         }
    3315             : 
    3316        2289 :         if (!sid_check_is_in_our_sam(&uinfo->sid))
    3317           0 :                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
    3318             : 
    3319        2289 :         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
    3320           0 :                 return NT_STATUS_NO_MEMORY;
    3321             :         }
    3322             : 
    3323        2289 :         become_root();
    3324        2289 :         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
    3325        2289 :         unbecome_root();
    3326             : 
    3327        2289 :         if (!ret) {
    3328           0 :                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
    3329             :                            dom_sid_str_buf(&uinfo->sid, &buf)));
    3330           0 :                 return NT_STATUS_NO_SUCH_USER;
    3331             :         }
    3332             : 
    3333        2289 :         sids = NULL;
    3334             : 
    3335             :         /* make both calls inside the root block */
    3336        2289 :         become_root();
    3337        2289 :         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
    3338             :                                             &sids, &unix_gids, &num_groups);
    3339        2289 :         if ( NT_STATUS_IS_OK(result) ) {
    3340        2289 :                 success = sid_peek_check_rid(get_global_sam_sid(),
    3341             :                                              pdb_get_group_sid(sam_pass),
    3342             :                                              &primary_group_rid);
    3343             :         }
    3344        2289 :         unbecome_root();
    3345             : 
    3346        2289 :         if (!NT_STATUS_IS_OK(result)) {
    3347           0 :                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
    3348             :                            dom_sid_str_buf(&uinfo->sid, &buf)));
    3349           0 :                 return result;
    3350             :         }
    3351             : 
    3352        2289 :         if ( !success ) {
    3353           0 :                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
    3354             :                           dom_sid_str_buf(pdb_get_group_sid(sam_pass), &buf),
    3355             :                           pdb_get_username(sam_pass)));
    3356           0 :                 TALLOC_FREE(sam_pass);
    3357           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    3358             :         }
    3359             : 
    3360        2289 :         gids = NULL;
    3361        2289 :         num_gids = 0;
    3362             : 
    3363        2289 :         dom_gid.attributes = SE_GROUP_DEFAULT_FLAGS;
    3364        2289 :         dom_gid.rid = primary_group_rid;
    3365        2289 :         ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
    3366             : 
    3367        4711 :         for (i=0; i<num_groups; i++) {
    3368             : 
    3369        2422 :                 if (!sid_peek_check_rid(get_global_sam_sid(),
    3370        2422 :                                         &(sids[i]), &dom_gid.rid)) {
    3371        2340 :                         DEBUG(10, ("Found sid %s not in our domain\n",
    3372             :                                    dom_sid_str_buf(&sids[i], &buf)));
    3373        2340 :                         continue;
    3374             :                 }
    3375             : 
    3376          82 :                 if (dom_gid.rid == primary_group_rid) {
    3377             :                         /* We added the primary group directly from the
    3378             :                          * sam_account. The other SIDs are unique from
    3379             :                          * enum_group_memberships */
    3380          82 :                         continue;
    3381             :                 }
    3382             : 
    3383           0 :                 ADD_TO_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, dom_gid, &gids, &num_gids);
    3384             :         }
    3385             : 
    3386        2289 :         rids->count = num_gids;
    3387        2289 :         rids->rids = gids;
    3388             : 
    3389        2289 :         *r->out.rids = rids;
    3390             : 
    3391        2289 :         DEBUG(5,("_samr_GetGroupsForUser: %d\n", __LINE__));
    3392             : 
    3393        2289 :         return result;
    3394             : }
    3395             : 
    3396             : /*******************************************************************
    3397             :  ********************************************************************/
    3398             : 
    3399          42 : static uint32_t samr_get_server_role(void)
    3400             : {
    3401          42 :         uint32_t role = ROLE_DOMAIN_PDC;
    3402             : 
    3403          42 :         if (lp_server_role() == ROLE_DOMAIN_BDC) {
    3404           0 :                 role = ROLE_DOMAIN_BDC;
    3405             :         }
    3406             : 
    3407          42 :         return role;
    3408             : }
    3409             : 
    3410             : /*******************************************************************
    3411             :  ********************************************************************/
    3412             : 
    3413          14 : static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
    3414             :                                  struct samr_DomInfo1 *r)
    3415             : {
    3416           0 :         const struct loadparm_substitution *lp_sub =
    3417          14 :                 loadparm_s3_global_substitution();
    3418           0 :         uint32_t account_policy_temp;
    3419           0 :         time_t u_expire, u_min_age;
    3420             : 
    3421          14 :         become_root();
    3422             : 
    3423             :         /* AS ROOT !!! */
    3424             : 
    3425          14 :         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
    3426          14 :         r->min_password_length = account_policy_temp;
    3427             : 
    3428          14 :         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
    3429          14 :         r->password_history_length = account_policy_temp;
    3430             : 
    3431          14 :         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
    3432             :                                &r->password_properties);
    3433             : 
    3434          14 :         pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
    3435          14 :         u_expire = account_policy_temp;
    3436             : 
    3437          14 :         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
    3438          14 :         u_min_age = account_policy_temp;
    3439             : 
    3440             :         /* !AS ROOT */
    3441             : 
    3442          14 :         unbecome_root();
    3443             : 
    3444          14 :         unix_to_nt_time_abs((NTTIME *)&r->max_password_age, u_expire);
    3445          14 :         unix_to_nt_time_abs((NTTIME *)&r->min_password_age, u_min_age);
    3446             : 
    3447          14 :         if (lp_check_password_script(talloc_tos(), lp_sub) && *lp_check_password_script(talloc_tos(), lp_sub)){
    3448           0 :                 r->password_properties |= DOMAIN_PASSWORD_COMPLEX;
    3449             :         }
    3450             : 
    3451          14 :         return NT_STATUS_OK;
    3452             : }
    3453             : 
    3454             : /*******************************************************************
    3455             :  ********************************************************************/
    3456             : 
    3457          36 : static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
    3458             :                                  struct samr_DomGeneralInformation *r,
    3459             :                                  struct samr_info *dinfo)
    3460             : {
    3461           0 :         const struct loadparm_substitution *lp_sub =
    3462          36 :                 loadparm_s3_global_substitution();
    3463           0 :         uint32_t u_logout;
    3464           0 :         time_t seq_num;
    3465             : 
    3466          36 :         become_root();
    3467             : 
    3468             :         /* AS ROOT !!! */
    3469             : 
    3470          36 :         r->num_users = count_sam_users(dinfo->disp_info, ACB_NORMAL);
    3471          36 :         r->num_groups        = count_sam_groups(dinfo->disp_info);
    3472          36 :         r->num_aliases       = count_sam_aliases(dinfo->disp_info);
    3473             : 
    3474          36 :         pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
    3475             : 
    3476          36 :         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
    3477             : 
    3478          36 :         if (!pdb_get_seq_num(&seq_num)) {
    3479           0 :                 seq_num = time(NULL);
    3480             :         }
    3481             : 
    3482             :         /* !AS ROOT */
    3483             : 
    3484          36 :         unbecome_root();
    3485             : 
    3486          36 :         r->oem_information.string    = lp_server_string(r, lp_sub);
    3487          36 :         r->domain_name.string                = lp_workgroup();
    3488          36 :         r->primary.string            = lp_netbios_name();
    3489          36 :         r->sequence_num                      = seq_num;
    3490          36 :         r->domain_server_state               = DOMAIN_SERVER_ENABLED;
    3491          36 :         r->role                              = (enum samr_Role) samr_get_server_role();
    3492          36 :         r->unknown3                  = 1;
    3493             : 
    3494          36 :         return NT_STATUS_OK;
    3495             : }
    3496             : 
    3497             : /*******************************************************************
    3498             :  ********************************************************************/
    3499             : 
    3500           6 : static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
    3501             :                                  struct samr_DomInfo3 *r)
    3502             : {
    3503           0 :         uint32_t u_logout;
    3504             : 
    3505           6 :         become_root();
    3506             : 
    3507             :         /* AS ROOT !!! */
    3508             : 
    3509             :         {
    3510           0 :                 uint32_t ul;
    3511           6 :                 pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
    3512           6 :                 u_logout = (time_t)ul;
    3513             :         }
    3514             : 
    3515             :         /* !AS ROOT */
    3516             : 
    3517           6 :         unbecome_root();
    3518             : 
    3519           6 :         unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
    3520             : 
    3521           6 :         return NT_STATUS_OK;
    3522             : }
    3523             : 
    3524             : /*******************************************************************
    3525             :  ********************************************************************/
    3526             : 
    3527           6 : static NTSTATUS query_dom_info_4(TALLOC_CTX *mem_ctx,
    3528             :                                  struct samr_DomOEMInformation *r)
    3529             : {
    3530           0 :         const struct loadparm_substitution *lp_sub =
    3531           6 :                 loadparm_s3_global_substitution();
    3532             : 
    3533           6 :         r->oem_information.string = lp_server_string(r, lp_sub);
    3534             : 
    3535           6 :         return NT_STATUS_OK;
    3536             : }
    3537             : 
    3538             : /*******************************************************************
    3539             :  ********************************************************************/
    3540             : 
    3541           6 : static NTSTATUS query_dom_info_5(TALLOC_CTX *mem_ctx,
    3542             :                                  struct samr_DomInfo5 *r)
    3543             : {
    3544           6 :         r->domain_name.string = get_global_sam_name();
    3545             : 
    3546           6 :         return NT_STATUS_OK;
    3547             : }
    3548             : 
    3549             : /*******************************************************************
    3550             :  ********************************************************************/
    3551             : 
    3552           6 : static NTSTATUS query_dom_info_6(TALLOC_CTX *mem_ctx,
    3553             :                                  struct samr_DomInfo6 *r)
    3554             : {
    3555             :         /* NT returns its own name when a PDC. win2k and later
    3556             :          * only the name of the PDC if itself is a BDC (samba4
    3557             :          * idl) */
    3558           6 :         r->primary.string = lp_netbios_name();
    3559             : 
    3560           6 :         return NT_STATUS_OK;
    3561             : }
    3562             : 
    3563             : /*******************************************************************
    3564             :  ********************************************************************/
    3565             : 
    3566           6 : static NTSTATUS query_dom_info_7(TALLOC_CTX *mem_ctx,
    3567             :                                  struct samr_DomInfo7 *r)
    3568             : {
    3569           6 :         r->role = (enum samr_Role) samr_get_server_role();
    3570             : 
    3571           6 :         return NT_STATUS_OK;
    3572             : }
    3573             : 
    3574             : /*******************************************************************
    3575             :  ********************************************************************/
    3576             : 
    3577           8 : static NTSTATUS query_dom_info_8(TALLOC_CTX *mem_ctx,
    3578             :                                  struct samr_DomInfo8 *r)
    3579             : {
    3580           0 :         time_t seq_num;
    3581             : 
    3582           8 :         become_root();
    3583             : 
    3584             :         /* AS ROOT !!! */
    3585             : 
    3586           8 :         if (!pdb_get_seq_num(&seq_num)) {
    3587           0 :                 seq_num = time(NULL);
    3588             :         }
    3589             : 
    3590             :         /* !AS ROOT */
    3591             : 
    3592           8 :         unbecome_root();
    3593             : 
    3594           8 :         r->sequence_num = seq_num;
    3595           8 :         r->domain_create_time = 0;
    3596             : 
    3597           8 :         return NT_STATUS_OK;
    3598             : }
    3599             : 
    3600             : /*******************************************************************
    3601             :  ********************************************************************/
    3602             : 
    3603           6 : static NTSTATUS query_dom_info_9(TALLOC_CTX *mem_ctx,
    3604             :                                  struct samr_DomInfo9 *r)
    3605             : {
    3606           6 :         r->domain_server_state = DOMAIN_SERVER_ENABLED;
    3607             : 
    3608           6 :         return NT_STATUS_OK;
    3609             : }
    3610             : 
    3611             : /*******************************************************************
    3612             :  ********************************************************************/
    3613             : 
    3614           6 : static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
    3615             :                                   struct samr_DomGeneralInformation2 *r,
    3616             :                                   struct samr_info *dinfo)
    3617             : {
    3618           0 :         NTSTATUS status;
    3619           0 :         uint32_t account_policy_temp;
    3620           0 :         time_t u_lock_duration, u_reset_time;
    3621             : 
    3622           6 :         status = query_dom_info_2(mem_ctx, &r->general, dinfo);
    3623           6 :         if (!NT_STATUS_IS_OK(status)) {
    3624           0 :                 return status;
    3625             :         }
    3626             : 
    3627             :         /* AS ROOT !!! */
    3628             : 
    3629           6 :         become_root();
    3630             : 
    3631           6 :         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
    3632           6 :         u_lock_duration = account_policy_temp;
    3633           6 :         if (u_lock_duration != -1) {
    3634           6 :                 u_lock_duration *= 60;
    3635             :         }
    3636             : 
    3637           6 :         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
    3638           6 :         u_reset_time = account_policy_temp * 60;
    3639             : 
    3640           6 :         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
    3641           6 :         r->lockout_threshold = account_policy_temp;
    3642             : 
    3643             :         /* !AS ROOT */
    3644             : 
    3645           6 :         unbecome_root();
    3646             : 
    3647           6 :         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
    3648           6 :         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
    3649             : 
    3650           6 :         return NT_STATUS_OK;
    3651             : }
    3652             : 
    3653             : /*******************************************************************
    3654             :  ********************************************************************/
    3655             : 
    3656          12 : static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
    3657             :                                   struct samr_DomInfo12 *r)
    3658             : {
    3659           0 :         uint32_t account_policy_temp;
    3660           0 :         time_t u_lock_duration, u_reset_time;
    3661             : 
    3662          12 :         become_root();
    3663             : 
    3664             :         /* AS ROOT !!! */
    3665             : 
    3666          12 :         pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
    3667          12 :         u_lock_duration = account_policy_temp;
    3668          12 :         if (u_lock_duration != -1) {
    3669          12 :                 u_lock_duration *= 60;
    3670             :         }
    3671             : 
    3672          12 :         pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
    3673          12 :         u_reset_time = account_policy_temp * 60;
    3674             : 
    3675          12 :         pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
    3676          12 :         r->lockout_threshold = account_policy_temp;
    3677             : 
    3678             :         /* !AS ROOT */
    3679             : 
    3680          12 :         unbecome_root();
    3681             : 
    3682          12 :         unix_to_nt_time_abs(&r->lockout_duration, u_lock_duration);
    3683          12 :         unix_to_nt_time_abs(&r->lockout_window, u_reset_time);
    3684             : 
    3685          12 :         return NT_STATUS_OK;
    3686             : }
    3687             : 
    3688             : /*******************************************************************
    3689             :  ********************************************************************/
    3690             : 
    3691           6 : static NTSTATUS query_dom_info_13(TALLOC_CTX *mem_ctx,
    3692             :                                   struct samr_DomInfo13 *r)
    3693             : {
    3694           0 :         time_t seq_num;
    3695             : 
    3696           6 :         become_root();
    3697             : 
    3698             :         /* AS ROOT !!! */
    3699             : 
    3700           6 :         if (!pdb_get_seq_num(&seq_num)) {
    3701           0 :                 seq_num = time(NULL);
    3702             :         }
    3703             : 
    3704             :         /* !AS ROOT */
    3705             : 
    3706           6 :         unbecome_root();
    3707             : 
    3708           6 :         r->sequence_num = seq_num;
    3709           6 :         r->domain_create_time = 0;
    3710           6 :         r->modified_count_at_last_promotion = 0;
    3711             : 
    3712           6 :         return NT_STATUS_OK;
    3713             : }
    3714             : 
    3715             : /*******************************************************************
    3716             :  _samr_QueryDomainInfo
    3717             :  ********************************************************************/
    3718             : 
    3719         112 : NTSTATUS _samr_QueryDomainInfo(struct pipes_struct *p,
    3720             :                                struct samr_QueryDomainInfo *r)
    3721             : {
    3722         112 :         NTSTATUS status = NT_STATUS_OK;
    3723           0 :         struct samr_info *dinfo;
    3724           0 :         union samr_DomainInfo *dom_info;
    3725             : 
    3726           0 :         uint32_t acc_required;
    3727             : 
    3728         112 :         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
    3729             : 
    3730         112 :         switch (r->in.level) {
    3731          26 :         case 1: /* DomainPasswordInformation */
    3732             :         case 12: /* DomainLockoutInformation */
    3733             :                 /* DOMAIN_READ_PASSWORD_PARAMETERS */
    3734          26 :                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
    3735          26 :                 break;
    3736           6 :         case 11: /* DomainGeneralInformation2 */
    3737             :                 /* DOMAIN_READ_PASSWORD_PARAMETERS |
    3738             :                  * DOMAIN_READ_OTHER_PARAMETERS */
    3739           6 :                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
    3740             :                                SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
    3741           6 :                 break;
    3742          80 :         case 2: /* DomainGeneralInformation */
    3743             :         case 3: /* DomainLogoffInformation */
    3744             :         case 4: /* DomainOemInformation */
    3745             :         case 5: /* DomainReplicationInformation */
    3746             :         case 6: /* DomainReplicationInformation */
    3747             :         case 7: /* DomainServerRoleInformation */
    3748             :         case 8: /* DomainModifiedInformation */
    3749             :         case 9: /* DomainStateInformation */
    3750             :         case 10: /* DomainUasInformation */
    3751             :         case 13: /* DomainModifiedInformation2 */
    3752             :                 /* DOMAIN_READ_OTHER_PARAMETERS */
    3753          80 :                 acc_required = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
    3754          80 :                 break;
    3755           0 :         default:
    3756           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    3757             :         }
    3758             : 
    3759         112 :         dinfo = samr_policy_handle_find(p,
    3760         112 :                                         r->in.domain_handle,
    3761             :                                         SAMR_HANDLE_DOMAIN,
    3762             :                                         acc_required,
    3763             :                                         NULL,
    3764             :                                         &status);
    3765         112 :         if (!NT_STATUS_IS_OK(status)) {
    3766           0 :                 return status;
    3767             :         }
    3768             : 
    3769         112 :         dom_info = talloc_zero(p->mem_ctx, union samr_DomainInfo);
    3770         112 :         if (!dom_info) {
    3771           0 :                 return NT_STATUS_NO_MEMORY;
    3772             :         }
    3773             : 
    3774         112 :         switch (r->in.level) {
    3775          14 :                 case 1:
    3776          14 :                         status = query_dom_info_1(p->mem_ctx, &dom_info->info1);
    3777          14 :                         break;
    3778          30 :                 case 2:
    3779          30 :                         status = query_dom_info_2(p->mem_ctx, &dom_info->general, dinfo);
    3780          30 :                         break;
    3781           6 :                 case 3:
    3782           6 :                         status = query_dom_info_3(p->mem_ctx, &dom_info->info3);
    3783           6 :                         break;
    3784           6 :                 case 4:
    3785           6 :                         status = query_dom_info_4(p->mem_ctx, &dom_info->oem);
    3786           6 :                         break;
    3787           6 :                 case 5:
    3788           6 :                         status = query_dom_info_5(p->mem_ctx, &dom_info->info5);
    3789           6 :                         break;
    3790           6 :                 case 6:
    3791           6 :                         status = query_dom_info_6(p->mem_ctx, &dom_info->info6);
    3792           6 :                         break;
    3793           6 :                 case 7:
    3794           6 :                         status = query_dom_info_7(p->mem_ctx, &dom_info->info7);
    3795           6 :                         break;
    3796           8 :                 case 8:
    3797           8 :                         status = query_dom_info_8(p->mem_ctx, &dom_info->info8);
    3798           8 :                         break;
    3799           6 :                 case 9:
    3800           6 :                         status = query_dom_info_9(p->mem_ctx, &dom_info->info9);
    3801           6 :                         break;
    3802           6 :                 case 11:
    3803           6 :                         status = query_dom_info_11(p->mem_ctx, &dom_info->general2, dinfo);
    3804           6 :                         break;
    3805          12 :                 case 12:
    3806          12 :                         status = query_dom_info_12(p->mem_ctx, &dom_info->info12);
    3807          12 :                         break;
    3808           6 :                 case 13:
    3809           6 :                         status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
    3810           6 :                         break;
    3811           0 :                 default:
    3812           0 :                         return NT_STATUS_INVALID_INFO_CLASS;
    3813             :         }
    3814             : 
    3815         112 :         if (!NT_STATUS_IS_OK(status)) {
    3816           0 :                 return status;
    3817             :         }
    3818             : 
    3819         112 :         *r->out.info = dom_info;
    3820             : 
    3821         112 :         DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
    3822             : 
    3823         112 :         return status;
    3824             : }
    3825             : 
    3826             : /* W2k3 seems to use the same check for all 3 objects that can be created via
    3827             :  * SAMR, if you try to create for example "Dialup" as an alias it says
    3828             :  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
    3829             :  * database. */
    3830             : 
    3831         997 : static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
    3832             : {
    3833           0 :         enum lsa_SidType type;
    3834           0 :         bool result;
    3835             : 
    3836         997 :         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
    3837             : 
    3838         997 :         become_root();
    3839             :         /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
    3840             :          * whether the name already exists */
    3841         997 :         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
    3842             :                              NULL, NULL, NULL, &type);
    3843         997 :         unbecome_root();
    3844             : 
    3845         997 :         if (!result) {
    3846         988 :                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
    3847         988 :                 return NT_STATUS_OK;
    3848             :         }
    3849             : 
    3850           9 :         DEBUG(5, ("trying to create %s, exists as %s\n",
    3851             :                   new_name, sid_type_lookup(type)));
    3852             : 
    3853           9 :         if (type == SID_NAME_DOM_GRP) {
    3854           0 :                 return NT_STATUS_GROUP_EXISTS;
    3855             :         }
    3856           9 :         if (type == SID_NAME_ALIAS) {
    3857           0 :                 return NT_STATUS_ALIAS_EXISTS;
    3858             :         }
    3859             : 
    3860             :         /* Yes, the default is NT_STATUS_USER_EXISTS */
    3861           9 :         return NT_STATUS_USER_EXISTS;
    3862             : }
    3863             : 
    3864             : /*******************************************************************
    3865             :  _samr_CreateUser2
    3866             :  ********************************************************************/
    3867             : 
    3868         702 : NTSTATUS _samr_CreateUser2(struct pipes_struct *p,
    3869             :                            struct samr_CreateUser2 *r)
    3870             : {
    3871         702 :         struct dcesrv_call_state *dce_call = p->dce_call;
    3872           0 :         struct auth_session_info *session_info =
    3873         702 :                 dcesrv_call_session_info(dce_call);
    3874         702 :         const char *account = NULL;
    3875           0 :         struct dom_sid sid;
    3876         702 :         uint32_t acb_info = r->in.acct_flags;
    3877           0 :         struct samr_info *dinfo;
    3878           0 :         NTSTATUS nt_status;
    3879           0 :         uint32_t acc_granted;
    3880           0 :         struct security_descriptor *psd;
    3881           0 :         size_t    sd_size;
    3882             :         /* check this, when giving away 'add computer to domain' privs */
    3883         702 :         uint32_t    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
    3884         702 :         bool can_add_account = False;
    3885             : 
    3886             :         /* Which privilege is needed to override the ACL? */
    3887         702 :         enum sec_privilege needed_priv = SEC_PRIV_INVALID;
    3888             : 
    3889         702 :         dinfo = samr_policy_handle_find(p,
    3890         702 :                                         r->in.domain_handle,
    3891             :                                         SAMR_HANDLE_DOMAIN,
    3892             :                                         SAMR_DOMAIN_ACCESS_CREATE_USER,
    3893             :                                         NULL,
    3894             :                                         &nt_status);
    3895         702 :         if (!NT_STATUS_IS_OK(nt_status)) {
    3896           2 :                 return nt_status;
    3897             :         }
    3898             : 
    3899         700 :         if (sid_check_is_builtin(&dinfo->sid)) {
    3900         311 :                 DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
    3901         311 :                 return NT_STATUS_ACCESS_DENIED;
    3902             :         }
    3903             : 
    3904         389 :         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
    3905           0 :               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
    3906             :                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
    3907             :                    this parameter is not an account type */
    3908           0 :                 return NT_STATUS_INVALID_PARAMETER;
    3909             :         }
    3910             : 
    3911         389 :         account = r->in.account_name->string;
    3912         389 :         if (account == NULL) {
    3913           0 :                 return NT_STATUS_NO_MEMORY;
    3914             :         }
    3915             : 
    3916         389 :         nt_status = can_create(p->mem_ctx, account);
    3917         389 :         if (!NT_STATUS_IS_OK(nt_status)) {
    3918           9 :                 return nt_status;
    3919             :         }
    3920             : 
    3921             :         /* determine which user right we need to check based on the acb_info */
    3922             : 
    3923         380 :         if (root_mode()) {
    3924         380 :                 can_add_account = true;
    3925           0 :         } else if (acb_info & ACB_WSTRUST) {
    3926           0 :                 needed_priv = SEC_PRIV_MACHINE_ACCOUNT;
    3927           0 :                 can_add_account = security_token_has_privilege(
    3928           0 :                         session_info->security_token, needed_priv);
    3929           0 :         } else if (acb_info & ACB_NORMAL &&
    3930           0 :                   (account[strlen(account)-1] != '$')) {
    3931             :                 /* usrmgr.exe (and net rpc trustdom add) creates a normal user
    3932             :                    account for domain trusts and changes the ACB flags later */
    3933           0 :                 needed_priv = SEC_PRIV_ADD_USERS;
    3934           0 :                 can_add_account = security_token_has_privilege(
    3935           0 :                         session_info->security_token, needed_priv);
    3936           0 :         } else if (lp_enable_privileges()) {
    3937             :                 /* implicit assumption of a BDC or domain trust account here
    3938             :                  * (we already check the flags earlier) */
    3939             :                 /* only Domain Admins can add a BDC or domain trust */
    3940           0 :                 can_add_account = nt_token_check_domain_rid(
    3941             :                         session_info->security_token,
    3942             :                         DOMAIN_RID_ADMINS );
    3943             :         }
    3944             : 
    3945         380 :         DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
    3946             :                   uidtoname(session_info->unix_token->uid),
    3947             :                   can_add_account ? "True":"False" ));
    3948             : 
    3949         380 :         if (!can_add_account) {
    3950           0 :                 return NT_STATUS_ACCESS_DENIED;
    3951             :         }
    3952             : 
    3953             :         /********** BEGIN Admin BLOCK **********/
    3954             : 
    3955         380 :         (void)winbind_off();
    3956         380 :         become_root();
    3957         380 :         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
    3958             :                                     r->out.rid);
    3959         380 :         unbecome_root();
    3960         380 :         (void)winbind_on();
    3961             : 
    3962             :         /********** END Admin BLOCK **********/
    3963             : 
    3964             :         /* now check for failure */
    3965             : 
    3966         380 :         if ( !NT_STATUS_IS_OK(nt_status) )
    3967           0 :                 return nt_status;
    3968             : 
    3969             :         /* Get the user's SID */
    3970             : 
    3971         380 :         sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
    3972             : 
    3973         380 :         map_max_allowed_access(session_info->security_token,
    3974         380 :                                session_info->unix_token,
    3975             :                                &des_access);
    3976             : 
    3977         380 :         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
    3978             :                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
    3979         380 :         se_map_generic(&des_access, &usr_generic_mapping);
    3980             : 
    3981             :         /*
    3982             :          * JRA - TESTME. We just created this user so we
    3983             :          * had rights to create them. Do we need to check
    3984             :          * any further access on this object ? Can't we
    3985             :          * just assume we have all the rights we need ?
    3986             :          */
    3987             : 
    3988         380 :         nt_status = access_check_object(psd, session_info->security_token,
    3989             :                                         needed_priv, SEC_PRIV_INVALID,
    3990             :                                         GENERIC_RIGHTS_USER_WRITE, des_access,
    3991             :                 &acc_granted, "_samr_CreateUser2");
    3992             : 
    3993         380 :         if ( !NT_STATUS_IS_OK(nt_status) ) {
    3994           0 :                 return nt_status;
    3995             :         }
    3996             : 
    3997         380 :         nt_status = create_samr_policy_handle(p->mem_ctx,
    3998             :                                               p,
    3999             :                                               SAMR_HANDLE_USER,
    4000             :                                               acc_granted,
    4001             :                                               &sid,
    4002             :                                               NULL,
    4003             :                                               r->out.user_handle);
    4004         380 :         if (!NT_STATUS_IS_OK(nt_status)) {
    4005           0 :                 return nt_status;
    4006             :         }
    4007             : 
    4008             :         /* After a "set" ensure we have no cached display info. */
    4009         380 :         force_flush_samr_cache(&sid);
    4010             : 
    4011         380 :         *r->out.access_granted = acc_granted;
    4012             : 
    4013         380 :         return NT_STATUS_OK;
    4014             : }
    4015             : 
    4016             : /****************************************************************
    4017             : ****************************************************************/
    4018             : 
    4019         624 : NTSTATUS _samr_CreateUser(struct pipes_struct *p,
    4020             :                           struct samr_CreateUser *r)
    4021             : {
    4022           0 :         struct samr_CreateUser2 c;
    4023           0 :         uint32_t access_granted;
    4024             : 
    4025         624 :         c.in.domain_handle      = r->in.domain_handle;
    4026         624 :         c.in.account_name       = r->in.account_name;
    4027         624 :         c.in.acct_flags         = ACB_NORMAL;
    4028         624 :         c.in.access_mask        = r->in.access_mask;
    4029         624 :         c.out.user_handle       = r->out.user_handle;
    4030         624 :         c.out.access_granted    = &access_granted;
    4031         624 :         c.out.rid               = r->out.rid;
    4032             : 
    4033         624 :         return _samr_CreateUser2(p, &c);
    4034             : }
    4035             : 
    4036             : /*******************************************************************
    4037             :  _samr_Connect
    4038             :  ********************************************************************/
    4039             : 
    4040         229 : NTSTATUS _samr_Connect(struct pipes_struct *p,
    4041             :                        struct samr_Connect *r)
    4042             : {
    4043         229 :         struct dcesrv_call_state *dce_call = p->dce_call;
    4044           0 :         struct auth_session_info *session_info =
    4045         229 :                 dcesrv_call_session_info(dce_call);
    4046           0 :         uint32_t acc_granted;
    4047         229 :         uint32_t    des_access = r->in.access_mask;
    4048           0 :         NTSTATUS status;
    4049             : 
    4050             :         /* Access check */
    4051             : 
    4052         229 :         if (!pipe_access_check(p)) {
    4053           0 :                 DEBUG(3, ("access denied to _samr_Connect\n"));
    4054           0 :                 return NT_STATUS_ACCESS_DENIED;
    4055             :         }
    4056             : 
    4057             :         /* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
    4058             :            was observed from a win98 client trying to enumerate users (when configured
    4059             :            user level access control on shares)   --jerry */
    4060             : 
    4061         229 :         map_max_allowed_access(session_info->security_token,
    4062         229 :                                session_info->unix_token,
    4063             :                                &des_access);
    4064             : 
    4065         229 :         se_map_generic( &des_access, &sam_generic_mapping );
    4066             : 
    4067         229 :         acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
    4068             :                                     |SAMR_ACCESS_LOOKUP_DOMAIN);
    4069             : 
    4070             :         /* set up the SAMR connect_anon response */
    4071         229 :         status = create_samr_policy_handle(p->mem_ctx,
    4072             :                                            p,
    4073             :                                            SAMR_HANDLE_CONNECT,
    4074             :                                            acc_granted,
    4075             :                                            NULL,
    4076             :                                            NULL,
    4077             :                                            r->out.connect_handle);
    4078         229 :         if (!NT_STATUS_IS_OK(status)) {
    4079           0 :                 return status;
    4080             :         }
    4081             : 
    4082         229 :         return NT_STATUS_OK;
    4083             : }
    4084             : 
    4085             : /*******************************************************************
    4086             :  _samr_Connect2
    4087             :  ********************************************************************/
    4088             : 
    4089         524 : NTSTATUS _samr_Connect2(struct pipes_struct *p,
    4090             :                         struct samr_Connect2 *r)
    4091             : {
    4092         524 :         struct dcesrv_call_state *dce_call = p->dce_call;
    4093           0 :         struct auth_session_info *session_info =
    4094         524 :                 dcesrv_call_session_info(dce_call);
    4095         524 :         struct security_descriptor *psd = NULL;
    4096           0 :         uint32_t    acc_granted;
    4097         524 :         uint32_t    des_access = r->in.access_mask;
    4098           0 :         NTSTATUS  nt_status;
    4099           0 :         size_t    sd_size;
    4100         524 :         const char *fn = "_samr_Connect2";
    4101             : 
    4102         524 :         switch (dce_call->pkt.u.request.opnum) {
    4103         365 :         case NDR_SAMR_CONNECT2:
    4104         365 :                 fn = "_samr_Connect2";
    4105         365 :                 break;
    4106          51 :         case NDR_SAMR_CONNECT3:
    4107          51 :                 fn = "_samr_Connect3";
    4108          51 :                 break;
    4109          51 :         case NDR_SAMR_CONNECT4:
    4110          51 :                 fn = "_samr_Connect4";
    4111          51 :                 break;
    4112          57 :         case NDR_SAMR_CONNECT5:
    4113          57 :                 fn = "_samr_Connect5";
    4114          57 :                 break;
    4115             :         }
    4116             : 
    4117         524 :         DEBUG(5,("%s: %d\n", fn, __LINE__));
    4118             : 
    4119             :         /* Access check */
    4120             : 
    4121         524 :         if (!pipe_access_check(p)) {
    4122           0 :                 DEBUG(3, ("access denied to %s\n", fn));
    4123           0 :                 return NT_STATUS_ACCESS_DENIED;
    4124             :         }
    4125             : 
    4126         524 :         map_max_allowed_access(session_info->security_token,
    4127         524 :                                session_info->unix_token,
    4128             :                                &des_access);
    4129             : 
    4130         524 :         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
    4131         524 :         se_map_generic(&des_access, &sam_generic_mapping);
    4132             : 
    4133         524 :         nt_status = access_check_object(psd, session_info->security_token,
    4134             :                                         SEC_PRIV_INVALID, SEC_PRIV_INVALID,
    4135             :                                         0, des_access, &acc_granted, fn);
    4136             : 
    4137         524 :         if ( !NT_STATUS_IS_OK(nt_status) )
    4138           0 :                 return nt_status;
    4139             : 
    4140         524 :         nt_status = create_samr_policy_handle(p->mem_ctx,
    4141             :                                               p,
    4142             :                                               SAMR_HANDLE_CONNECT,
    4143             :                                               acc_granted,
    4144             :                                               NULL,
    4145             :                                               NULL,
    4146             :                                               r->out.connect_handle);
    4147         524 :         if (!NT_STATUS_IS_OK(nt_status)) {
    4148           0 :                 return nt_status;
    4149             :         }
    4150             : 
    4151         524 :         DEBUG(5,("%s: %d\n", fn, __LINE__));
    4152             : 
    4153         524 :         return NT_STATUS_OK;
    4154             : }
    4155             : 
    4156             : /****************************************************************
    4157             :  _samr_Connect3
    4158             : ****************************************************************/
    4159             : 
    4160          51 : NTSTATUS _samr_Connect3(struct pipes_struct *p,
    4161             :                         struct samr_Connect3 *r)
    4162             : {
    4163           0 :         struct samr_Connect2 c;
    4164             : 
    4165          51 :         c.in.system_name        = r->in.system_name;
    4166          51 :         c.in.access_mask        = r->in.access_mask;
    4167          51 :         c.out.connect_handle    = r->out.connect_handle;
    4168             : 
    4169          51 :         return _samr_Connect2(p, &c);
    4170             : }
    4171             : 
    4172             : /*******************************************************************
    4173             :  _samr_Connect4
    4174             :  ********************************************************************/
    4175             : 
    4176          51 : NTSTATUS _samr_Connect4(struct pipes_struct *p,
    4177             :                         struct samr_Connect4 *r)
    4178             : {
    4179           0 :         struct samr_Connect2 c;
    4180             : 
    4181          51 :         c.in.system_name        = r->in.system_name;
    4182          51 :         c.in.access_mask        = r->in.access_mask;
    4183          51 :         c.out.connect_handle    = r->out.connect_handle;
    4184             : 
    4185          51 :         return _samr_Connect2(p, &c);
    4186             : }
    4187             : 
    4188             : /*******************************************************************
    4189             :  _samr_Connect5
    4190             :  ********************************************************************/
    4191             : 
    4192          57 : NTSTATUS _samr_Connect5(struct pipes_struct *p,
    4193             :                         struct samr_Connect5 *r)
    4194             : {
    4195           0 :         NTSTATUS status;
    4196           0 :         struct samr_Connect2 c;
    4197           0 :         struct samr_ConnectInfo1 info1;
    4198             : 
    4199          57 :         info1.client_version = SAMR_CONNECT_AFTER_W2K;
    4200          57 :         info1.supported_features = 0;
    4201             : 
    4202          57 :         c.in.system_name        = r->in.system_name;
    4203          57 :         c.in.access_mask        = r->in.access_mask;
    4204          57 :         c.out.connect_handle    = r->out.connect_handle;
    4205             : 
    4206          57 :         *r->out.level_out = 1;
    4207             : 
    4208          57 :         status = _samr_Connect2(p, &c);
    4209          57 :         if (!NT_STATUS_IS_OK(status)) {
    4210           0 :                 return status;
    4211             :         }
    4212             : 
    4213          57 :         r->out.info_out->info1 = info1;
    4214             : 
    4215          57 :         return NT_STATUS_OK;
    4216             : }
    4217             : 
    4218             : /**********************************************************************
    4219             :  _samr_LookupDomain
    4220             :  **********************************************************************/
    4221             : 
    4222         370 : NTSTATUS _samr_LookupDomain(struct pipes_struct *p,
    4223             :                             struct samr_LookupDomain *r)
    4224             : {
    4225           0 :         NTSTATUS status;
    4226           0 :         const char *domain_name;
    4227         370 :         struct dom_sid *sid = NULL;
    4228           0 :         struct dom_sid_buf buf;
    4229             : 
    4230             :         /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
    4231             :            Reverted that change so we will work with RAS servers again */
    4232             : 
    4233         370 :         (void)samr_policy_handle_find(p,
    4234         370 :                                       r->in.connect_handle,
    4235             :                                       SAMR_HANDLE_CONNECT,
    4236             :                                       SAMR_ACCESS_LOOKUP_DOMAIN,
    4237             :                                       NULL,
    4238             :                                       &status);
    4239         370 :         if (!NT_STATUS_IS_OK(status)) {
    4240           0 :                 return status;
    4241             :         }
    4242             : 
    4243         370 :         domain_name = r->in.domain_name->string;
    4244         370 :         if (!domain_name) {
    4245          34 :                 return NT_STATUS_INVALID_PARAMETER;
    4246             :         }
    4247             : 
    4248         336 :         sid = talloc_zero(p->mem_ctx, struct dom_sid2);
    4249         336 :         if (!sid) {
    4250           0 :                 return NT_STATUS_NO_MEMORY;
    4251             :         }
    4252             : 
    4253         336 :         if (strequal(domain_name, builtin_domain_name())) {
    4254          17 :                 sid_copy(sid, &global_sid_Builtin);
    4255             :         } else {
    4256         319 :                 if (!secrets_fetch_domain_sid(domain_name, sid)) {
    4257          34 :                         status = NT_STATUS_NO_SUCH_DOMAIN;
    4258             :                 }
    4259             :         }
    4260             : 
    4261         336 :         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name,
    4262             :                  dom_sid_str_buf(sid, &buf)));
    4263             : 
    4264         336 :         *r->out.sid = sid;
    4265             : 
    4266         336 :         return status;
    4267             : }
    4268             : 
    4269             : /**********************************************************************
    4270             :  _samr_EnumDomains
    4271             :  **********************************************************************/
    4272             : 
    4273          60 : NTSTATUS _samr_EnumDomains(struct pipes_struct *p,
    4274             :                            struct samr_EnumDomains *r)
    4275             : {
    4276           0 :         NTSTATUS status;
    4277          60 :         uint32_t num_entries = 2;
    4278          60 :         struct samr_SamEntry *entry_array = NULL;
    4279           0 :         struct samr_SamArray *sam;
    4280             : 
    4281          60 :         (void)samr_policy_handle_find(p,
    4282          60 :                                       r->in.connect_handle,
    4283             :                                       SAMR_HANDLE_CONNECT,
    4284             :                                       SAMR_ACCESS_ENUM_DOMAINS,
    4285             :                                       NULL,
    4286             :                                       &status);
    4287          60 :         if (!NT_STATUS_IS_OK(status)) {
    4288           0 :                 return status;
    4289             :         }
    4290             : 
    4291          60 :         sam = talloc_zero(p->mem_ctx, struct samr_SamArray);
    4292          60 :         if (!sam) {
    4293           0 :                 return NT_STATUS_NO_MEMORY;
    4294             :         }
    4295             : 
    4296          60 :         entry_array = talloc_zero_array(p->mem_ctx,
    4297             :                                         struct samr_SamEntry,
    4298             :                                         num_entries);
    4299          60 :         if (!entry_array) {
    4300           0 :                 return NT_STATUS_NO_MEMORY;
    4301             :         }
    4302             : 
    4303          60 :         entry_array[0].idx = 0;
    4304          60 :         init_lsa_String(&entry_array[0].name, get_global_sam_name());
    4305             : 
    4306          60 :         entry_array[1].idx = 1;
    4307          60 :         init_lsa_String(&entry_array[1].name, "Builtin");
    4308             : 
    4309          60 :         sam->count = num_entries;
    4310          60 :         sam->entries = entry_array;
    4311             : 
    4312          60 :         *r->out.sam = sam;
    4313          60 :         *r->out.num_entries = num_entries;
    4314             : 
    4315          60 :         return status;
    4316             : }
    4317             : 
    4318             : /*******************************************************************
    4319             :  _samr_OpenAlias
    4320             :  ********************************************************************/
    4321             : 
    4322         618 : NTSTATUS _samr_OpenAlias(struct pipes_struct *p,
    4323             :                          struct samr_OpenAlias *r)
    4324             : {
    4325         618 :         struct dcesrv_call_state *dce_call = p->dce_call;
    4326           0 :         struct auth_session_info *session_info =
    4327         618 :                 dcesrv_call_session_info(dce_call);
    4328           0 :         struct dom_sid sid;
    4329         618 :         uint32_t alias_rid = r->in.rid;
    4330           0 :         struct samr_info *dinfo;
    4331         618 :         struct security_descriptor *psd = NULL;
    4332           0 :         uint32_t    acc_granted;
    4333         618 :         uint32_t    des_access = r->in.access_mask;
    4334           0 :         size_t    sd_size;
    4335           0 :         NTSTATUS  status;
    4336             : 
    4337         618 :         dinfo = samr_policy_handle_find(p,
    4338         618 :                                         r->in.domain_handle,
    4339             :                                         SAMR_HANDLE_DOMAIN,
    4340             :                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
    4341             :                                         NULL,
    4342             :                                         &status);
    4343         618 :         if (!NT_STATUS_IS_OK(status)) {
    4344           0 :                 return status;
    4345             :         }
    4346             : 
    4347             :         /* append the alias' RID to it */
    4348             : 
    4349         618 :         if (!sid_compose(&sid, &dinfo->sid, alias_rid))
    4350           0 :                 return NT_STATUS_NO_SUCH_ALIAS;
    4351             : 
    4352             :         /*check if access can be granted as requested by client. */
    4353             : 
    4354         618 :         map_max_allowed_access(session_info->security_token,
    4355         618 :                                session_info->unix_token,
    4356             :                                &des_access);
    4357             : 
    4358         618 :         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
    4359         618 :         se_map_generic(&des_access,&ali_generic_mapping);
    4360             : 
    4361         618 :         status = access_check_object(psd, session_info->security_token,
    4362             :                                      SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID,
    4363             :                                      GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
    4364             :                                      des_access, &acc_granted, "_samr_OpenAlias");
    4365             : 
    4366         618 :         if ( !NT_STATUS_IS_OK(status) )
    4367           0 :                 return status;
    4368             : 
    4369             :         {
    4370             :                 /* Check we actually have the requested alias */
    4371           0 :                 enum lsa_SidType type;
    4372           0 :                 bool result;
    4373           0 :                 gid_t gid;
    4374             : 
    4375         618 :                 become_root();
    4376         618 :                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
    4377         618 :                 unbecome_root();
    4378             : 
    4379         618 :                 if (!result || (type != SID_NAME_ALIAS)) {
    4380           0 :                         return NT_STATUS_NO_SUCH_ALIAS;
    4381             :                 }
    4382             : 
    4383             :                 /* make sure there is a mapping */
    4384             : 
    4385         618 :                 if ( !sid_to_gid( &sid, &gid ) ) {
    4386           0 :                         return NT_STATUS_NO_SUCH_ALIAS;
    4387             :                 }
    4388             : 
    4389             :         }
    4390             : 
    4391         618 :         status = create_samr_policy_handle(p->mem_ctx,
    4392             :                                            p,
    4393             :                                            SAMR_HANDLE_ALIAS,
    4394             :                                            acc_granted,
    4395             :                                            &sid,
    4396             :                                            NULL,
    4397             :                                            r->out.alias_handle);
    4398         618 :         if (!NT_STATUS_IS_OK(status)) {
    4399           0 :                 return status;
    4400             :         }
    4401             : 
    4402         618 :         return NT_STATUS_OK;
    4403             : }
    4404             : 
    4405             : /*******************************************************************
    4406             :  set_user_info_2
    4407             :  ********************************************************************/
    4408             : 
    4409           4 : static NTSTATUS set_user_info_2(TALLOC_CTX *mem_ctx,
    4410             :                                 struct samr_UserInfo2 *id2,
    4411             :                                 struct samu *pwd)
    4412             : {
    4413           4 :         if (id2 == NULL) {
    4414           0 :                 DEBUG(5,("set_user_info_2: NULL id2\n"));
    4415           0 :                 return NT_STATUS_ACCESS_DENIED;
    4416             :         }
    4417             : 
    4418           4 :         copy_id2_to_sam_passwd(pwd, id2);
    4419             : 
    4420           4 :         return pdb_update_sam_account(pwd);
    4421             : }
    4422             : 
    4423             : /*******************************************************************
    4424             :  set_user_info_4
    4425             :  ********************************************************************/
    4426             : 
    4427           6 : static NTSTATUS set_user_info_4(TALLOC_CTX *mem_ctx,
    4428             :                                 struct samr_UserInfo4 *id4,
    4429             :                                 struct samu *pwd)
    4430             : {
    4431           6 :         if (id4 == NULL) {
    4432           0 :                 DEBUG(5,("set_user_info_2: NULL id4\n"));
    4433           0 :                 return NT_STATUS_ACCESS_DENIED;
    4434             :         }
    4435             : 
    4436           6 :         copy_id4_to_sam_passwd(pwd, id4);
    4437             : 
    4438           6 :         return pdb_update_sam_account(pwd);
    4439             : }
    4440             : 
    4441             : /*******************************************************************
    4442             :  set_user_info_6
    4443             :  ********************************************************************/
    4444             : 
    4445          24 : static NTSTATUS set_user_info_6(TALLOC_CTX *mem_ctx,
    4446             :                                 struct samr_UserInfo6 *id6,
    4447             :                                 struct samu *pwd)
    4448             : {
    4449          24 :         if (id6 == NULL) {
    4450           0 :                 DEBUG(5,("set_user_info_6: NULL id6\n"));
    4451           0 :                 return NT_STATUS_ACCESS_DENIED;
    4452             :         }
    4453             : 
    4454          24 :         copy_id6_to_sam_passwd(pwd, id6);
    4455             : 
    4456          24 :         return pdb_update_sam_account(pwd);
    4457             : }
    4458             : 
    4459             : /*******************************************************************
    4460             :  set_user_info_7
    4461             :  ********************************************************************/
    4462             : 
    4463           6 : static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
    4464             :                                 struct samr_UserInfo7 *id7,
    4465             :                                 struct samu *pwd)
    4466             : {
    4467           0 :         NTSTATUS rc;
    4468             : 
    4469           6 :         if (id7 == NULL) {
    4470           0 :                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
    4471           0 :                 return NT_STATUS_ACCESS_DENIED;
    4472             :         }
    4473             : 
    4474           6 :         if (!id7->account_name.string) {
    4475           0 :                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
    4476           0 :                 return NT_STATUS_ACCESS_DENIED;
    4477             :         }
    4478             : 
    4479             :         /* check to see if the new username already exists.  Note: we can't
    4480             :            reliably lock all backends, so there is potentially the
    4481             :            possibility that a user can be created in between this check and
    4482             :            the rename.  The rename should fail, but may not get the
    4483             :            exact same failure status code.  I think this is small enough
    4484             :            of a window for this type of operation and the results are
    4485             :            simply that the rename fails with a slightly different status
    4486             :            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
    4487             : 
    4488           6 :         rc = can_create(mem_ctx, id7->account_name.string);
    4489             : 
    4490             :         /* when there is nothing to change, we're done here */
    4491           6 :         if (NT_STATUS_EQUAL(rc, NT_STATUS_USER_EXISTS) &&
    4492           0 :             strequal(id7->account_name.string, pdb_get_username(pwd))) {
    4493           0 :                 return NT_STATUS_OK;
    4494             :         }
    4495           6 :         if (!NT_STATUS_IS_OK(rc)) {
    4496           0 :                 return rc;
    4497             :         }
    4498             : 
    4499           6 :         rc = pdb_rename_sam_account(pwd, id7->account_name.string);
    4500             : 
    4501           6 :         return rc;
    4502             : }
    4503             : 
    4504             : /*******************************************************************
    4505             :  set_user_info_8
    4506             :  ********************************************************************/
    4507             : 
    4508           4 : static NTSTATUS set_user_info_8(TALLOC_CTX *mem_ctx,
    4509             :                                 struct samr_UserInfo8 *id8,
    4510             :                                 struct samu *pwd)
    4511             : {
    4512           4 :         if (id8 == NULL) {
    4513           0 :                 DEBUG(5,("set_user_info_8: NULL id8\n"));
    4514           0 :                 return NT_STATUS_ACCESS_DENIED;
    4515             :         }
    4516             : 
    4517           4 :         copy_id8_to_sam_passwd(pwd, id8);
    4518             : 
    4519           4 :         return pdb_update_sam_account(pwd);
    4520             : }
    4521             : 
    4522             : /*******************************************************************
    4523             :  set_user_info_10
    4524             :  ********************************************************************/
    4525             : 
    4526          12 : static NTSTATUS set_user_info_10(TALLOC_CTX *mem_ctx,
    4527             :                                  struct samr_UserInfo10 *id10,
    4528             :                                  struct samu *pwd)
    4529             : {
    4530          12 :         if (id10 == NULL) {
    4531           0 :                 DEBUG(5,("set_user_info_8: NULL id10\n"));
    4532           0 :                 return NT_STATUS_ACCESS_DENIED;
    4533             :         }
    4534             : 
    4535          12 :         copy_id10_to_sam_passwd(pwd, id10);
    4536             : 
    4537          12 :         return pdb_update_sam_account(pwd);
    4538             : }
    4539             : 
    4540             : /*******************************************************************
    4541             :  set_user_info_11
    4542             :  ********************************************************************/
    4543             : 
    4544           6 : static NTSTATUS set_user_info_11(TALLOC_CTX *mem_ctx,
    4545             :                                  struct samr_UserInfo11 *id11,
    4546             :                                  struct samu *pwd)
    4547             : {
    4548           6 :         if (id11 == NULL) {
    4549           0 :                 DEBUG(5,("set_user_info_11: NULL id11\n"));
    4550           0 :                 return NT_STATUS_ACCESS_DENIED;
    4551             :         }
    4552             : 
    4553           6 :         copy_id11_to_sam_passwd(pwd, id11);
    4554             : 
    4555           6 :         return pdb_update_sam_account(pwd);
    4556             : }
    4557             : 
    4558             : /*******************************************************************
    4559             :  set_user_info_12
    4560             :  ********************************************************************/
    4561             : 
    4562           6 : static NTSTATUS set_user_info_12(TALLOC_CTX *mem_ctx,
    4563             :                                  struct samr_UserInfo12 *id12,
    4564             :                                  struct samu *pwd)
    4565             : {
    4566           6 :         if (id12 == NULL) {
    4567           0 :                 DEBUG(5,("set_user_info_12: NULL id12\n"));
    4568           0 :                 return NT_STATUS_ACCESS_DENIED;
    4569             :         }
    4570             : 
    4571           6 :         copy_id12_to_sam_passwd(pwd, id12);
    4572             : 
    4573           6 :         return pdb_update_sam_account(pwd);
    4574             : }
    4575             : 
    4576             : /*******************************************************************
    4577             :  set_user_info_13
    4578             :  ********************************************************************/
    4579             : 
    4580           6 : static NTSTATUS set_user_info_13(TALLOC_CTX *mem_ctx,
    4581             :                                  struct samr_UserInfo13 *id13,
    4582             :                                  struct samu *pwd)
    4583             : {
    4584           6 :         if (id13 == NULL) {
    4585           0 :                 DEBUG(5,("set_user_info_13: NULL id13\n"));
    4586           0 :                 return NT_STATUS_ACCESS_DENIED;
    4587             :         }
    4588             : 
    4589           6 :         copy_id13_to_sam_passwd(pwd, id13);
    4590             : 
    4591           6 :         return pdb_update_sam_account(pwd);
    4592             : }
    4593             : 
    4594             : /*******************************************************************
    4595             :  set_user_info_14
    4596             :  ********************************************************************/
    4597             : 
    4598           6 : static NTSTATUS set_user_info_14(TALLOC_CTX *mem_ctx,
    4599             :                                  struct samr_UserInfo14 *id14,
    4600             :                                  struct samu *pwd)
    4601             : {
    4602           6 :         if (id14 == NULL) {
    4603           0 :                 DEBUG(5,("set_user_info_14: NULL id14\n"));
    4604           0 :                 return NT_STATUS_ACCESS_DENIED;
    4605             :         }
    4606             : 
    4607           6 :         copy_id14_to_sam_passwd(pwd, id14);
    4608             : 
    4609           6 :         return pdb_update_sam_account(pwd);
    4610             : }
    4611             : 
    4612             : /*******************************************************************
    4613             :  set_user_info_16
    4614             :  ********************************************************************/
    4615             : 
    4616          41 : static NTSTATUS set_user_info_16(TALLOC_CTX *mem_ctx,
    4617             :                                  struct samr_UserInfo16 *id16,
    4618             :                                  struct samu *pwd)
    4619             : {
    4620          41 :         if (id16 == NULL) {
    4621           0 :                 DEBUG(5,("set_user_info_16: NULL id16\n"));
    4622           0 :                 return NT_STATUS_ACCESS_DENIED;
    4623             :         }
    4624             : 
    4625          41 :         copy_id16_to_sam_passwd(pwd, id16);
    4626             : 
    4627          41 :         return pdb_update_sam_account(pwd);
    4628             : }
    4629             : 
    4630             : /*******************************************************************
    4631             :  set_user_info_17
    4632             :  ********************************************************************/
    4633             : 
    4634           4 : static NTSTATUS set_user_info_17(TALLOC_CTX *mem_ctx,
    4635             :                                  struct samr_UserInfo17 *id17,
    4636             :                                  struct samu *pwd)
    4637             : {
    4638           4 :         if (id17 == NULL) {
    4639           0 :                 DEBUG(5,("set_user_info_17: NULL id17\n"));
    4640           0 :                 return NT_STATUS_ACCESS_DENIED;
    4641             :         }
    4642             : 
    4643           4 :         copy_id17_to_sam_passwd(pwd, id17);
    4644             : 
    4645           4 :         return pdb_update_sam_account(pwd);
    4646             : }
    4647             : 
    4648             : /*******************************************************************
    4649             :  set_user_info_18
    4650             :  ********************************************************************/
    4651             : 
    4652          25 : static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
    4653             :                                  TALLOC_CTX *mem_ctx,
    4654             :                                  DATA_BLOB *session_key,
    4655             :                                  struct samu *pwd)
    4656             : {
    4657           0 :         int rc;
    4658             : 
    4659          25 :         if (id18 == NULL) {
    4660           0 :                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
    4661           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4662             :         }
    4663             : 
    4664          25 :         if (id18->nt_pwd_active || id18->lm_pwd_active) {
    4665          25 :                 if (!session_key->length) {
    4666           0 :                         return NT_STATUS_NO_USER_SESSION_KEY;
    4667             :                 }
    4668             :         }
    4669             : 
    4670          25 :         if (id18->nt_pwd_active) {
    4671          25 :                 DATA_BLOB in = data_blob_const(id18->nt_pwd.hash, 16);
    4672          25 :                 uint8_t outbuf[16] = { 0, };
    4673          25 :                 DATA_BLOB out = data_blob_const(outbuf, sizeof(outbuf));
    4674             : 
    4675          25 :                 rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
    4676          25 :                 if (rc != 0) {
    4677           0 :                         return gnutls_error_to_ntstatus(rc,
    4678             :                                                         NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
    4679             :                 }
    4680             : 
    4681          25 :                 if (!pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED)) {
    4682           0 :                         return NT_STATUS_ACCESS_DENIED;
    4683             :                 }
    4684             : 
    4685          25 :                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
    4686             :         }
    4687             : 
    4688          25 :         if (id18->lm_pwd_active) {
    4689          17 :                 DATA_BLOB in = data_blob_const(id18->lm_pwd.hash, 16);
    4690          17 :                 uint8_t outbuf[16] = { 0, };
    4691          17 :                 DATA_BLOB out = data_blob_const(outbuf, sizeof(outbuf));
    4692             : 
    4693          17 :                 rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
    4694          17 :                 if (rc != 0) {
    4695           0 :                         return gnutls_error_to_ntstatus(rc,
    4696             :                                                         NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
    4697             :                 }
    4698             : 
    4699          17 :                 if (!pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED)) {
    4700           0 :                         return NT_STATUS_ACCESS_DENIED;
    4701             :                 }
    4702             : 
    4703          17 :                 pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
    4704             :         }
    4705             : 
    4706          25 :         copy_id18_to_sam_passwd(pwd, id18);
    4707             : 
    4708          25 :         return pdb_update_sam_account(pwd);
    4709             : }
    4710             : 
    4711             : /*******************************************************************
    4712             :  set_user_info_20
    4713             :  ********************************************************************/
    4714             : 
    4715           4 : static NTSTATUS set_user_info_20(TALLOC_CTX *mem_ctx,
    4716             :                                  struct samr_UserInfo20 *id20,
    4717             :                                  struct samu *pwd)
    4718             : {
    4719           4 :         if (id20 == NULL) {
    4720           0 :                 DEBUG(5,("set_user_info_20: NULL id20\n"));
    4721           0 :                 return NT_STATUS_ACCESS_DENIED;
    4722             :         }
    4723             : 
    4724           4 :         copy_id20_to_sam_passwd(pwd, id20);
    4725             : 
    4726           4 :         return pdb_update_sam_account(pwd);
    4727             : }
    4728             : 
    4729             : /*******************************************************************
    4730             :  set_user_info_21
    4731             :  ********************************************************************/
    4732             : 
    4733         231 : static NTSTATUS set_user_info_21(struct samr_UserInfo21 *id21,
    4734             :                                  TALLOC_CTX *mem_ctx,
    4735             :                                  DATA_BLOB *session_key,
    4736             :                                  struct samu *pwd)
    4737             : {
    4738           0 :         NTSTATUS status;
    4739           0 :         int rc;
    4740             : 
    4741         231 :         if (id21 == NULL) {
    4742           0 :                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
    4743           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4744             :         }
    4745             : 
    4746         231 :         if (id21->fields_present == 0) {
    4747           4 :                 return NT_STATUS_INVALID_PARAMETER;
    4748             :         }
    4749             : 
    4750         227 :         if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
    4751          20 :                 return NT_STATUS_ACCESS_DENIED;
    4752             :         }
    4753             : 
    4754         207 :         if (id21->fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
    4755          69 :                 if (id21->nt_password_set) {
    4756          69 :                         DATA_BLOB in = data_blob_const(
    4757          69 :                                 id21->nt_owf_password.array, 16);
    4758          69 :                         uint8_t outbuf[16] = { 0, };
    4759          69 :                         DATA_BLOB out = data_blob_const(
    4760             :                                 outbuf, sizeof(outbuf));
    4761             : 
    4762          69 :                         if ((id21->nt_owf_password.length != 16) ||
    4763          66 :                             (id21->nt_owf_password.size != 16)) {
    4764           3 :                                 return NT_STATUS_INVALID_PARAMETER;
    4765             :                         }
    4766             : 
    4767          66 :                         if (!session_key->length) {
    4768           0 :                                 return NT_STATUS_NO_USER_SESSION_KEY;
    4769             :                         }
    4770             : 
    4771          66 :                         rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
    4772          66 :                         if (rc != 0) {
    4773           0 :                                 return gnutls_error_to_ntstatus(rc,
    4774             :                                                                 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
    4775             :                         }
    4776             : 
    4777          66 :                         pdb_set_nt_passwd(pwd, out.data, PDB_CHANGED);
    4778          66 :                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
    4779             :                 }
    4780             :         }
    4781             : 
    4782         204 :         if (id21->fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
    4783          33 :                 if (id21->lm_password_set) {
    4784          33 :                         DATA_BLOB in = data_blob_const(
    4785          33 :                                 id21->lm_owf_password.array, 16);
    4786          33 :                         uint8_t outbuf[16] = { 0, };
    4787          33 :                         DATA_BLOB out = data_blob_const(
    4788             :                                 outbuf, sizeof(outbuf));
    4789             : 
    4790          33 :                         if ((id21->lm_owf_password.length != 16) ||
    4791          33 :                             (id21->lm_owf_password.size != 16)) {
    4792           0 :                                 return NT_STATUS_INVALID_PARAMETER;
    4793             :                         }
    4794             : 
    4795          33 :                         if (!session_key->length) {
    4796           0 :                                 return NT_STATUS_NO_USER_SESSION_KEY;
    4797             :                         }
    4798             : 
    4799          33 :                         rc = sess_crypt_blob(&out, &in, session_key, SAMBA_GNUTLS_DECRYPT);
    4800          33 :                         if (rc != 0) {
    4801           0 :                                 return gnutls_error_to_ntstatus(rc,
    4802             :                                                                 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
    4803             :                         }
    4804             : 
    4805          33 :                         pdb_set_lanman_passwd(pwd, out.data, PDB_CHANGED);
    4806          33 :                         pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
    4807             :                 }
    4808             :         }
    4809             : 
    4810             :         /* we need to separately check for an account rename first */
    4811             : 
    4812         204 :         if (id21->account_name.string &&
    4813           2 :             (!strequal(id21->account_name.string, pdb_get_username(pwd))))
    4814             :         {
    4815             : 
    4816             :                 /* check to see if the new username already exists.  Note: we can't
    4817             :                    reliably lock all backends, so there is potentially the
    4818             :                    possibility that a user can be created in between this check and
    4819             :                    the rename.  The rename should fail, but may not get the
    4820             :                    exact same failure status code.  I think this is small enough
    4821             :                    of a window for this type of operation and the results are
    4822             :                    simply that the rename fails with a slightly different status
    4823             :                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
    4824             : 
    4825           0 :                 status = can_create(mem_ctx, id21->account_name.string);
    4826           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4827           0 :                         return status;
    4828             :                 }
    4829             : 
    4830           0 :                 status = pdb_rename_sam_account(pwd, id21->account_name.string);
    4831             : 
    4832           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4833           0 :                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
    4834             :                                 nt_errstr(status)));
    4835           0 :                         return status;
    4836             :                 }
    4837             : 
    4838             :                 /* set the new username so that later
    4839             :                    functions can work on the new account */
    4840           0 :                 pdb_set_username(pwd, id21->account_name.string, PDB_SET);
    4841             :         }
    4842             : 
    4843         204 :         copy_id21_to_sam_passwd("INFO_21", pwd, id21);
    4844             : 
    4845             :         /*
    4846             :          * The funny part about the previous two calls is
    4847             :          * that pwd still has the password hashes from the
    4848             :          * passdb entry.  These have not been updated from
    4849             :          * id21.  I don't know if they need to be set.    --jerry
    4850             :          */
    4851             : 
    4852         204 :         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
    4853           0 :                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
    4854           0 :                 if ( !NT_STATUS_IS_OK(status) ) {
    4855           0 :                         return status;
    4856             :                 }
    4857             :         }
    4858             : 
    4859             :         /* Don't worry about writing out the user account since the
    4860             :            primary group SID is generated solely from the user's Unix
    4861             :            primary group. */
    4862             : 
    4863             :         /* write the change out */
    4864         204 :         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
    4865           0 :                 return status;
    4866             :         }
    4867             : 
    4868         204 :         return NT_STATUS_OK;
    4869             : }
    4870             : 
    4871             : /*******************************************************************
    4872             :  set_user_info_23
    4873             :  ********************************************************************/
    4874             : 
    4875           8 : static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
    4876             :                                  struct samr_UserInfo23 *id23,
    4877             :                                  const char *rhost,
    4878             :                                  struct samu *pwd)
    4879             : {
    4880           8 :         char *plaintext_buf = NULL;
    4881           8 :         size_t len = 0;
    4882           0 :         uint32_t acct_ctrl;
    4883           0 :         NTSTATUS status;
    4884             : 
    4885           8 :         if (id23 == NULL) {
    4886           0 :                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
    4887           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4888             :         }
    4889             : 
    4890           8 :         if (id23->info.fields_present == 0) {
    4891           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4892             :         }
    4893             : 
    4894           8 :         if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
    4895           0 :                 return NT_STATUS_ACCESS_DENIED;
    4896             :         }
    4897             : 
    4898           8 :         if ((id23->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
    4899           2 :             (id23->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
    4900             : 
    4901           8 :                 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
    4902             :                           pdb_get_username(pwd)));
    4903             : 
    4904           8 :                 if (!decode_pw_buffer(mem_ctx,
    4905           8 :                                       id23->password.data,
    4906             :                                       &plaintext_buf,
    4907             :                                       &len,
    4908             :                                       CH_UTF16)) {
    4909           3 :                         return NT_STATUS_WRONG_PASSWORD;
    4910             :                 }
    4911             : 
    4912           5 :                 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
    4913           0 :                         return NT_STATUS_ACCESS_DENIED;
    4914             :                 }
    4915             :         }
    4916             : 
    4917           5 :         copy_id23_to_sam_passwd(pwd, id23);
    4918             : 
    4919           5 :         acct_ctrl = pdb_get_acct_ctrl(pwd);
    4920             : 
    4921             :         /* if it's a trust account, don't update /etc/passwd */
    4922           5 :         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
    4923           5 :                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
    4924           5 :                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
    4925           0 :                 DEBUG(5, ("Changing trust account.  Not updating /etc/passwd\n"));
    4926           5 :         } else if (plaintext_buf) {
    4927             :                 /* update the UNIX password */
    4928           5 :                 if (lp_unix_password_sync() ) {
    4929           0 :                         struct passwd *passwd;
    4930           0 :                         if (pdb_get_username(pwd) == NULL) {
    4931           0 :                                 DEBUG(1, ("chgpasswd: User without name???\n"));
    4932           0 :                                 return NT_STATUS_ACCESS_DENIED;
    4933             :                         }
    4934             : 
    4935           0 :                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
    4936           0 :                         if (passwd == NULL) {
    4937           0 :                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
    4938             :                         }
    4939             : 
    4940           0 :                         if(!chgpasswd(pdb_get_username(pwd), rhost,
    4941             :                                       passwd, "", plaintext_buf, True)) {
    4942           0 :                                 return NT_STATUS_ACCESS_DENIED;
    4943             :                         }
    4944           0 :                         TALLOC_FREE(passwd);
    4945             :                 }
    4946             :         }
    4947             : 
    4948           5 :         BURN_STR(plaintext_buf);
    4949             : 
    4950           5 :         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
    4951           0 :             (!NT_STATUS_IS_OK(status =  pdb_set_unix_primary_group(mem_ctx,
    4952             :                                                                    pwd)))) {
    4953           0 :                 return status;
    4954             :         }
    4955             : 
    4956           5 :         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
    4957           0 :                 return status;
    4958             :         }
    4959             : 
    4960           5 :         return NT_STATUS_OK;
    4961             : }
    4962             : 
    4963             : /*******************************************************************
    4964             :  set_user_info_pw
    4965             :  ********************************************************************/
    4966             : 
    4967         202 : static bool set_user_info_pw(uint8_t *pass, const char *rhost, struct samu *pwd)
    4968             : {
    4969         202 :         size_t len = 0;
    4970         202 :         char *plaintext_buf = NULL;
    4971           0 :         uint32_t acct_ctrl;
    4972             : 
    4973         202 :         DEBUG(5, ("Attempting administrator password change for user %s\n",
    4974             :                   pdb_get_username(pwd)));
    4975             : 
    4976         202 :         acct_ctrl = pdb_get_acct_ctrl(pwd);
    4977             : 
    4978         202 :         if (!decode_pw_buffer(talloc_tos(),
    4979             :                                 pass,
    4980             :                                 &plaintext_buf,
    4981             :                                 &len,
    4982             :                                 CH_UTF16)) {
    4983           4 :                 return False;
    4984             :         }
    4985             : 
    4986         198 :         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
    4987           0 :                 return False;
    4988             :         }
    4989             : 
    4990             :         /* if it's a trust account, don't update /etc/passwd */
    4991         198 :         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
    4992         198 :                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
    4993         163 :                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
    4994          64 :                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
    4995             :         } else {
    4996             :                 /* update the UNIX password */
    4997         134 :                 if (lp_unix_password_sync()) {
    4998           0 :                         struct passwd *passwd;
    4999             : 
    5000           0 :                         if (pdb_get_username(pwd) == NULL) {
    5001           0 :                                 DEBUG(1, ("chgpasswd: User without name???\n"));
    5002           0 :                                 return False;
    5003             :                         }
    5004             : 
    5005           0 :                         passwd = Get_Pwnam_alloc(pwd, pdb_get_username(pwd));
    5006           0 :                         if (passwd == NULL) {
    5007           0 :                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
    5008             :                         }
    5009             : 
    5010           0 :                         if(!chgpasswd(pdb_get_username(pwd), rhost, passwd,
    5011             :                                       "", plaintext_buf, True)) {
    5012           0 :                                 return False;
    5013             :                         }
    5014           0 :                         TALLOC_FREE(passwd);
    5015             :                 }
    5016             :         }
    5017             : 
    5018         198 :         BURN_STR(plaintext_buf);
    5019             : 
    5020         198 :         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
    5021             : 
    5022         198 :         return True;
    5023             : }
    5024             : 
    5025             : static bool
    5026           4 : set_user_info_pw_aes(DATA_BLOB *pw_data, const char *rhost, struct samu *pwd)
    5027             : {
    5028           0 :         uint32_t acct_ctrl;
    5029           4 :         DATA_BLOB new_password = {
    5030             :                 .length = 0,
    5031             :         };
    5032           0 :         bool ok;
    5033             : 
    5034           4 :         DBG_NOTICE("Attempting administrator password change for user %s\n",
    5035             :                    pdb_get_username(pwd));
    5036             : 
    5037           4 :         acct_ctrl = pdb_get_acct_ctrl(pwd);
    5038             : 
    5039           4 :         ok = decode_pwd_string_from_buffer514(talloc_tos(),
    5040           4 :                                               pw_data->data,
    5041             :                                               CH_UTF16,
    5042             :                                               &new_password);
    5043           4 :         if (!ok) {
    5044           0 :                 return false;
    5045             :         }
    5046             : 
    5047           4 :         ok = pdb_set_plaintext_passwd(pwd, (char *)new_password.data);
    5048           4 :         if (!ok) {
    5049           0 :                 return false;
    5050             :         }
    5051             : 
    5052             :         /* if it's a trust account, don't update /etc/passwd */
    5053           4 :         if (((acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST) ||
    5054           4 :             ((acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
    5055           4 :             ((acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST)) {
    5056           0 :                 DBG_NOTICE("Changing trust account or non-unix-user password, "
    5057             :                            "not updating /etc/passwd\n");
    5058             :         } else {
    5059             :                 /* update the UNIX password */
    5060           4 :                 if (lp_unix_password_sync()) {
    5061           0 :                         struct passwd *passwd;
    5062           0 :                         const char *username;
    5063             : 
    5064           0 :                         username = pdb_get_username(pwd);
    5065           0 :                         if (username == NULL) {
    5066           0 :                                 DBG_WARNING("User unknown\n");
    5067           0 :                                 return false;
    5068             :                         }
    5069             : 
    5070           0 :                         passwd = Get_Pwnam_alloc(pwd, username);
    5071           0 :                         if (passwd == NULL) {
    5072           0 :                                 DBG_WARNING("chgpasswd: Username does not "
    5073             :                                             "exist on system !?!\n");
    5074             :                         }
    5075             : 
    5076           0 :                         ok = chgpasswd(username,
    5077             :                                        rhost,
    5078             :                                        passwd,
    5079             :                                        "",
    5080           0 :                                        (char *)new_password.data,
    5081             :                                        true);
    5082           0 :                         if (!ok) {
    5083           0 :                                 return false;
    5084             :                         }
    5085           0 :                         TALLOC_FREE(passwd);
    5086             :                 }
    5087             :         }
    5088           4 :         TALLOC_FREE(new_password.data);
    5089             : 
    5090           4 :         DBG_NOTICE("pdb_update_pwd()\n");
    5091             : 
    5092           4 :         return true;
    5093             : }
    5094             : 
    5095             : /*******************************************************************
    5096             :  set_user_info_24
    5097             :  ********************************************************************/
    5098             : 
    5099         111 : static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
    5100             :                                  const char *rhost,
    5101             :                                  struct samr_UserInfo24 *id24,
    5102             :                                  struct samu *pwd)
    5103             : {
    5104           0 :         NTSTATUS status;
    5105             : 
    5106         111 :         if (id24 == NULL) {
    5107           0 :                 DEBUG(5, ("set_user_info_24: NULL id24\n"));
    5108           0 :                 return NT_STATUS_INVALID_PARAMETER;
    5109             :         }
    5110             : 
    5111         111 :         if (!set_user_info_pw(id24->password.data, rhost, pwd)) {
    5112           0 :                 return NT_STATUS_WRONG_PASSWORD;
    5113             :         }
    5114             : 
    5115         111 :         copy_id24_to_sam_passwd(pwd, id24);
    5116             : 
    5117         111 :         status = pdb_update_sam_account(pwd);
    5118         111 :         if (!NT_STATUS_IS_OK(status)) {
    5119           0 :                 return status;
    5120             :         }
    5121             : 
    5122         111 :         return NT_STATUS_OK;
    5123             : }
    5124             : 
    5125             : /*******************************************************************
    5126             :  set_user_info_25
    5127             :  ********************************************************************/
    5128             : 
    5129          53 : static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
    5130             :                                  const char *rhost,
    5131             :                                  struct samr_UserInfo25 *id25,
    5132             :                                  struct samu *pwd)
    5133             : {
    5134           0 :         NTSTATUS status;
    5135             : 
    5136          53 :         if (id25 == NULL) {
    5137           0 :                 DEBUG(5, ("set_user_info_25: NULL id25\n"));
    5138           0 :                 return NT_STATUS_INVALID_PARAMETER;
    5139             :         }
    5140             : 
    5141          53 :         if (id25->info.fields_present == 0) {
    5142           0 :                 return NT_STATUS_INVALID_PARAMETER;
    5143             :         }
    5144             : 
    5145          53 :         if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
    5146           0 :                 return NT_STATUS_ACCESS_DENIED;
    5147             :         }
    5148             : 
    5149          53 :         if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
    5150           2 :             (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
    5151             : 
    5152          53 :                 if (!set_user_info_pw(id25->password.data, rhost, pwd)) {
    5153           3 :                         return NT_STATUS_WRONG_PASSWORD;
    5154             :                 }
    5155             :         }
    5156             : 
    5157          50 :         copy_id25_to_sam_passwd(pwd, id25);
    5158             : 
    5159             :         /* write the change out */
    5160          50 :         if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
    5161           0 :                 return status;
    5162             :         }
    5163             : 
    5164             :         /*
    5165             :          * We need to "pdb_update_sam_account" before the unix primary group
    5166             :          * is set, because the idealx scripts would also change the
    5167             :          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
    5168             :          * the delete explicit / add explicit, which would then fail to find
    5169             :          * the previous primaryGroupSid value.
    5170             :          */
    5171             : 
    5172          50 :         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
    5173           0 :                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
    5174           0 :                 if ( !NT_STATUS_IS_OK(status) ) {
    5175           0 :                         return status;
    5176             :                 }
    5177             :         }
    5178             : 
    5179          50 :         return NT_STATUS_OK;
    5180             : }
    5181             : 
    5182             : /*******************************************************************
    5183             :  set_user_info_26
    5184             :  ********************************************************************/
    5185             : 
    5186          38 : static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
    5187             :                                  const char *rhost,
    5188             :                                  struct samr_UserInfo26 *id26,
    5189             :                                  struct samu *pwd)
    5190             : {
    5191           0 :         NTSTATUS status;
    5192             : 
    5193          38 :         if (id26 == NULL) {
    5194           0 :                 DEBUG(5, ("set_user_info_26: NULL id26\n"));
    5195           0 :                 return NT_STATUS_INVALID_PARAMETER;
    5196             :         }
    5197             : 
    5198          38 :         if (!set_user_info_pw(id26->password.data, rhost, pwd)) {
    5199           1 :                 return NT_STATUS_WRONG_PASSWORD;
    5200             :         }
    5201             : 
    5202          37 :         copy_pwd_expired_to_sam_passwd(pwd, id26->password_expired);
    5203             : 
    5204          37 :         status = pdb_update_sam_account(pwd);
    5205          37 :         if (!NT_STATUS_IS_OK(status)) {
    5206           0 :                 return status;
    5207             :         }
    5208             : 
    5209          37 :         return NT_STATUS_OK;
    5210             : }
    5211             : 
    5212           1 : static NTSTATUS set_user_info_31(TALLOC_CTX *mem_ctx,
    5213             :                                  const char *rhost,
    5214             :                                  DATA_BLOB *pw_data,
    5215             :                                  uint8_t password_expired,
    5216             :                                  struct samu *pwd)
    5217             : {
    5218           0 :         NTSTATUS status;
    5219           0 :         bool ok;
    5220             : 
    5221           1 :         if (pw_data->length == 0 || pw_data->length > 514) {
    5222           0 :                 return NT_STATUS_WRONG_PASSWORD;
    5223             :         }
    5224             : 
    5225           1 :         ok = set_user_info_pw_aes(pw_data, rhost, pwd);
    5226           1 :         if (!ok) {
    5227           0 :                 return NT_STATUS_WRONG_PASSWORD;
    5228             :         }
    5229             : 
    5230           1 :         copy_pwd_expired_to_sam_passwd(pwd, password_expired);
    5231             : 
    5232           1 :         status = pdb_update_sam_account(pwd);
    5233           1 :         if (!NT_STATUS_IS_OK(status)) {
    5234           0 :                 return status;
    5235             :         }
    5236             : 
    5237           1 :         return NT_STATUS_OK;
    5238             : }
    5239             : 
    5240           3 : static NTSTATUS set_user_info_32(TALLOC_CTX *mem_ctx,
    5241             :                                  const char *rhost,
    5242             :                                  DATA_BLOB *pw_data,
    5243             :                                  struct samr_UserInfo32 *id32,
    5244             :                                  struct samu *pwd)
    5245             : {
    5246           0 :         NTSTATUS status;
    5247           0 :         bool ok;
    5248             : 
    5249           3 :         if (pw_data->length == 0 || pw_data->length > 514) {
    5250           0 :                 return NT_STATUS_WRONG_PASSWORD;
    5251             :         }
    5252             : 
    5253           3 :         if (id32 == NULL) {
    5254           0 :                 return NT_STATUS_INVALID_PARAMETER;
    5255             :         }
    5256             : 
    5257           3 :         if (id32->info.fields_present == 0) {
    5258           0 :                 return NT_STATUS_INVALID_PARAMETER;
    5259             :         }
    5260             : 
    5261           3 :         if (id32->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
    5262           0 :                 return NT_STATUS_ACCESS_DENIED;
    5263             :         }
    5264             : 
    5265           3 :         if ((id32->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
    5266           1 :             (id32->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
    5267           3 :                 ok = set_user_info_pw_aes(pw_data, rhost, pwd);
    5268           3 :                 if (!ok) {
    5269           0 :                         return NT_STATUS_WRONG_PASSWORD;
    5270             :                 }
    5271             :         }
    5272             : 
    5273           3 :         copy_id32_to_sam_passwd(pwd, id32);
    5274             : 
    5275           3 :         status = pdb_update_sam_account(pwd);
    5276           3 :         if (!NT_STATUS_IS_OK(status)) {
    5277           0 :                 return status;
    5278             :         }
    5279             : 
    5280             :         /*
    5281             :          * We need to "pdb_update_sam_account" before the unix primary group
    5282             :          * is set, because the idealx scripts would also change the
    5283             :          * sambaPrimaryGroupSid using the ldap replace method. pdb_ldap uses
    5284             :          * the delete explicit / add explicit, which would then fail to find
    5285             :          * the previous primaryGroupSid value.
    5286             :          */
    5287           3 :         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID)) {
    5288           0 :                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
    5289           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5290           0 :                         return status;
    5291             :                 }
    5292             :         }
    5293             : 
    5294           3 :         return NT_STATUS_OK;
    5295             : }
    5296             : 
    5297             : /*************************************************************
    5298             : **************************************************************/
    5299             : 
    5300         298 : static uint32_t samr_set_user_info_map_fields_to_access_mask(uint32_t fields)
    5301             : {
    5302         298 :         uint32_t acc_required = 0;
    5303             : 
    5304             :         /* USER_ALL_USERNAME */
    5305         298 :         if (fields & SAMR_FIELD_ACCOUNT_NAME)
    5306           3 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5307             :         /* USER_ALL_FULLNAME */
    5308         298 :         if (fields & SAMR_FIELD_FULL_NAME)
    5309         108 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5310             :         /* USER_ALL_PRIMARYGROUPID */
    5311         298 :         if (fields & SAMR_FIELD_PRIMARY_GID)
    5312           2 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5313             :         /* USER_ALL_HOMEDIRECTORY */
    5314         298 :         if (fields & SAMR_FIELD_HOME_DIRECTORY)
    5315           6 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5316             :         /* USER_ALL_HOMEDIRECTORYDRIVE */
    5317         298 :         if (fields & SAMR_FIELD_HOME_DRIVE)
    5318           6 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5319             :         /* USER_ALL_SCRIPTPATH */
    5320         298 :         if (fields & SAMR_FIELD_LOGON_SCRIPT)
    5321           4 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5322             :         /* USER_ALL_PROFILEPATH */
    5323         298 :         if (fields & SAMR_FIELD_PROFILE_PATH)
    5324           4 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5325             :         /* USER_ALL_ADMINCOMMENT */
    5326         298 :         if (fields & SAMR_FIELD_COMMENT)
    5327          76 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5328             :         /* USER_ALL_WORKSTATIONS */
    5329         298 :         if (fields & SAMR_FIELD_WORKSTATIONS)
    5330          10 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5331             :         /* USER_ALL_LOGONHOURS */
    5332         298 :         if (fields & SAMR_FIELD_LOGON_HOURS)
    5333           4 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5334             :         /* USER_ALL_ACCOUNTEXPIRES */
    5335         298 :         if (fields & SAMR_FIELD_ACCT_EXPIRY)
    5336           8 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5337             :         /* USER_ALL_USERACCOUNTCONTROL */
    5338         298 :         if (fields & SAMR_FIELD_ACCT_FLAGS)
    5339          63 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5340             :         /* USER_ALL_PARAMETERS */
    5341         298 :         if (fields & SAMR_FIELD_PARAMETERS)
    5342           8 :                 acc_required |= SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5343             :         /* USER_ALL_USERCOMMENT */
    5344         298 :         if (fields & SAMR_FIELD_COMMENT)
    5345          76 :                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
    5346             :         /* USER_ALL_COUNTRYCODE */
    5347         298 :         if (fields & SAMR_FIELD_COUNTRY_CODE)
    5348           0 :                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
    5349             :         /* USER_ALL_CODEPAGE */
    5350         298 :         if (fields & SAMR_FIELD_CODE_PAGE)
    5351           0 :                 acc_required |= SAMR_USER_ACCESS_SET_LOC_COM;
    5352             :         /* USER_ALL_NTPASSWORDPRESENT */
    5353         298 :         if (fields & SAMR_FIELD_NT_PASSWORD_PRESENT)
    5354         142 :                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
    5355             :         /* USER_ALL_LMPASSWORDPRESENT */
    5356         298 :         if (fields & SAMR_FIELD_LM_PASSWORD_PRESENT)
    5357          57 :                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
    5358             :         /* USER_ALL_PASSWORDEXPIRED */
    5359         298 :         if (fields & SAMR_FIELD_EXPIRED_FLAG)
    5360          60 :                 acc_required |= SAMR_USER_ACCESS_SET_PASSWORD;
    5361             : 
    5362         298 :         return acc_required;
    5363             : }
    5364             : 
    5365         119 : static NTSTATUS arc4_decrypt_data(DATA_BLOB session_key,
    5366             :                                      uint8_t *data,
    5367             :                                      size_t data_size)
    5368             : {
    5369         119 :         gnutls_cipher_hd_t cipher_hnd = NULL;
    5370         119 :         gnutls_datum_t my_session_key = {
    5371         119 :                 .data = session_key.data,
    5372         119 :                 .size = session_key.length,
    5373             :         };
    5374         119 :         NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
    5375           0 :         int rc;
    5376             : 
    5377         119 :         rc = gnutls_cipher_init(&cipher_hnd,
    5378             :                                 GNUTLS_CIPHER_ARCFOUR_128,
    5379             :                                 &my_session_key,
    5380             :                                 NULL);
    5381         119 :         if (rc < 0) {
    5382           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
    5383           0 :                 goto out;
    5384             :         }
    5385             : 
    5386         119 :         rc = gnutls_cipher_decrypt(cipher_hnd,
    5387             :                                    data,
    5388             :                                    data_size);
    5389         119 :         gnutls_cipher_deinit(cipher_hnd);
    5390         119 :         if (rc < 0) {
    5391           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
    5392           0 :                 goto out;
    5393             :         }
    5394             : 
    5395         119 :         status = NT_STATUS_OK;
    5396         119 : out:
    5397         119 :         return status;
    5398             : }
    5399             : 
    5400             : /*******************************************************************
    5401             :  samr_SetUserInfo
    5402             :  ********************************************************************/
    5403             : 
    5404         603 : NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
    5405             :                            struct samr_SetUserInfo *r)
    5406             : {
    5407         603 :         struct dcesrv_call_state *dce_call = p->dce_call;
    5408         603 :         struct dcesrv_connection *dcesrv_conn = dce_call->conn;
    5409           0 :         const struct tsocket_address *remote_address =
    5410         603 :                 dcesrv_connection_get_remote_address(dcesrv_conn);
    5411           0 :         struct auth_session_info *session_info =
    5412         603 :                 dcesrv_call_session_info(dce_call);
    5413           0 :         struct samr_info *uinfo;
    5414           0 :         NTSTATUS status;
    5415         603 :         struct samu *pwd = NULL;
    5416         603 :         union samr_UserInfo *info = r->in.info;
    5417         603 :         uint32_t acc_required = 0;
    5418         603 :         uint32_t fields = 0;
    5419           0 :         bool ret;
    5420           0 :         char *rhost;
    5421           0 :         DATA_BLOB session_key;
    5422           0 :         struct dom_sid_buf buf;
    5423         603 :         struct loadparm_context *lp_ctx = NULL;
    5424           0 :         bool encrypted;
    5425             : 
    5426         603 :         lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
    5427         603 :         if (lp_ctx == NULL) {
    5428           0 :                 return NT_STATUS_NO_MEMORY;
    5429             :         }
    5430             : 
    5431             :         /* This is tricky.  A WinXP domain join sets
    5432             :           (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
    5433             :           The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser().  But the
    5434             :           standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser().
    5435             :           This should be enough for levels 18, 24, 25,& 26.  Info level 23 can set more so
    5436             :           we'll use the set from the WinXP join as the basis. */
    5437             : 
    5438         603 :         switch (r->in.level) {
    5439           4 :         case 2: /* UserPreferencesInformation */
    5440             :                 /* USER_WRITE_ACCOUNT | USER_WRITE_PREFERENCES */
    5441           4 :                 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES | SAMR_USER_ACCESS_SET_LOC_COM;
    5442           4 :                 break;
    5443         125 :         case 4: /* UserLogonHoursInformation */
    5444             :         case 6: /* UserNameInformation */
    5445             :         case 7: /* UserAccountNameInformation */
    5446             :         case 8: /* UserFullNameInformation */
    5447             :         case 9: /* UserPrimaryGroupInformation */
    5448             :         case 10: /* UserHomeInformation */
    5449             :         case 11: /* UserScriptInformation */
    5450             :         case 12: /* UserProfileInformation */
    5451             :         case 13: /* UserAdminCommentInformation */
    5452             :         case 14: /* UserWorkStationsInformation */
    5453             :         case 16: /* UserControlInformation */
    5454             :         case 17: /* UserExpiresInformation */
    5455             :         case 20: /* UserParametersInformation */
    5456             :                 /* USER_WRITE_ACCOUNT */
    5457         125 :                 acc_required = SAMR_USER_ACCESS_SET_ATTRIBUTES;
    5458         125 :                 break;
    5459          25 :         case 18: /* UserInternal1Information */
    5460             :                 /* FIXME: gd, this is a guess */
    5461          25 :                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
    5462          25 :                 break;
    5463         231 :         case 21: /* UserAllInformation */
    5464         231 :                 fields = info->info21.fields_present;
    5465         231 :                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
    5466         231 :                 break;
    5467           8 :         case 23: /* UserInternal4Information */
    5468           8 :                 fields = info->info23.info.fields_present;
    5469           8 :                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
    5470           8 :                 break;
    5471          53 :         case 25: /* UserInternal4InformationNew */
    5472          53 :                 fields = info->info25.info.fields_present;
    5473          53 :                 acc_required = samr_set_user_info_map_fields_to_access_mask(fields);
    5474          53 :                 break;
    5475         151 :         case 24: /* UserInternal5Information */
    5476             :         case 26: /* UserInternal5InformationNew */
    5477             :         case 31: /* UserInternal5InformationNew */
    5478         151 :                 acc_required = SAMR_USER_ACCESS_SET_PASSWORD;
    5479         151 :                 break;
    5480           6 :         case 32:
    5481           6 :                 fields = info->info32.info.fields_present;
    5482           0 :                 acc_required =
    5483           6 :                         samr_set_user_info_map_fields_to_access_mask(fields);
    5484           6 :                 break;
    5485           0 :         default:
    5486           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    5487             :         }
    5488             : 
    5489         603 :         uinfo = samr_policy_handle_find(p,
    5490         603 :                                         r->in.user_handle,
    5491             :                                         SAMR_HANDLE_USER,
    5492             :                                         acc_required,
    5493             :                                         NULL,
    5494             :                                         &status);
    5495         603 :         if (!NT_STATUS_IS_OK(status)) {
    5496           0 :                 return status;
    5497             :         }
    5498             : 
    5499         603 :         DEBUG(5, ("_samr_SetUserInfo: sid:%s, level:%d\n",
    5500             :                   dom_sid_str_buf(&uinfo->sid, &buf),
    5501             :                   r->in.level));
    5502             : 
    5503         603 :         if (info == NULL) {
    5504           0 :                 DEBUG(5, ("_samr_SetUserInfo: NULL info level\n"));
    5505           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    5506             :         }
    5507             : 
    5508         603 :         if (!(pwd = samu_new(NULL))) {
    5509           0 :                 return NT_STATUS_NO_MEMORY;
    5510             :         }
    5511             : 
    5512         603 :         become_root();
    5513         603 :         ret = pdb_getsampwsid(pwd, &uinfo->sid);
    5514         603 :         unbecome_root();
    5515             : 
    5516         603 :         if (!ret) {
    5517           0 :                 TALLOC_FREE(pwd);
    5518           0 :                 return NT_STATUS_NO_SUCH_USER;
    5519             :         }
    5520             : 
    5521         603 :         rhost = tsocket_address_inet_addr_string(remote_address,
    5522             :                                                  talloc_tos());
    5523         603 :         if (rhost == NULL) {
    5524           0 :                 return NT_STATUS_NO_MEMORY;
    5525             :         }
    5526             : 
    5527             :         /* ================ BEGIN Privilege BLOCK ================ */
    5528             : 
    5529         603 :         become_root();
    5530             : 
    5531             :         /* ok!  user info levels (lots: see MSDEV help), off we go... */
    5532             : 
    5533         603 :         switch (r->in.level) {
    5534             : 
    5535           4 :                 case 2:
    5536           4 :                         status = set_user_info_2(p->mem_ctx,
    5537             :                                                  &info->info2, pwd);
    5538         603 :                         break;
    5539             : 
    5540           6 :                 case 4:
    5541           6 :                         status = set_user_info_4(p->mem_ctx,
    5542             :                                                  &info->info4, pwd);
    5543           6 :                         break;
    5544             : 
    5545          24 :                 case 6:
    5546          24 :                         status = set_user_info_6(p->mem_ctx,
    5547             :                                                  &info->info6, pwd);
    5548          24 :                         break;
    5549             : 
    5550           6 :                 case 7:
    5551           6 :                         status = set_user_info_7(p->mem_ctx,
    5552             :                                                  &info->info7, pwd);
    5553           6 :                         break;
    5554             : 
    5555           4 :                 case 8:
    5556           4 :                         status = set_user_info_8(p->mem_ctx,
    5557             :                                                  &info->info8, pwd);
    5558           4 :                         break;
    5559             : 
    5560          12 :                 case 10:
    5561          12 :                         status = set_user_info_10(p->mem_ctx,
    5562             :                                                   &info->info10, pwd);
    5563          12 :                         break;
    5564             : 
    5565           6 :                 case 11:
    5566           6 :                         status = set_user_info_11(p->mem_ctx,
    5567             :                                                   &info->info11, pwd);
    5568           6 :                         break;
    5569             : 
    5570           6 :                 case 12:
    5571           6 :                         status = set_user_info_12(p->mem_ctx,
    5572             :                                                   &info->info12, pwd);
    5573           6 :                         break;
    5574             : 
    5575           6 :                 case 13:
    5576           6 :                         status = set_user_info_13(p->mem_ctx,
    5577             :                                                   &info->info13, pwd);
    5578           6 :                         break;
    5579             : 
    5580           6 :                 case 14:
    5581           6 :                         status = set_user_info_14(p->mem_ctx,
    5582             :                                                   &info->info14, pwd);
    5583           6 :                         break;
    5584             : 
    5585          41 :                 case 16:
    5586          41 :                         status = set_user_info_16(p->mem_ctx,
    5587             :                                                   &info->info16, pwd);
    5588          41 :                         break;
    5589             : 
    5590           4 :                 case 17:
    5591           4 :                         status = set_user_info_17(p->mem_ctx,
    5592             :                                                   &info->info17, pwd);
    5593           4 :                         break;
    5594             : 
    5595          25 :                 case 18:
    5596          25 :                         status = session_extract_session_key(
    5597             :                                 session_info, &session_key, KEY_USE_16BYTES);
    5598          25 :                         if(!NT_STATUS_IS_OK(status)) {
    5599           0 :                                 break;
    5600             :                         }
    5601             :                         /* Used by AS/U JRA. */
    5602          25 :                         status = set_user_info_18(&info->info18,
    5603             :                                                   p->mem_ctx,
    5604             :                                                   &session_key,
    5605             :                                                   pwd);
    5606          25 :                         break;
    5607             : 
    5608           4 :                 case 20:
    5609           4 :                         status = set_user_info_20(p->mem_ctx,
    5610             :                                                   &info->info20, pwd);
    5611           4 :                         break;
    5612             : 
    5613         231 :                 case 21:
    5614         231 :                         status = session_extract_session_key(
    5615             :                                 session_info, &session_key, KEY_USE_16BYTES);
    5616         231 :                         if(!NT_STATUS_IS_OK(status)) {
    5617           0 :                                 break;
    5618             :                         }
    5619         231 :                         status = set_user_info_21(&info->info21,
    5620             :                                                   p->mem_ctx,
    5621             :                                                   &session_key,
    5622             :                                                   pwd);
    5623         231 :                         break;
    5624             : 
    5625           8 :                 case 23:
    5626           0 :                         encrypted =
    5627           8 :                                 dcerpc_is_transport_encrypted(session_info);
    5628           8 :                         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
    5629           0 :                             !encrypted) {
    5630           0 :                                 status = NT_STATUS_ACCESS_DENIED;
    5631           0 :                                 break;
    5632             :                         }
    5633             : 
    5634           8 :                         status = session_extract_session_key(
    5635             :                                 session_info, &session_key, KEY_USE_16BYTES);
    5636           8 :                         if(!NT_STATUS_IS_OK(status)) {
    5637           0 :                                 break;
    5638             :                         }
    5639             :                         /*
    5640             :                          * This can be allowed as it requires a session key
    5641             :                          * which we only have if we have a SMB session.
    5642             :                          */
    5643           8 :                         GNUTLS_FIPS140_SET_LAX_MODE();
    5644           8 :                         status = arc4_decrypt_data(session_key,
    5645           8 :                                                    info->info23.password.data,
    5646             :                                                    516);
    5647           8 :                         GNUTLS_FIPS140_SET_STRICT_MODE();
    5648           8 :                         if(!NT_STATUS_IS_OK(status)) {
    5649           0 :                                 break;
    5650             :                         }
    5651             : 
    5652             : #ifdef DEBUG_PASSWORD
    5653           8 :                         dump_data(100, info->info23.password.data, 516);
    5654             : #endif
    5655             : 
    5656           8 :                         status = set_user_info_23(p->mem_ctx,
    5657             :                                                   &info->info23,
    5658             :                                                   rhost,
    5659             :                                                   pwd);
    5660           8 :                         break;
    5661             : 
    5662         111 :                 case 24:
    5663           0 :                         encrypted =
    5664         111 :                                 dcerpc_is_transport_encrypted(session_info);
    5665         111 :                         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
    5666           0 :                             !encrypted) {
    5667           0 :                                 status = NT_STATUS_ACCESS_DENIED;
    5668           0 :                                 break;
    5669             :                         }
    5670             : 
    5671         111 :                         status = session_extract_session_key(
    5672             :                                 session_info, &session_key, KEY_USE_16BYTES);
    5673         111 :                         if(!NT_STATUS_IS_OK(status)) {
    5674           0 :                                 break;
    5675             :                         }
    5676             :                         /*
    5677             :                          * This can be allowed as it requires a session key
    5678             :                          * which we only have if we have a SMB session.
    5679             :                          */
    5680         111 :                         GNUTLS_FIPS140_SET_LAX_MODE();
    5681         111 :                         status = arc4_decrypt_data(session_key,
    5682         111 :                                                    info->info24.password.data,
    5683             :                                                    516);
    5684         111 :                         GNUTLS_FIPS140_SET_STRICT_MODE();
    5685         111 :                         if(!NT_STATUS_IS_OK(status)) {
    5686           0 :                                 break;
    5687             :                         }
    5688             : 
    5689             : #ifdef DEBUG_PASSWORD
    5690         111 :                         dump_data(100, info->info24.password.data, 516);
    5691             : #endif
    5692             : 
    5693         111 :                         status = set_user_info_24(p->mem_ctx,
    5694             :                                                   rhost,
    5695             :                                                   &info->info24, pwd);
    5696         111 :                         break;
    5697             : 
    5698          53 :                 case 25:
    5699           0 :                         encrypted =
    5700          53 :                                 dcerpc_is_transport_encrypted(session_info);
    5701          53 :                         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
    5702           0 :                             !encrypted) {
    5703           0 :                                 status = NT_STATUS_ACCESS_DENIED;
    5704           0 :                                 break;
    5705             :                         }
    5706             : 
    5707          53 :                         status = session_extract_session_key(
    5708             :                                 session_info, &session_key, KEY_USE_16BYTES);
    5709          53 :                         if(!NT_STATUS_IS_OK(status)) {
    5710           0 :                                 break;
    5711             :                         }
    5712             :                         /*
    5713             :                          * This can be allowed as it requires a session key
    5714             :                          * which we only have if we have a SMB session.
    5715             :                          */
    5716          53 :                         GNUTLS_FIPS140_SET_LAX_MODE();
    5717          53 :                         status = decode_rc4_passwd_buffer(&session_key,
    5718             :                                         &info->info25.password);
    5719          53 :                         GNUTLS_FIPS140_SET_STRICT_MODE();
    5720          53 :                         if (!NT_STATUS_IS_OK(status)) {
    5721           0 :                                 break;
    5722             :                         }
    5723             : 
    5724             : #ifdef DEBUG_PASSWORD
    5725          53 :                         dump_data(100, info->info25.password.data, 532);
    5726             : #endif
    5727             : 
    5728          53 :                         status = set_user_info_25(p->mem_ctx,
    5729             :                                                   rhost,
    5730             :                                                   &info->info25, pwd);
    5731          53 :                         break;
    5732             : 
    5733          38 :                 case 26:
    5734           0 :                         encrypted =
    5735          38 :                                 dcerpc_is_transport_encrypted(session_info);
    5736          38 :                         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
    5737           0 :                             !encrypted) {
    5738           0 :                                 status = NT_STATUS_ACCESS_DENIED;
    5739           0 :                                 break;
    5740             :                         }
    5741             : 
    5742          38 :                         status = session_extract_session_key(
    5743             :                                 session_info, &session_key, KEY_USE_16BYTES);
    5744          38 :                         if(!NT_STATUS_IS_OK(status)) {
    5745           0 :                                 break;
    5746             :                         }
    5747             :                         /*
    5748             :                          * This can be allowed as it requires a session key
    5749             :                          * which we only have if we have a SMB session.
    5750             :                          */
    5751          38 :                         GNUTLS_FIPS140_SET_LAX_MODE();
    5752          38 :                         status = decode_rc4_passwd_buffer(&session_key,
    5753             :                                         &info->info26.password);
    5754          38 :                         GNUTLS_FIPS140_SET_STRICT_MODE();
    5755          38 :                         if (!NT_STATUS_IS_OK(status)) {
    5756           0 :                                 break;
    5757             :                         }
    5758             : 
    5759             : #ifdef DEBUG_PASSWORD
    5760          38 :                         dump_data(100, info->info26.password.data, 516);
    5761             : #endif
    5762             : 
    5763          38 :                         status = set_user_info_26(p->mem_ctx,
    5764             :                                                   rhost,
    5765             :                                                   &info->info26, pwd);
    5766          38 :                         break;
    5767           2 :                 case 31: {
    5768           2 :                         DATA_BLOB new_password = data_blob_null;
    5769           2 :                         const DATA_BLOB ciphertext = data_blob_const(
    5770           2 :                                 info->info31.password.cipher,
    5771           2 :                                 info->info31.password.cipher_len);
    5772           2 :                         DATA_BLOB iv = data_blob_const(
    5773           2 :                                 info->info31.password.salt,
    5774             :                                 sizeof(info->info31.password.salt));
    5775             : 
    5776           2 :                         status = session_extract_session_key(session_info,
    5777             :                                                              &session_key,
    5778             :                                                              KEY_USE_16BYTES);
    5779           2 :                         if (!NT_STATUS_IS_OK(status)) {
    5780           0 :                                 break;
    5781             :                         }
    5782             : 
    5783           0 :                         status =
    5784           2 :                                 samba_gnutls_aead_aes_256_cbc_hmac_sha512_decrypt(
    5785             :                                         p->mem_ctx,
    5786             :                                         &ciphertext,
    5787             :                                         &session_key,
    5788             :                                         &samr_aes256_enc_key_salt,
    5789             :                                         &samr_aes256_mac_key_salt,
    5790             :                                         &iv,
    5791           2 :                                         info->info31.password.auth_data,
    5792             :                                         &new_password);
    5793           2 :                         if (!NT_STATUS_IS_OK(status)) {
    5794           1 :                                 DBG_ERR("samba_gnutls_aead_aes_256_cbc_hmac_"
    5795             :                                         "sha512_decrypt "
    5796             :                                         "failed with %s\n",
    5797             :                                         nt_errstr(status));
    5798           1 :                                 status = NT_STATUS_WRONG_PASSWORD;
    5799           1 :                                 break;
    5800             :                         }
    5801             : 
    5802           1 :                         status = set_user_info_31(p->mem_ctx,
    5803             :                                                   rhost,
    5804             :                                                   &new_password,
    5805           1 :                                                   info->info31.password_expired,
    5806             :                                                   pwd);
    5807           1 :                         data_blob_clear(&new_password);
    5808             : 
    5809           1 :                         break;
    5810             :                 }
    5811           6 :                 case 32: {
    5812           6 :                         DATA_BLOB new_password = data_blob_null;
    5813           6 :                         const DATA_BLOB ciphertext = data_blob_const(
    5814           6 :                                 info->info32.password.cipher,
    5815           6 :                                 info->info32.password.cipher_len);
    5816           6 :                         DATA_BLOB iv = data_blob_const(
    5817           6 :                                 info->info32.password.salt,
    5818             :                                 sizeof(info->info32.password.salt));
    5819             : 
    5820           6 :                         status = session_extract_session_key(session_info,
    5821             :                                                              &session_key,
    5822             :                                                              KEY_USE_16BYTES);
    5823           6 :                         if (!NT_STATUS_IS_OK(status)) {
    5824           0 :                                 break;
    5825             :                         }
    5826             : 
    5827           0 :                         status =
    5828           6 :                                 samba_gnutls_aead_aes_256_cbc_hmac_sha512_decrypt(
    5829             :                                         p->mem_ctx,
    5830             :                                         &ciphertext,
    5831             :                                         &session_key,
    5832             :                                         &samr_aes256_enc_key_salt,
    5833             :                                         &samr_aes256_mac_key_salt,
    5834             :                                         &iv,
    5835           6 :                                         info->info32.password.auth_data,
    5836             :                                         &new_password);
    5837           6 :                         if (!NT_STATUS_IS_OK(status)) {
    5838           3 :                                 status = NT_STATUS_WRONG_PASSWORD;
    5839           3 :                                 break;
    5840             :                         }
    5841             : 
    5842           3 :                         status = set_user_info_32(p->mem_ctx,
    5843             :                                                   rhost,
    5844             :                                                   &new_password,
    5845             :                                                   &info->info32,
    5846             :                                                   pwd);
    5847           3 :                         data_blob_clear_free(&new_password);
    5848             : 
    5849           3 :                         break;
    5850             :                 }
    5851           0 :                 default:
    5852           0 :                         status = NT_STATUS_INVALID_INFO_CLASS;
    5853             :         }
    5854             : 
    5855         603 :         TALLOC_FREE(pwd);
    5856             : 
    5857         603 :         unbecome_root();
    5858             : 
    5859             :         /* ================ END Privilege BLOCK ================ */
    5860             : 
    5861         603 :         if (NT_STATUS_IS_OK(status)) {
    5862         559 :                 force_flush_samr_cache(&uinfo->sid);
    5863             :         }
    5864             : 
    5865         603 :         return status;
    5866             : }
    5867             : 
    5868             : /*******************************************************************
    5869             :  _samr_SetUserInfo2
    5870             :  ********************************************************************/
    5871             : 
    5872         156 : NTSTATUS _samr_SetUserInfo2(struct pipes_struct *p,
    5873             :                             struct samr_SetUserInfo2 *r)
    5874             : {
    5875           0 :         struct samr_SetUserInfo q;
    5876             : 
    5877         156 :         q.in.user_handle        = r->in.user_handle;
    5878         156 :         q.in.level              = r->in.level;
    5879         156 :         q.in.info               = r->in.info;
    5880             : 
    5881         156 :         return _samr_SetUserInfo(p, &q);
    5882             : }
    5883             : 
    5884             : /*********************************************************************
    5885             :  _samr_GetAliasMembership
    5886             : *********************************************************************/
    5887             : 
    5888        3862 : NTSTATUS _samr_GetAliasMembership(struct pipes_struct *p,
    5889             :                                   struct samr_GetAliasMembership *r)
    5890             : {
    5891           0 :         size_t num_alias_rids;
    5892           0 :         uint32_t *alias_rids;
    5893           0 :         struct samr_info *dinfo;
    5894           0 :         size_t i;
    5895             : 
    5896           0 :         NTSTATUS status;
    5897             : 
    5898           0 :         struct dom_sid *members;
    5899             : 
    5900        3862 :         DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
    5901             : 
    5902        3862 :         dinfo = samr_policy_handle_find(p,
    5903        3862 :                                         r->in.domain_handle,
    5904             :                                         SAMR_HANDLE_DOMAIN,
    5905             :                                         SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
    5906             :                                         | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
    5907             :                                         NULL,
    5908             :                                         &status);
    5909        3862 :         if (!NT_STATUS_IS_OK(status)) {
    5910           0 :                 return status;
    5911             :         }
    5912             : 
    5913        3862 :         if (!sid_check_is_our_sam(&dinfo->sid) &&
    5914        1792 :             !sid_check_is_builtin(&dinfo->sid))
    5915           0 :                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
    5916             : 
    5917        3862 :         if (r->in.sids->num_sids) {
    5918        3560 :                 members = talloc_array(p->mem_ctx, struct dom_sid, r->in.sids->num_sids);
    5919             : 
    5920        3560 :                 if (members == NULL)
    5921           0 :                         return NT_STATUS_NO_MEMORY;
    5922             :         } else {
    5923         302 :                 members = NULL;
    5924             :         }
    5925             : 
    5926       11216 :         for (i=0; i<r->in.sids->num_sids; i++)
    5927        7354 :                 sid_copy(&members[i], r->in.sids->sids[i].sid);
    5928             : 
    5929        3862 :         alias_rids = NULL;
    5930        3862 :         num_alias_rids = 0;
    5931             : 
    5932        3862 :         become_root();
    5933        3862 :         status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
    5934        3862 :                                             r->in.sids->num_sids,
    5935             :                                             &alias_rids, &num_alias_rids);
    5936        3862 :         unbecome_root();
    5937             : 
    5938        3862 :         if (!NT_STATUS_IS_OK(status)) {
    5939           0 :                 return status;
    5940             :         }
    5941             : 
    5942        3862 :         r->out.rids->count = num_alias_rids;
    5943        3862 :         r->out.rids->ids = alias_rids;
    5944             : 
    5945        3862 :         if (r->out.rids->ids == NULL) {
    5946             :                 /* Windows domain clients don't accept a NULL ptr here */
    5947         499 :                 r->out.rids->ids = talloc_zero(p->mem_ctx, uint32_t);
    5948             :         }
    5949        3862 :         if (r->out.rids->ids == NULL) {
    5950           0 :                 return NT_STATUS_NO_MEMORY;
    5951             :         }
    5952             : 
    5953        3862 :         return NT_STATUS_OK;
    5954             : }
    5955             : 
    5956             : /*********************************************************************
    5957             :  _samr_GetMembersInAlias
    5958             : *********************************************************************/
    5959             : 
    5960         618 : NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p,
    5961             :                                  struct samr_GetMembersInAlias *r)
    5962             : {
    5963           0 :         struct samr_info *ainfo;
    5964           0 :         NTSTATUS status;
    5965           0 :         size_t i;
    5966         618 :         size_t num_sids = 0;
    5967         618 :         struct lsa_SidPtr *sids = NULL;
    5968         618 :         struct dom_sid *pdb_sids = NULL;
    5969           0 :         struct dom_sid_buf buf;
    5970             : 
    5971         618 :         ainfo = samr_policy_handle_find(p,
    5972         618 :                                         r->in.alias_handle,
    5973             :                                         SAMR_HANDLE_ALIAS,
    5974             :                                         SAMR_ALIAS_ACCESS_GET_MEMBERS,
    5975             :                                         NULL,
    5976             :                                         &status);
    5977         618 :         if (!NT_STATUS_IS_OK(status)) {
    5978           0 :                 return status;
    5979             :         }
    5980             : 
    5981         618 :         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
    5982             : 
    5983         618 :         become_root();
    5984         618 :         status = pdb_enum_aliasmem(&ainfo->sid, talloc_tos(), &pdb_sids,
    5985             :                                    &num_sids);
    5986         618 :         unbecome_root();
    5987             : 
    5988         618 :         if (!NT_STATUS_IS_OK(status)) {
    5989           0 :                 return status;
    5990             :         }
    5991             : 
    5992         618 :         if (num_sids) {
    5993          17 :                 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr, num_sids);
    5994          17 :                 if (sids == NULL) {
    5995           0 :                         TALLOC_FREE(pdb_sids);
    5996           0 :                         return NT_STATUS_NO_MEMORY;
    5997             :                 }
    5998             :         }
    5999             : 
    6000         648 :         for (i = 0; i < num_sids; i++) {
    6001          30 :                 sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]);
    6002          30 :                 if (!sids[i].sid) {
    6003           0 :                         TALLOC_FREE(pdb_sids);
    6004           0 :                         return NT_STATUS_NO_MEMORY;
    6005             :                 }
    6006             :         }
    6007             : 
    6008         618 :         r->out.sids->num_sids = num_sids;
    6009         618 :         r->out.sids->sids = sids;
    6010             : 
    6011         618 :         TALLOC_FREE(pdb_sids);
    6012             : 
    6013         618 :         return NT_STATUS_OK;
    6014             : }
    6015             : 
    6016             : /*********************************************************************
    6017             :  _samr_QueryGroupMember
    6018             : *********************************************************************/
    6019             : 
    6020         311 : NTSTATUS _samr_QueryGroupMember(struct pipes_struct *p,
    6021             :                                 struct samr_QueryGroupMember *r)
    6022             : {
    6023           0 :         struct samr_info *ginfo;
    6024           0 :         size_t i, num_members;
    6025             : 
    6026         311 :         uint32_t *rid=NULL;
    6027         311 :         uint32_t *attr=NULL;
    6028             : 
    6029           0 :         NTSTATUS status;
    6030         311 :         struct samr_RidAttrArray *rids = NULL;
    6031           0 :         struct dom_sid_buf buf;
    6032             : 
    6033         311 :         ginfo = samr_policy_handle_find(p,
    6034         311 :                                         r->in.group_handle,
    6035             :                                         SAMR_HANDLE_GROUP,
    6036             :                                         SAMR_GROUP_ACCESS_GET_MEMBERS,
    6037             :                                         NULL,
    6038             :                                         &status);
    6039         311 :         if (!NT_STATUS_IS_OK(status)) {
    6040           0 :                 return status;
    6041             :         }
    6042             : 
    6043         311 :         rids = talloc_zero(p->mem_ctx, struct samr_RidAttrArray);
    6044         311 :         if (!rids) {
    6045           0 :                 return NT_STATUS_NO_MEMORY;
    6046             :         }
    6047             : 
    6048         311 :         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
    6049             : 
    6050         311 :         if (!sid_check_is_in_our_sam(&ginfo->sid)) {
    6051           0 :                 DEBUG(3, ("sid %s is not in our domain\n",
    6052             :                           dom_sid_str_buf(&ginfo->sid, &buf)));
    6053           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    6054             :         }
    6055             : 
    6056         311 :         DEBUG(10, ("lookup on Domain SID\n"));
    6057             : 
    6058         311 :         become_root();
    6059         311 :         status = pdb_enum_group_members(p->mem_ctx, &ginfo->sid,
    6060             :                                         &rid, &num_members);
    6061         311 :         unbecome_root();
    6062             : 
    6063         311 :         if (!NT_STATUS_IS_OK(status))
    6064           0 :                 return status;
    6065             : 
    6066         311 :         if (num_members) {
    6067           7 :                 attr=talloc_zero_array(p->mem_ctx, uint32_t, num_members);
    6068           7 :                 if (attr == NULL) {
    6069           0 :                         return NT_STATUS_NO_MEMORY;
    6070             :                 }
    6071             :         } else {
    6072         304 :                 attr = NULL;
    6073             :         }
    6074             : 
    6075         333 :         for (i=0; i<num_members; i++) {
    6076          22 :                 attr[i] = SE_GROUP_DEFAULT_FLAGS;
    6077             :         }
    6078             : 
    6079         311 :         rids->count = num_members;
    6080         311 :         rids->attributes = attr;
    6081         311 :         rids->rids = rid;
    6082             : 
    6083         311 :         *r->out.rids = rids;
    6084             : 
    6085         311 :         return NT_STATUS_OK;
    6086             : }
    6087             : 
    6088             : /*********************************************************************
    6089             :  _samr_AddAliasMember
    6090             : *********************************************************************/
    6091             : 
    6092           1 : NTSTATUS _samr_AddAliasMember(struct pipes_struct *p,
    6093             :                               struct samr_AddAliasMember *r)
    6094             : {
    6095           0 :         struct samr_info *ainfo;
    6096           0 :         struct dom_sid_buf buf;
    6097           0 :         NTSTATUS status;
    6098             : 
    6099           1 :         ainfo = samr_policy_handle_find(p,
    6100           1 :                                         r->in.alias_handle,
    6101             :                                         SAMR_HANDLE_ALIAS,
    6102             :                                         SAMR_ALIAS_ACCESS_ADD_MEMBER,
    6103             :                                         NULL,
    6104             :                                         &status);
    6105           1 :         if (!NT_STATUS_IS_OK(status)) {
    6106           0 :                 return status;
    6107             :         }
    6108             : 
    6109           1 :         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
    6110             : 
    6111             :         /******** BEGIN SeAddUsers BLOCK *********/
    6112             : 
    6113           1 :         become_root();
    6114           1 :         status = pdb_add_aliasmem(&ainfo->sid, r->in.sid);
    6115           1 :         unbecome_root();
    6116             : 
    6117             :         /******** END SeAddUsers BLOCK *********/
    6118             : 
    6119           1 :         if (NT_STATUS_IS_OK(status)) {
    6120           1 :                 force_flush_samr_cache(&ainfo->sid);
    6121             :         }
    6122             : 
    6123           1 :         return status;
    6124             : }
    6125             : 
    6126             : /*********************************************************************
    6127             :  _samr_DeleteAliasMember
    6128             : *********************************************************************/
    6129             : 
    6130           1 : NTSTATUS _samr_DeleteAliasMember(struct pipes_struct *p,
    6131             :                                  struct samr_DeleteAliasMember *r)
    6132             : {
    6133           0 :         struct samr_info *ainfo;
    6134           0 :         struct dom_sid_buf buf;
    6135           0 :         NTSTATUS status;
    6136             : 
    6137           1 :         ainfo = samr_policy_handle_find(p,
    6138           1 :                                         r->in.alias_handle,
    6139             :                                         SAMR_HANDLE_ALIAS,
    6140             :                                         SAMR_ALIAS_ACCESS_REMOVE_MEMBER,
    6141             :                                         NULL,
    6142             :                                         &status);
    6143           1 :         if (!NT_STATUS_IS_OK(status)) {
    6144           0 :                 return status;
    6145             :         }
    6146             : 
    6147           1 :         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
    6148             :                    dom_sid_str_buf(&ainfo->sid, &buf)));
    6149             : 
    6150             :         /******** BEGIN SeAddUsers BLOCK *********/
    6151             : 
    6152           1 :         become_root();
    6153           1 :         status = pdb_del_aliasmem(&ainfo->sid, r->in.sid);
    6154           1 :         unbecome_root();
    6155             : 
    6156             :         /******** END SeAddUsers BLOCK *********/
    6157             : 
    6158           1 :         if (NT_STATUS_IS_OK(status)) {
    6159           1 :                 force_flush_samr_cache(&ainfo->sid);
    6160             :         }
    6161             : 
    6162           1 :         return status;
    6163             : }
    6164             : 
    6165             : /*********************************************************************
    6166             :  _samr_AddGroupMember
    6167             : *********************************************************************/
    6168             : 
    6169           3 : NTSTATUS _samr_AddGroupMember(struct pipes_struct *p,
    6170             :                               struct samr_AddGroupMember *r)
    6171             : {
    6172           0 :         struct samr_info *ginfo;
    6173           0 :         struct dom_sid_buf buf;
    6174           0 :         NTSTATUS status;
    6175           0 :         uint32_t group_rid;
    6176             : 
    6177           3 :         ginfo = samr_policy_handle_find(p,
    6178           3 :                                         r->in.group_handle,
    6179             :                                         SAMR_HANDLE_GROUP,
    6180             :                                         SAMR_GROUP_ACCESS_ADD_MEMBER,
    6181             :                                         NULL,
    6182             :                                         &status);
    6183           3 :         if (!NT_STATUS_IS_OK(status)) {
    6184           0 :                 return status;
    6185             :         }
    6186             : 
    6187           3 :         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
    6188             : 
    6189           3 :         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
    6190             :                                 &group_rid)) {
    6191           0 :                 return NT_STATUS_INVALID_HANDLE;
    6192             :         }
    6193             : 
    6194             :         /******** BEGIN SeAddUsers BLOCK *********/
    6195             : 
    6196           3 :         become_root();
    6197           3 :         status = pdb_add_groupmem(p->mem_ctx, group_rid, r->in.rid);
    6198           3 :         unbecome_root();
    6199             : 
    6200             :         /******** END SeAddUsers BLOCK *********/
    6201             : 
    6202           3 :         force_flush_samr_cache(&ginfo->sid);
    6203             : 
    6204           3 :         return status;
    6205             : }
    6206             : 
    6207             : /*********************************************************************
    6208             :  _samr_DeleteGroupMember
    6209             : *********************************************************************/
    6210             : 
    6211           2 : NTSTATUS _samr_DeleteGroupMember(struct pipes_struct *p,
    6212             :                                  struct samr_DeleteGroupMember *r)
    6213             : 
    6214             : {
    6215           0 :         struct samr_info *ginfo;
    6216           0 :         NTSTATUS status;
    6217           0 :         uint32_t group_rid;
    6218             : 
    6219             :         /*
    6220             :          * delete the group member named r->in.rid
    6221             :          * who is a member of the sid associated with the handle
    6222             :          * the rid is a user's rid as the group is a domain group.
    6223             :          */
    6224             : 
    6225           2 :         ginfo = samr_policy_handle_find(p,
    6226           2 :                                         r->in.group_handle,
    6227             :                                         SAMR_HANDLE_GROUP,
    6228             :                                         SAMR_GROUP_ACCESS_REMOVE_MEMBER,
    6229             :                                         NULL,
    6230             :                                         &status);
    6231           2 :         if (!NT_STATUS_IS_OK(status)) {
    6232           0 :                 return status;
    6233             :         }
    6234             : 
    6235           2 :         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
    6236             :                                 &group_rid)) {
    6237           0 :                 return NT_STATUS_INVALID_HANDLE;
    6238             :         }
    6239             : 
    6240             :         /******** BEGIN SeAddUsers BLOCK *********/
    6241             : 
    6242           2 :         become_root();
    6243           2 :         status = pdb_del_groupmem(p->mem_ctx, group_rid, r->in.rid);
    6244           2 :         unbecome_root();
    6245             : 
    6246             :         /******** END SeAddUsers BLOCK *********/
    6247             : 
    6248           2 :         force_flush_samr_cache(&ginfo->sid);
    6249             : 
    6250           2 :         return status;
    6251             : }
    6252             : 
    6253             : /*********************************************************************
    6254             :  _samr_DeleteUser
    6255             : *********************************************************************/
    6256             : 
    6257          74 : NTSTATUS _samr_DeleteUser(struct pipes_struct *p,
    6258             :                           struct samr_DeleteUser *r)
    6259             : {
    6260           0 :         struct samr_info *uinfo;
    6261           0 :         NTSTATUS status;
    6262          74 :         struct samu *sam_pass=NULL;
    6263           0 :         bool ret;
    6264             : 
    6265          74 :         DEBUG(5, ("_samr_DeleteUser: %d\n", __LINE__));
    6266             : 
    6267          74 :         uinfo = samr_policy_handle_find(p,
    6268          74 :                                         r->in.user_handle,
    6269             :                                         SAMR_HANDLE_USER,
    6270             :                                         SEC_STD_DELETE,
    6271             :                                         NULL,
    6272             :                                         &status);
    6273          74 :         if (!NT_STATUS_IS_OK(status)) {
    6274           0 :                 return status;
    6275             :         }
    6276             : 
    6277          74 :         if (!sid_check_is_in_our_sam(&uinfo->sid))
    6278           0 :                 return NT_STATUS_CANNOT_DELETE;
    6279             : 
    6280             :         /* check if the user exists before trying to delete */
    6281          74 :         if ( !(sam_pass = samu_new( NULL )) ) {
    6282           0 :                 return NT_STATUS_NO_MEMORY;
    6283             :         }
    6284             : 
    6285          74 :         become_root();
    6286          74 :         ret = pdb_getsampwsid(sam_pass, &uinfo->sid);
    6287          74 :         unbecome_root();
    6288             : 
    6289          74 :         if(!ret) {
    6290           0 :                 struct dom_sid_buf buf;
    6291           0 :                 DEBUG(5,("_samr_DeleteUser: User %s doesn't exist.\n",
    6292             :                          dom_sid_str_buf(&uinfo->sid, &buf)));
    6293           0 :                 TALLOC_FREE(sam_pass);
    6294           0 :                 return NT_STATUS_NO_SUCH_USER;
    6295             :         }
    6296             : 
    6297             :         /******** BEGIN SeAddUsers BLOCK *********/
    6298             : 
    6299          74 :         become_root();
    6300          74 :         status = pdb_delete_user(p->mem_ctx, sam_pass);
    6301          74 :         unbecome_root();
    6302             : 
    6303             :         /******** END SeAddUsers BLOCK *********/
    6304             : 
    6305          74 :         if ( !NT_STATUS_IS_OK(status) ) {
    6306           0 :                 DEBUG(5,("_samr_DeleteUser: Failed to delete entry for "
    6307             :                          "user %s: %s.\n", pdb_get_username(sam_pass),
    6308             :                          nt_errstr(status)));
    6309           0 :                 TALLOC_FREE(sam_pass);
    6310           0 :                 return status;
    6311             :         }
    6312             : 
    6313             : 
    6314          74 :         TALLOC_FREE(sam_pass);
    6315             : 
    6316          74 :         force_flush_samr_cache(&uinfo->sid);
    6317             : 
    6318          74 :         if (!close_policy_hnd(p, r->in.user_handle))
    6319           0 :                 return NT_STATUS_OBJECT_NAME_INVALID;
    6320             : 
    6321          74 :         ZERO_STRUCTP(r->out.user_handle);
    6322             : 
    6323          74 :         return NT_STATUS_OK;
    6324             : }
    6325             : 
    6326             : /*********************************************************************
    6327             :  _samr_DeleteDomainGroup
    6328             : *********************************************************************/
    6329             : 
    6330           1 : NTSTATUS _samr_DeleteDomainGroup(struct pipes_struct *p,
    6331             :                                  struct samr_DeleteDomainGroup *r)
    6332             : {
    6333           0 :         struct samr_info *ginfo;
    6334           0 :         struct dom_sid_buf buf;
    6335           0 :         NTSTATUS status;
    6336           0 :         uint32_t group_rid;
    6337             : 
    6338           1 :         DEBUG(5, ("samr_DeleteDomainGroup: %d\n", __LINE__));
    6339             : 
    6340           1 :         ginfo = samr_policy_handle_find(p,
    6341           1 :                                         r->in.group_handle,
    6342             :                                         SAMR_HANDLE_GROUP,
    6343             :                                         SEC_STD_DELETE,
    6344             :                                         NULL,
    6345             :                                         &status);
    6346           1 :         if (!NT_STATUS_IS_OK(status)) {
    6347           0 :                 return status;
    6348             :         }
    6349             : 
    6350           1 :         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ginfo->sid, &buf)));
    6351             : 
    6352           1 :         if (!sid_peek_check_rid(get_global_sam_sid(), &ginfo->sid,
    6353             :                                 &group_rid)) {
    6354           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    6355             :         }
    6356             : 
    6357             :         /******** BEGIN SeAddUsers BLOCK *********/
    6358             : 
    6359           1 :         become_root();
    6360           1 :         status = pdb_delete_dom_group(p->mem_ctx, group_rid);
    6361           1 :         unbecome_root();
    6362             : 
    6363             :         /******** END SeAddUsers BLOCK *********/
    6364             : 
    6365           1 :         if ( !NT_STATUS_IS_OK(status) ) {
    6366           0 :                 DEBUG(5,("_samr_DeleteDomainGroup: Failed to delete mapping "
    6367             :                          "entry for group %s: %s\n",
    6368             :                          dom_sid_str_buf(&ginfo->sid, &buf),
    6369             :                          nt_errstr(status)));
    6370           0 :                 return status;
    6371             :         }
    6372             : 
    6373           1 :         force_flush_samr_cache(&ginfo->sid);
    6374             : 
    6375           1 :         if (!close_policy_hnd(p, r->in.group_handle))
    6376           0 :                 return NT_STATUS_OBJECT_NAME_INVALID;
    6377             : 
    6378           1 :         return NT_STATUS_OK;
    6379             : }
    6380             : 
    6381             : /*********************************************************************
    6382             :  _samr_DeleteDomAlias
    6383             : *********************************************************************/
    6384             : 
    6385           1 : NTSTATUS _samr_DeleteDomAlias(struct pipes_struct *p,
    6386             :                               struct samr_DeleteDomAlias *r)
    6387             : {
    6388           0 :         struct samr_info *ainfo;
    6389           0 :         struct dom_sid_buf buf;
    6390           0 :         NTSTATUS status;
    6391             : 
    6392           1 :         DEBUG(5, ("_samr_DeleteDomAlias: %d\n", __LINE__));
    6393             : 
    6394           1 :         ainfo = samr_policy_handle_find(p,
    6395           1 :                                         r->in.alias_handle,
    6396             :                                         SAMR_HANDLE_ALIAS,
    6397             :                                         SEC_STD_DELETE,
    6398             :                                         NULL,
    6399             :                                         &status);
    6400           1 :         if (!NT_STATUS_IS_OK(status)) {
    6401           0 :                 return status;
    6402             :         }
    6403             : 
    6404           1 :         DEBUG(10, ("sid is %s\n", dom_sid_str_buf(&ainfo->sid, &buf)));
    6405             : 
    6406             :         /* Don't let Windows delete builtin groups */
    6407             : 
    6408           1 :         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
    6409           0 :                 return NT_STATUS_SPECIAL_ACCOUNT;
    6410             :         }
    6411             : 
    6412           1 :         if (!sid_check_is_in_our_sam(&ainfo->sid))
    6413           0 :                 return NT_STATUS_NO_SUCH_ALIAS;
    6414             : 
    6415           1 :         DEBUG(10, ("lookup on Local SID\n"));
    6416             : 
    6417             :         /******** BEGIN SeAddUsers BLOCK *********/
    6418             : 
    6419           1 :         become_root();
    6420             :         /* Have passdb delete the alias */
    6421           1 :         status = pdb_delete_alias(&ainfo->sid);
    6422           1 :         unbecome_root();
    6423             : 
    6424             :         /******** END SeAddUsers BLOCK *********/
    6425             : 
    6426           1 :         if ( !NT_STATUS_IS_OK(status))
    6427           0 :                 return status;
    6428             : 
    6429           1 :         force_flush_samr_cache(&ainfo->sid);
    6430             : 
    6431           1 :         if (!close_policy_hnd(p, r->in.alias_handle))
    6432           0 :                 return NT_STATUS_OBJECT_NAME_INVALID;
    6433             : 
    6434           1 :         return NT_STATUS_OK;
    6435             : }
    6436             : 
    6437             : /*********************************************************************
    6438             :  _samr_CreateDomainGroup
    6439             : *********************************************************************/
    6440             : 
    6441         602 : NTSTATUS _samr_CreateDomainGroup(struct pipes_struct *p,
    6442             :                                  struct samr_CreateDomainGroup *r)
    6443             : 
    6444             : {
    6445           0 :         NTSTATUS status;
    6446           0 :         const char *name;
    6447           0 :         struct samr_info *dinfo;
    6448           0 :         struct dom_sid sid;
    6449             : 
    6450         602 :         dinfo = samr_policy_handle_find(p,
    6451         602 :                                         r->in.domain_handle,
    6452             :                                         SAMR_HANDLE_DOMAIN,
    6453             :                                         SAMR_DOMAIN_ACCESS_CREATE_GROUP,
    6454             :                                         NULL,
    6455             :                                         &status);
    6456         602 :         if (!NT_STATUS_IS_OK(status)) {
    6457           0 :                 return status;
    6458             :         }
    6459             : 
    6460         602 :         if (!sid_check_is_our_sam(&dinfo->sid)) {
    6461         301 :                 return NT_STATUS_ACCESS_DENIED;
    6462             :         }
    6463             : 
    6464         301 :         name = r->in.name->string;
    6465         301 :         if (name == NULL) {
    6466           0 :                 return NT_STATUS_NO_MEMORY;
    6467             :         }
    6468             : 
    6469         301 :         status = can_create(p->mem_ctx, name);
    6470         301 :         if (!NT_STATUS_IS_OK(status)) {
    6471           0 :                 return status;
    6472             :         }
    6473             : 
    6474             :         /******** BEGIN SeAddUsers BLOCK *********/
    6475             : 
    6476         301 :         become_root();
    6477             :         /* check that we successfully create the UNIX group */
    6478         301 :         status = pdb_create_dom_group(p->mem_ctx, name, r->out.rid);
    6479         301 :         unbecome_root();
    6480             : 
    6481             :         /******** END SeAddUsers BLOCK *********/
    6482             : 
    6483             :         /* check if we should bail out here */
    6484             : 
    6485         301 :         if ( !NT_STATUS_IS_OK(status) )
    6486           0 :                 return status;
    6487             : 
    6488         301 :         sid_compose(&sid, &dinfo->sid, *r->out.rid);
    6489             : 
    6490         301 :         status = create_samr_policy_handle(p->mem_ctx,
    6491             :                                            p,
    6492             :                                            SAMR_HANDLE_GROUP,
    6493             :                                            GENERIC_RIGHTS_GROUP_ALL_ACCESS,
    6494             :                                            &sid,
    6495             :                                            NULL,
    6496             :                                            r->out.group_handle);
    6497         301 :         if (!NT_STATUS_IS_OK(status)) {
    6498           0 :                 return status;
    6499             :         }
    6500             : 
    6501         301 :         force_flush_samr_cache(&dinfo->sid);
    6502             : 
    6503         301 :         return NT_STATUS_OK;
    6504             : }
    6505             : 
    6506             : /*********************************************************************
    6507             :  _samr_CreateDomAlias
    6508             : *********************************************************************/
    6509             : 
    6510         602 : NTSTATUS _samr_CreateDomAlias(struct pipes_struct *p,
    6511             :                               struct samr_CreateDomAlias *r)
    6512             : {
    6513           0 :         struct dom_sid info_sid;
    6514         602 :         const char *name = NULL;
    6515           0 :         struct samr_info *dinfo;
    6516           0 :         gid_t gid;
    6517           0 :         NTSTATUS result;
    6518             : 
    6519         602 :         dinfo = samr_policy_handle_find(p,
    6520         602 :                                         r->in.domain_handle,
    6521             :                                         SAMR_HANDLE_DOMAIN,
    6522             :                                         SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
    6523             :                                         NULL,
    6524             :                                         &result);
    6525         602 :         if (!NT_STATUS_IS_OK(result)) {
    6526           0 :                 return result;
    6527             :         }
    6528             : 
    6529         602 :         if (!sid_check_is_our_sam(&dinfo->sid)) {
    6530         301 :                 return NT_STATUS_ACCESS_DENIED;
    6531             :         }
    6532             : 
    6533         301 :         name = r->in.alias_name->string;
    6534             : 
    6535         301 :         result = can_create(p->mem_ctx, name);
    6536         301 :         if (!NT_STATUS_IS_OK(result)) {
    6537           0 :                 return result;
    6538             :         }
    6539             : 
    6540             :         /******** BEGIN SeAddUsers BLOCK *********/
    6541             : 
    6542         301 :         become_root();
    6543             :         /* Have passdb create the alias */
    6544         301 :         result = pdb_create_alias(name, r->out.rid);
    6545         301 :         unbecome_root();
    6546             : 
    6547             :         /******** END SeAddUsers BLOCK *********/
    6548             : 
    6549         301 :         if (!NT_STATUS_IS_OK(result)) {
    6550           0 :                 DEBUG(10, ("pdb_create_alias failed: %s\n",
    6551             :                            nt_errstr(result)));
    6552           0 :                 return result;
    6553             :         }
    6554             : 
    6555         301 :         sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
    6556             : 
    6557         301 :         if (!sid_to_gid(&info_sid, &gid)) {
    6558           0 :                 DEBUG(10, ("Could not find alias just created\n"));
    6559           0 :                 return NT_STATUS_ACCESS_DENIED;
    6560             :         }
    6561             : 
    6562             :         /* check if the group has been successfully created */
    6563         301 :         if ( getgrgid(gid) == NULL ) {
    6564           0 :                 DEBUG(1, ("getgrgid(%u) of just created alias failed\n",
    6565             :                            (unsigned int)gid));
    6566           0 :                 return NT_STATUS_ACCESS_DENIED;
    6567             :         }
    6568             : 
    6569         301 :         result = create_samr_policy_handle(p->mem_ctx,
    6570             :                                            p,
    6571             :                                            SAMR_HANDLE_ALIAS,
    6572             :                                            GENERIC_RIGHTS_ALIAS_ALL_ACCESS,
    6573             :                                            &info_sid,
    6574             :                                            NULL,
    6575             :                                            r->out.alias_handle);
    6576         301 :         if (!NT_STATUS_IS_OK(result)) {
    6577           0 :                 return result;
    6578             :         }
    6579             : 
    6580         301 :         force_flush_samr_cache(&info_sid);
    6581             : 
    6582         301 :         return NT_STATUS_OK;
    6583             : }
    6584             : 
    6585             : /*********************************************************************
    6586             :  _samr_QueryGroupInfo
    6587             : *********************************************************************/
    6588             : 
    6589          19 : NTSTATUS _samr_QueryGroupInfo(struct pipes_struct *p,
    6590             :                               struct samr_QueryGroupInfo *r)
    6591             : {
    6592           0 :         struct samr_info *ginfo;
    6593           0 :         NTSTATUS status;
    6594           0 :         GROUP_MAP *map;
    6595          19 :         union samr_GroupInfo *info = NULL;
    6596           0 :         bool ret;
    6597          19 :         uint32_t attributes = SE_GROUP_DEFAULT_FLAGS;
    6598          19 :         const char *group_name = NULL;
    6599          19 :         const char *group_description = NULL;
    6600             : 
    6601          19 :         ginfo = samr_policy_handle_find(p,
    6602          19 :                                         r->in.group_handle,
    6603             :                                         SAMR_HANDLE_GROUP,
    6604             :                                         SAMR_GROUP_ACCESS_LOOKUP_INFO,
    6605             :                                         NULL,
    6606             :                                         &status);
    6607          19 :         if (!NT_STATUS_IS_OK(status)) {
    6608           0 :                 return status;
    6609             :         }
    6610             : 
    6611          19 :         map = talloc_zero(p->mem_ctx, GROUP_MAP);
    6612          19 :         if (!map) {
    6613           0 :                 return NT_STATUS_NO_MEMORY;
    6614             :         }
    6615             : 
    6616          19 :         become_root();
    6617          19 :         ret = get_domain_group_from_sid(ginfo->sid, map);
    6618          19 :         unbecome_root();
    6619          19 :         if (!ret)
    6620           0 :                 return NT_STATUS_INVALID_HANDLE;
    6621             : 
    6622          19 :         group_name = talloc_move(r, &map->nt_name);
    6623          19 :         group_description = talloc_move(r, &map->comment);
    6624             : 
    6625          19 :         TALLOC_FREE(map);
    6626             : 
    6627          19 :         info = talloc_zero(p->mem_ctx, union samr_GroupInfo);
    6628          19 :         if (!info) {
    6629           0 :                 return NT_STATUS_NO_MEMORY;
    6630             :         }
    6631             : 
    6632          19 :         switch (r->in.level) {
    6633           4 :                 case 1: {
    6634           0 :                         uint32_t *members;
    6635           0 :                         size_t num_members;
    6636             : 
    6637           4 :                         become_root();
    6638           4 :                         status = pdb_enum_group_members(
    6639           4 :                                 p->mem_ctx, &ginfo->sid, &members,
    6640             :                                 &num_members);
    6641           4 :                         unbecome_root();
    6642             : 
    6643           4 :                         if (!NT_STATUS_IS_OK(status)) {
    6644           0 :                                 return status;
    6645             :                         }
    6646             : 
    6647           4 :                         info->all.name.string                = group_name;
    6648           4 :                         info->all.attributes         = attributes;
    6649           4 :                         info->all.num_members                = num_members;
    6650           4 :                         info->all.description.string = group_description;
    6651           4 :                         break;
    6652             :                 }
    6653           4 :                 case 2:
    6654           4 :                         info->name.string = group_name;
    6655           4 :                         break;
    6656           4 :                 case 3:
    6657           4 :                         info->attributes.attributes = attributes;
    6658           4 :                         break;
    6659           4 :                 case 4:
    6660           4 :                         info->description.string = group_description;
    6661           4 :                         break;
    6662           3 :                 case 5: {
    6663             :                         /*
    6664             :                         uint32_t *members;
    6665             :                         size_t num_members;
    6666             :                         */
    6667             : 
    6668             :                         /*
    6669             :                         become_root();
    6670             :                         status = pdb_enum_group_members(
    6671             :                                 p->mem_ctx, &ginfo->sid, &members,
    6672             :                                 &num_members);
    6673             :                         unbecome_root();
    6674             : 
    6675             :                         if (!NT_STATUS_IS_OK(status)) {
    6676             :                                 return status;
    6677             :                         }
    6678             :                         */
    6679           3 :                         info->all2.name.string               = group_name;
    6680           3 :                         info->all2.attributes                = attributes;
    6681           3 :                         info->all2.num_members               = 0; /* num_members - in w2k3 this is always 0 */
    6682           3 :                         info->all2.description.string        = group_description;
    6683             : 
    6684           3 :                         break;
    6685             :                 }
    6686           0 :                 default:
    6687           0 :                         return NT_STATUS_INVALID_INFO_CLASS;
    6688             :         }
    6689             : 
    6690          19 :         *r->out.info = info;
    6691             : 
    6692          19 :         return NT_STATUS_OK;
    6693             : }
    6694             : 
    6695             : /*********************************************************************
    6696             :  _samr_SetGroupInfo
    6697             : *********************************************************************/
    6698             : 
    6699           4 : NTSTATUS _samr_SetGroupInfo(struct pipes_struct *p,
    6700             :                             struct samr_SetGroupInfo *r)
    6701             : {
    6702           0 :         struct samr_info *ginfo;
    6703           0 :         GROUP_MAP *map;
    6704           0 :         NTSTATUS status;
    6705           0 :         bool ret;
    6706             : 
    6707           4 :         ginfo = samr_policy_handle_find(p,
    6708           4 :                                         r->in.group_handle,
    6709             :                                         SAMR_HANDLE_GROUP,
    6710             :                                         SAMR_GROUP_ACCESS_SET_INFO,
    6711             :                                         NULL,
    6712             :                                         &status);
    6713           4 :         if (!NT_STATUS_IS_OK(status)) {
    6714           0 :                 return status;
    6715             :         }
    6716             : 
    6717           4 :         map = talloc_zero(p->mem_ctx, GROUP_MAP);
    6718           4 :         if (!map) {
    6719           0 :                 return NT_STATUS_NO_MEMORY;
    6720             :         }
    6721             : 
    6722           4 :         become_root();
    6723           4 :         ret = get_domain_group_from_sid(ginfo->sid, map);
    6724           4 :         unbecome_root();
    6725           4 :         if (!ret)
    6726           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    6727             : 
    6728           4 :         switch (r->in.level) {
    6729           1 :                 case 2:
    6730           2 :                         map->nt_name = talloc_strdup(map,
    6731           1 :                                                      r->in.info->name.string);
    6732           1 :                         if (!map->nt_name) {
    6733           0 :                                 return NT_STATUS_NO_MEMORY;
    6734             :                         }
    6735           1 :                         break;
    6736           1 :                 case 3:
    6737           1 :                         break;
    6738           1 :                 case 4:
    6739           2 :                         map->comment = talloc_strdup(map,
    6740           1 :                                                 r->in.info->description.string);
    6741           1 :                         if (!map->comment) {
    6742           0 :                                 return NT_STATUS_NO_MEMORY;
    6743             :                         }
    6744           1 :                         break;
    6745           1 :                 default:
    6746           1 :                         return NT_STATUS_INVALID_INFO_CLASS;
    6747             :         }
    6748             : 
    6749             :         /******** BEGIN SeAddUsers BLOCK *********/
    6750             : 
    6751           3 :         become_root();
    6752           3 :         status = pdb_update_group_mapping_entry(map);
    6753           3 :         unbecome_root();
    6754             : 
    6755             :         /******** End SeAddUsers BLOCK *********/
    6756             : 
    6757           3 :         TALLOC_FREE(map);
    6758             : 
    6759           3 :         if (NT_STATUS_IS_OK(status)) {
    6760           3 :                 force_flush_samr_cache(&ginfo->sid);
    6761             :         }
    6762             : 
    6763           3 :         return status;
    6764             : }
    6765             : 
    6766             : /*********************************************************************
    6767             :  _samr_SetAliasInfo
    6768             : *********************************************************************/
    6769             : 
    6770           2 : NTSTATUS _samr_SetAliasInfo(struct pipes_struct *p,
    6771             :                             struct samr_SetAliasInfo *r)
    6772             : {
    6773           0 :         struct samr_info *ainfo;
    6774           0 :         struct acct_info *info;
    6775           0 :         NTSTATUS status;
    6776             : 
    6777           2 :         ainfo = samr_policy_handle_find(p,
    6778           2 :                                         r->in.alias_handle,
    6779             :                                         SAMR_HANDLE_ALIAS,
    6780             :                                         SAMR_ALIAS_ACCESS_SET_INFO,
    6781             :                                         NULL,
    6782             :                                         &status);
    6783           2 :         if (!NT_STATUS_IS_OK(status)) {
    6784           0 :                 return status;
    6785             :         }
    6786             : 
    6787           2 :         info = talloc_zero(p->mem_ctx, struct acct_info);
    6788           2 :         if (!info) {
    6789           0 :                 return NT_STATUS_NO_MEMORY;
    6790             :         }
    6791             : 
    6792             :         /* get the current group information */
    6793             : 
    6794           2 :         become_root();
    6795           2 :         status = pdb_get_aliasinfo(&ainfo->sid, info);
    6796           2 :         unbecome_root();
    6797             : 
    6798           2 :         if ( !NT_STATUS_IS_OK(status))
    6799           0 :                 return status;
    6800             : 
    6801           2 :         switch (r->in.level) {
    6802           1 :                 case ALIASINFONAME:
    6803             :                 {
    6804           0 :                         char *group_name;
    6805             : 
    6806             :                         /* We currently do not support renaming groups in the
    6807             :                            the BUILTIN domain.  Refer to util_builtin.c to understand
    6808             :                            why.  The eventually needs to be fixed to be like Windows
    6809             :                            where you can rename builtin groups, just not delete them */
    6810             : 
    6811           1 :                         if ( sid_check_is_in_builtin( &ainfo->sid ) ) {
    6812           0 :                                 return NT_STATUS_SPECIAL_ACCOUNT;
    6813             :                         }
    6814             : 
    6815             :                         /* There has to be a valid name (and it has to be different) */
    6816             : 
    6817           1 :                         if ( !r->in.info->name.string )
    6818           0 :                                 return NT_STATUS_INVALID_PARAMETER;
    6819             : 
    6820             :                         /* If the name is the same just reply "ok".  Yes this
    6821             :                            doesn't allow you to change the case of a group name. */
    6822             : 
    6823           1 :                         if (strequal(r->in.info->name.string, info->acct_name)) {
    6824           1 :                                 return NT_STATUS_OK;
    6825             :                         }
    6826             : 
    6827           0 :                         talloc_free(info->acct_name);
    6828           0 :                         info->acct_name = talloc_strdup(info, r->in.info->name.string);
    6829           0 :                         if (!info->acct_name) {
    6830           0 :                                 return NT_STATUS_NO_MEMORY;
    6831             :                         }
    6832             : 
    6833             :                         /* make sure the name doesn't already exist as a user
    6834             :                            or local group */
    6835             : 
    6836           0 :                         group_name = talloc_asprintf(p->mem_ctx,
    6837             :                                                      "%s\\%s",
    6838             :                                                      lp_netbios_name(),
    6839             :                                                      info->acct_name);
    6840           0 :                         if (group_name == NULL) {
    6841           0 :                                 return NT_STATUS_NO_MEMORY;
    6842             :                         }
    6843             : 
    6844           0 :                         status = can_create( p->mem_ctx, group_name );
    6845           0 :                         talloc_free(group_name);
    6846           0 :                         if ( !NT_STATUS_IS_OK( status ) )
    6847           0 :                                 return status;
    6848           0 :                         break;
    6849             :                 }
    6850           1 :                 case ALIASINFODESCRIPTION:
    6851           1 :                         TALLOC_FREE(info->acct_desc);
    6852           1 :                         if (r->in.info->description.string) {
    6853           1 :                                 info->acct_desc = talloc_strdup(info,
    6854           1 :                                                                 r->in.info->description.string);
    6855             :                         } else {
    6856           0 :                                 info->acct_desc = talloc_strdup(info, "");
    6857             :                         }
    6858           1 :                         if (!info->acct_desc) {
    6859           0 :                                 return NT_STATUS_NO_MEMORY;
    6860             :                         }
    6861           1 :                         break;
    6862           0 :                 default:
    6863           0 :                         return NT_STATUS_INVALID_INFO_CLASS;
    6864             :         }
    6865             : 
    6866             :         /******** BEGIN SeAddUsers BLOCK *********/
    6867             : 
    6868           1 :         become_root();
    6869           1 :         status = pdb_set_aliasinfo(&ainfo->sid, info);
    6870           1 :         unbecome_root();
    6871             : 
    6872             :         /******** End SeAddUsers BLOCK *********/
    6873             : 
    6874           1 :         if (NT_STATUS_IS_OK(status))
    6875           1 :                 force_flush_samr_cache(&ainfo->sid);
    6876             : 
    6877           1 :         return status;
    6878             : }
    6879             : 
    6880             : /****************************************************************
    6881             :  _samr_GetDomPwInfo
    6882             : ****************************************************************/
    6883             : 
    6884         347 : NTSTATUS _samr_GetDomPwInfo(struct pipes_struct *p,
    6885             :                             struct samr_GetDomPwInfo *r)
    6886             : {
    6887           0 :         const struct loadparm_substitution *lp_sub =
    6888         347 :                 loadparm_s3_global_substitution();
    6889         347 :         uint32_t min_password_length = 0;
    6890         347 :         uint32_t password_properties = 0;
    6891             : 
    6892             :         /* Perform access check.  Since this rpc does not require a
    6893             :            policy handle it will not be caught by the access checks on
    6894             :            SAMR_CONNECT or SAMR_CONNECT_ANON. */
    6895             : 
    6896         347 :         if (!pipe_access_check(p)) {
    6897           0 :                 DEBUG(3, ("access denied to _samr_GetDomPwInfo\n"));
    6898           0 :                 return NT_STATUS_ACCESS_DENIED;
    6899             :         }
    6900             : 
    6901         347 :         become_root();
    6902         347 :         pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
    6903             :                                &min_password_length);
    6904         347 :         pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
    6905             :                                &password_properties);
    6906         347 :         unbecome_root();
    6907             : 
    6908         347 :         if (lp_check_password_script(talloc_tos(), lp_sub) && *lp_check_password_script(talloc_tos(), lp_sub)) {
    6909           0 :                 password_properties |= DOMAIN_PASSWORD_COMPLEX;
    6910             :         }
    6911             : 
    6912         347 :         r->out.info->min_password_length = min_password_length;
    6913         347 :         r->out.info->password_properties = password_properties;
    6914             : 
    6915         347 :         return NT_STATUS_OK;
    6916             : }
    6917             : 
    6918             : /*********************************************************************
    6919             :  _samr_OpenGroup
    6920             : *********************************************************************/
    6921             : 
    6922         311 : NTSTATUS _samr_OpenGroup(struct pipes_struct *p,
    6923             :                          struct samr_OpenGroup *r)
    6924             : 
    6925             : {
    6926         311 :         struct dcesrv_call_state *dce_call = p->dce_call;
    6927           0 :         struct auth_session_info *session_info =
    6928         311 :                 dcesrv_call_session_info(dce_call);
    6929           0 :         struct dom_sid info_sid;
    6930           0 :         struct dom_sid_buf buf;
    6931           0 :         GROUP_MAP *map;
    6932           0 :         struct samr_info *dinfo;
    6933         311 :         struct security_descriptor         *psd = NULL;
    6934           0 :         uint32_t            acc_granted;
    6935         311 :         uint32_t            des_access = r->in.access_mask;
    6936           0 :         size_t            sd_size;
    6937           0 :         NTSTATUS          status;
    6938           0 :         bool ret;
    6939             : 
    6940         311 :         dinfo = samr_policy_handle_find(p,
    6941         311 :                                         r->in.domain_handle,
    6942             :                                         SAMR_HANDLE_DOMAIN,
    6943             :                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
    6944             :                                         NULL,
    6945             :                                         &status);
    6946         311 :         if (!NT_STATUS_IS_OK(status)) {
    6947           1 :                 return status;
    6948             :         }
    6949             : 
    6950             :         /*check if access can be granted as requested by client. */
    6951         310 :         map_max_allowed_access(session_info->security_token,
    6952         310 :                                session_info->unix_token,
    6953             :                                &des_access);
    6954             : 
    6955         310 :         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
    6956         310 :         se_map_generic(&des_access,&grp_generic_mapping);
    6957             : 
    6958         310 :         status = access_check_object(psd, session_info->security_token,
    6959             :                                      SEC_PRIV_ADD_USERS, SEC_PRIV_INVALID, GENERIC_RIGHTS_GROUP_ALL_ACCESS,
    6960             :                                      des_access, &acc_granted, "_samr_OpenGroup");
    6961             : 
    6962         310 :         if ( !NT_STATUS_IS_OK(status) )
    6963           0 :                 return status;
    6964             : 
    6965             :         /* this should not be hard-coded like this */
    6966             : 
    6967         310 :         if (!sid_check_is_our_sam(&dinfo->sid)) {
    6968           0 :                 return NT_STATUS_ACCESS_DENIED;
    6969             :         }
    6970             : 
    6971         310 :         sid_compose(&info_sid, &dinfo->sid, r->in.rid);
    6972             : 
    6973         310 :         DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
    6974             :                    dom_sid_str_buf(&info_sid, &buf)));
    6975             : 
    6976         310 :         map = talloc_zero(p->mem_ctx, GROUP_MAP);
    6977         310 :         if (!map) {
    6978           0 :                 return NT_STATUS_NO_MEMORY;
    6979             :         }
    6980             : 
    6981             :         /* check if that group really exists */
    6982         310 :         become_root();
    6983         310 :         ret = get_domain_group_from_sid(info_sid, map);
    6984         310 :         unbecome_root();
    6985         310 :         if (!ret)
    6986           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    6987             : 
    6988         310 :         TALLOC_FREE(map);
    6989             : 
    6990         310 :         status = create_samr_policy_handle(p->mem_ctx,
    6991             :                                            p,
    6992             :                                            SAMR_HANDLE_GROUP,
    6993             :                                            acc_granted,
    6994             :                                            &info_sid,
    6995             :                                            NULL,
    6996             :                                            r->out.group_handle);
    6997         310 :         if (!NT_STATUS_IS_OK(status)) {
    6998           0 :                 return status;
    6999             :         }
    7000             : 
    7001         310 :         return NT_STATUS_OK;
    7002             : }
    7003             : 
    7004             : /*********************************************************************
    7005             :  _samr_RemoveMemberFromForeignDomain
    7006             : *********************************************************************/
    7007             : 
    7008           3 : NTSTATUS _samr_RemoveMemberFromForeignDomain(struct pipes_struct *p,
    7009             :                                              struct samr_RemoveMemberFromForeignDomain *r)
    7010             : {
    7011           0 :         struct samr_info *dinfo;
    7012           0 :         struct dom_sid_buf buf;
    7013           0 :         NTSTATUS                result;
    7014             : 
    7015           3 :         DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
    7016             :                  dom_sid_str_buf(r->in.sid, &buf)));
    7017             : 
    7018             :         /* Find the policy handle. Open a policy on it. */
    7019             : 
    7020           3 :         dinfo = samr_policy_handle_find(p,
    7021           3 :                                         r->in.domain_handle,
    7022             :                                         SAMR_HANDLE_DOMAIN,
    7023             :                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
    7024             :                                         NULL,
    7025             :                                         &result);
    7026           3 :         if (!NT_STATUS_IS_OK(result)) {
    7027           0 :                 return result;
    7028             :         }
    7029             : 
    7030           3 :         DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
    7031             :                   dom_sid_str_buf(&dinfo->sid, &buf)));
    7032             : 
    7033             :         /* we can only delete a user from a group since we don't have
    7034             :            nested groups anyways.  So in the latter case, just say OK */
    7035             : 
    7036             :         /* TODO: The above comment nowadays is bogus. Since we have nested
    7037             :          * groups now, and aliases members are never reported out of the unix
    7038             :          * group membership, the "just say OK" makes this call a no-op. For
    7039             :          * us. This needs fixing however. */
    7040             : 
    7041             :         /* I've only ever seen this in the wild when deleting a user from
    7042             :          * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
    7043             :          * is the user about to be deleted. I very much suspect this is the
    7044             :          * only application of this call. To verify this, let people report
    7045             :          * other cases. */
    7046             : 
    7047           3 :         if (!sid_check_is_builtin(&dinfo->sid)) {
    7048           0 :                 struct dom_sid_buf buf2;
    7049           1 :                 DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
    7050             :                          "global_sam_sid() = %s\n",
    7051             :                          dom_sid_str_buf(&dinfo->sid, &buf),
    7052             :                          dom_sid_str_buf(get_global_sam_sid(), &buf2)));
    7053           1 :                 DEBUGADD(1,("please report to samba-technical@lists.samba.org!\n"));
    7054           1 :                 return NT_STATUS_OK;
    7055             :         }
    7056             : 
    7057           2 :         force_flush_samr_cache(&dinfo->sid);
    7058             : 
    7059           2 :         result = NT_STATUS_OK;
    7060             : 
    7061           2 :         return result;
    7062             : }
    7063             : 
    7064             : /*******************************************************************
    7065             :  _samr_QueryDomainInfo2
    7066             :  ********************************************************************/
    7067             : 
    7068          44 : NTSTATUS _samr_QueryDomainInfo2(struct pipes_struct *p,
    7069             :                                 struct samr_QueryDomainInfo2 *r)
    7070             : {
    7071           0 :         struct samr_QueryDomainInfo q;
    7072             : 
    7073          44 :         q.in.domain_handle      = r->in.domain_handle;
    7074          44 :         q.in.level              = r->in.level;
    7075             : 
    7076          44 :         q.out.info              = r->out.info;
    7077             : 
    7078          44 :         return _samr_QueryDomainInfo(p, &q);
    7079             : }
    7080             : 
    7081             : /*******************************************************************
    7082             :  ********************************************************************/
    7083             : 
    7084          20 : static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
    7085             :                                struct samr_DomInfo1 *r)
    7086             : {
    7087           0 :         time_t u_expire, u_min_age;
    7088             : 
    7089          20 :         u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
    7090          20 :         u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
    7091             : 
    7092          20 :         pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
    7093          20 :                                (uint32_t)r->min_password_length);
    7094          20 :         pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
    7095          20 :                                (uint32_t)r->password_history_length);
    7096          20 :         pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
    7097          20 :                                (uint32_t)r->password_properties);
    7098          20 :         pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
    7099          20 :         pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
    7100             : 
    7101          20 :         return NT_STATUS_OK;
    7102             : }
    7103             : 
    7104             : /*******************************************************************
    7105             :  ********************************************************************/
    7106             : 
    7107           2 : static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
    7108             :                                struct samr_DomInfo3 *r)
    7109             : {
    7110           0 :         time_t u_logout;
    7111             : 
    7112           2 :         u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
    7113             : 
    7114           2 :         pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
    7115             : 
    7116           2 :         return NT_STATUS_OK;
    7117             : }
    7118             : 
    7119             : /*******************************************************************
    7120             :  ********************************************************************/
    7121             : 
    7122          20 : static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
    7123             :                                 struct samr_DomInfo12 *r)
    7124             : {
    7125           0 :         time_t u_lock_duration, u_reset_time;
    7126             : 
    7127             :         /*
    7128             :          * It is not possible to set lockout_duration < lockout_window.
    7129             :          * (The test is the other way around since the negative numbers
    7130             :          *  are stored...)
    7131             :          *
    7132             :          * This constraint is documented here for the samr rpc service:
    7133             :          * MS-SAMR 3.1.1.6 Attribute Constraints for Originating Updates
    7134             :          * http://msdn.microsoft.com/en-us/library/cc245667%28PROT.10%29.aspx
    7135             :          *
    7136             :          * And here for the ldap backend:
    7137             :          * MS-ADTS 3.1.1.5.3.2 Constraints
    7138             :          * http://msdn.microsoft.com/en-us/library/cc223462(PROT.10).aspx
    7139             :          */
    7140          20 :         if (r->lockout_duration > r->lockout_window) {
    7141           2 :                 return NT_STATUS_INVALID_PARAMETER;
    7142             :         }
    7143             : 
    7144          18 :         u_lock_duration = nt_time_to_unix_abs((NTTIME *)&r->lockout_duration);
    7145          18 :         if (u_lock_duration != -1) {
    7146          18 :                 u_lock_duration /= 60;
    7147             :         }
    7148             : 
    7149          18 :         u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
    7150             : 
    7151          18 :         pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
    7152          18 :         pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
    7153          18 :         pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
    7154          18 :                                (uint32_t)r->lockout_threshold);
    7155             : 
    7156          18 :         return NT_STATUS_OK;
    7157             : }
    7158             : 
    7159             : /*******************************************************************
    7160             :  _samr_SetDomainInfo
    7161             :  ********************************************************************/
    7162             : 
    7163          62 : NTSTATUS _samr_SetDomainInfo(struct pipes_struct *p,
    7164             :                              struct samr_SetDomainInfo *r)
    7165             : {
    7166           0 :         NTSTATUS status;
    7167          62 :         uint32_t acc_required = 0;
    7168             : 
    7169          62 :         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
    7170             : 
    7171          62 :         switch (r->in.level) {
    7172          40 :         case 1: /* DomainPasswordInformation */
    7173             :         case 12: /* DomainLockoutInformation */
    7174             :                 /* DOMAIN_WRITE_PASSWORD_PARAMETERS */
    7175          40 :                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_1;
    7176          40 :                 break;
    7177           6 :         case 3: /* DomainLogoffInformation */
    7178             :         case 4: /* DomainOemInformation */
    7179             :                 /* DOMAIN_WRITE_OTHER_PARAMETERS */
    7180           6 :                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_2;
    7181           6 :                 break;
    7182           6 :         case 6: /* DomainReplicationInformation */
    7183             :         case 9: /* DomainStateInformation */
    7184             :         case 7: /* DomainServerRoleInformation */
    7185             :                 /* DOMAIN_ADMINISTER_SERVER */
    7186           6 :                 acc_required = SAMR_DOMAIN_ACCESS_SET_INFO_3;
    7187           6 :                 break;
    7188          10 :         default:
    7189          10 :                 return NT_STATUS_INVALID_INFO_CLASS;
    7190             :         }
    7191             : 
    7192          52 :         (void)samr_policy_handle_find(p,
    7193          52 :                                       r->in.domain_handle,
    7194             :                                       SAMR_HANDLE_DOMAIN,
    7195             :                                       acc_required,
    7196             :                                       NULL,
    7197             :                                       &status);
    7198          52 :         if (!NT_STATUS_IS_OK(status)) {
    7199           0 :                 return status;
    7200             :         }
    7201             : 
    7202          52 :         DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
    7203             : 
    7204          52 :         switch (r->in.level) {
    7205          20 :                 case 1:
    7206          20 :                         status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
    7207          20 :                         break;
    7208           2 :                 case 3:
    7209           2 :                         status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
    7210           2 :                         break;
    7211           4 :                 case 4:
    7212           4 :                         break;
    7213           2 :                 case 6:
    7214           2 :                         break;
    7215           2 :                 case 7:
    7216           2 :                         break;
    7217           2 :                 case 9:
    7218           2 :                         break;
    7219          20 :                 case 12:
    7220          20 :                         status = set_dom_info_12(p->mem_ctx, &r->in.info->info12);
    7221          20 :                         break;
    7222           0 :                 default:
    7223           0 :                         return NT_STATUS_INVALID_INFO_CLASS;
    7224             :         }
    7225             : 
    7226          52 :         if (!NT_STATUS_IS_OK(status)) {
    7227           2 :                 return status;
    7228             :         }
    7229             : 
    7230          50 :         DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
    7231             : 
    7232          50 :         return NT_STATUS_OK;
    7233             : }
    7234             : 
    7235             : /****************************************************************
    7236             :  _samr_GetDisplayEnumerationIndex
    7237             : ****************************************************************/
    7238             : 
    7239          40 : NTSTATUS _samr_GetDisplayEnumerationIndex(struct pipes_struct *p,
    7240             :                                           struct samr_GetDisplayEnumerationIndex *r)
    7241             : {
    7242           0 :         struct samr_info *dinfo;
    7243          40 :         uint32_t max_entries = (uint32_t) -1;
    7244          40 :         uint32_t enum_context = 0;
    7245          40 :         uint32_t i, num_account = 0;
    7246          40 :         struct samr_displayentry *entries = NULL;
    7247           0 :         NTSTATUS status;
    7248             : 
    7249          40 :         DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
    7250             : 
    7251          40 :         dinfo = samr_policy_handle_find(p,
    7252          40 :                                         r->in.domain_handle,
    7253             :                                         SAMR_HANDLE_DOMAIN,
    7254             :                                         SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
    7255             :                                         NULL,
    7256             :                                         &status);
    7257          40 :         if (!NT_STATUS_IS_OK(status)) {
    7258           0 :                 return status;
    7259             :         }
    7260             : 
    7261          40 :         if ((r->in.level < 1) || (r->in.level > 3)) {
    7262          16 :                 DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
    7263             :                         "Unknown info level (%u)\n",
    7264             :                         r->in.level));
    7265          16 :                 return NT_STATUS_INVALID_INFO_CLASS;
    7266             :         }
    7267             : 
    7268          24 :         become_root();
    7269             : 
    7270             :         /* The following done as ROOT. Don't return without unbecome_root(). */
    7271             : 
    7272          24 :         switch (r->in.level) {
    7273           8 :         case 1:
    7274           8 :                 if (dinfo->disp_info->users == NULL) {
    7275           2 :                         dinfo->disp_info->users = pdb_search_users(
    7276           1 :                                 dinfo->disp_info, ACB_NORMAL);
    7277           1 :                         if (dinfo->disp_info->users == NULL) {
    7278           0 :                                 unbecome_root();
    7279           0 :                                 return NT_STATUS_ACCESS_DENIED;
    7280             :                         }
    7281           1 :                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
    7282             :                                 "starting user enumeration at index %u\n",
    7283             :                                 (unsigned int)enum_context));
    7284             :                 } else {
    7285           7 :                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
    7286             :                                 "using cached user enumeration at index %u\n",
    7287             :                                 (unsigned int)enum_context));
    7288             :                 }
    7289           8 :                 num_account = pdb_search_entries(dinfo->disp_info->users,
    7290             :                                                  enum_context, max_entries,
    7291             :                                                  &entries);
    7292           8 :                 break;
    7293           8 :         case 2:
    7294           8 :                 if (dinfo->disp_info->machines == NULL) {
    7295           2 :                         dinfo->disp_info->machines = pdb_search_users(
    7296           1 :                                 dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
    7297           1 :                         if (dinfo->disp_info->machines == NULL) {
    7298           0 :                                 unbecome_root();
    7299           0 :                                 return NT_STATUS_ACCESS_DENIED;
    7300             :                         }
    7301           1 :                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
    7302             :                                 "starting machine enumeration at index %u\n",
    7303             :                                 (unsigned int)enum_context));
    7304             :                 } else {
    7305           7 :                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
    7306             :                                 "using cached machine enumeration at index %u\n",
    7307             :                                 (unsigned int)enum_context));
    7308             :                 }
    7309           8 :                 num_account = pdb_search_entries(dinfo->disp_info->machines,
    7310             :                                                  enum_context, max_entries,
    7311             :                                                  &entries);
    7312           8 :                 break;
    7313           8 :         case 3:
    7314           8 :                 if (dinfo->disp_info->groups == NULL) {
    7315           2 :                         dinfo->disp_info->groups = pdb_search_groups(
    7316           1 :                                 dinfo->disp_info);
    7317           1 :                         if (dinfo->disp_info->groups == NULL) {
    7318           0 :                                 unbecome_root();
    7319           0 :                                 return NT_STATUS_ACCESS_DENIED;
    7320             :                         }
    7321           1 :                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
    7322             :                                 "starting group enumeration at index %u\n",
    7323             :                                 (unsigned int)enum_context));
    7324             :                 } else {
    7325           7 :                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
    7326             :                                 "using cached group enumeration at index %u\n",
    7327             :                                 (unsigned int)enum_context));
    7328             :                 }
    7329           8 :                 num_account = pdb_search_entries(dinfo->disp_info->groups,
    7330             :                                                  enum_context, max_entries,
    7331             :                                                  &entries);
    7332           8 :                 break;
    7333           0 :         default:
    7334           0 :                 unbecome_root();
    7335           0 :                 smb_panic("info class changed");
    7336           0 :                 break;
    7337             :         }
    7338             : 
    7339          24 :         unbecome_root();
    7340             : 
    7341             :         /* Ensure we cache this enumeration. */
    7342          24 :         set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
    7343             : 
    7344          24 :         DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
    7345             :                 r->in.name->string));
    7346             : 
    7347         114 :         for (i=0; i<num_account; i++) {
    7348          92 :                 if (strequal(entries[i].account_name, r->in.name->string)) {
    7349           2 :                         DEBUG(10,("_samr_GetDisplayEnumerationIndex: "
    7350             :                                 "found %s at idx %d\n",
    7351             :                                 r->in.name->string, i));
    7352           2 :                         *r->out.idx = i;
    7353           2 :                         return NT_STATUS_OK;
    7354             :                 }
    7355             :         }
    7356             : 
    7357             :         /* assuming account_name lives at the very end */
    7358          22 :         *r->out.idx = num_account;
    7359             : 
    7360          22 :         return NT_STATUS_NO_MORE_ENTRIES;
    7361             : }
    7362             : 
    7363             : /****************************************************************
    7364             :  _samr_GetDisplayEnumerationIndex2
    7365             : ****************************************************************/
    7366             : 
    7367          20 : NTSTATUS _samr_GetDisplayEnumerationIndex2(struct pipes_struct *p,
    7368             :                                            struct samr_GetDisplayEnumerationIndex2 *r)
    7369             : {
    7370           0 :         struct samr_GetDisplayEnumerationIndex q;
    7371             : 
    7372          20 :         q.in.domain_handle      = r->in.domain_handle;
    7373          20 :         q.in.level              = r->in.level;
    7374          20 :         q.in.name               = r->in.name;
    7375             : 
    7376          20 :         q.out.idx               = r->out.idx;
    7377             : 
    7378          20 :         return _samr_GetDisplayEnumerationIndex(p, &q);
    7379             : }
    7380             : 
    7381             : /****************************************************************
    7382             :  _samr_RidToSid
    7383             : ****************************************************************/
    7384             : 
    7385           8 : NTSTATUS _samr_RidToSid(struct pipes_struct *p,
    7386             :                         struct samr_RidToSid *r)
    7387             : {
    7388           0 :         struct samr_info *dinfo;
    7389           0 :         NTSTATUS status;
    7390           0 :         struct dom_sid sid;
    7391             : 
    7392           8 :         dinfo = samr_policy_handle_find(p,
    7393           8 :                                         r->in.domain_handle,
    7394             :                                         SAMR_HANDLE_DOMAIN,
    7395             :                                         0,
    7396             :                                         NULL,
    7397             :                                         &status);
    7398           8 :         if (!NT_STATUS_IS_OK(status)) {
    7399           0 :                 return status;
    7400             :         }
    7401             : 
    7402           8 :         if (!sid_compose(&sid, &dinfo->sid, r->in.rid)) {
    7403           0 :                 return NT_STATUS_NO_MEMORY;
    7404             :         }
    7405             : 
    7406           8 :         *r->out.sid = dom_sid_dup(p->mem_ctx, &sid);
    7407           8 :         if (!*r->out.sid) {
    7408           0 :                 return NT_STATUS_NO_MEMORY;
    7409             :         }
    7410             : 
    7411           8 :         return NT_STATUS_OK;
    7412             : }
    7413             : 
    7414             : /****************************************************************
    7415             : ****************************************************************/
    7416             : 
    7417           0 : static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_ctx,
    7418             :                                                                const struct samr_PwInfo *dom_pw_info,
    7419             :                                                                const struct samr_ValidatePasswordReq2 *req,
    7420             :                                                                struct samr_ValidatePasswordRepCtr *rep)
    7421             : {
    7422           0 :         NTSTATUS status;
    7423             : 
    7424           0 :         if (req->password.string == NULL) {
    7425           0 :                 return SAMR_VALIDATION_STATUS_SUCCESS;
    7426             :         }
    7427           0 :         if (strlen(req->password.string) < dom_pw_info->min_password_length) {
    7428           0 :                 ZERO_STRUCT(rep->info);
    7429           0 :                 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
    7430             :         }
    7431           0 :         if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
    7432           0 :                 status = check_password_complexity(req->account.string,
    7433             :                                                    NULL, /* full_name */
    7434           0 :                                                    req->password.string,
    7435             :                                                    NULL);
    7436           0 :                 if (!NT_STATUS_IS_OK(status)) {
    7437           0 :                         ZERO_STRUCT(rep->info);
    7438           0 :                         return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
    7439             :                 }
    7440             :         }
    7441             : 
    7442           0 :         return SAMR_VALIDATION_STATUS_SUCCESS;
    7443             : }
    7444             : 
    7445             : /****************************************************************
    7446             : ****************************************************************/
    7447             : 
    7448           3 : static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ctx,
    7449             :                                                               const struct samr_PwInfo *dom_pw_info,
    7450             :                                                               const struct samr_ValidatePasswordReq3 *req,
    7451             :                                                               struct samr_ValidatePasswordRepCtr *rep)
    7452             : {
    7453           0 :         NTSTATUS status;
    7454             : 
    7455           3 :         if (req->password.string == NULL) {
    7456           0 :                 return SAMR_VALIDATION_STATUS_SUCCESS;
    7457             :         }
    7458           3 :         if (strlen(req->password.string) < dom_pw_info->min_password_length) {
    7459           0 :                 ZERO_STRUCT(rep->info);
    7460           0 :                 return SAMR_VALIDATION_STATUS_PWD_TOO_SHORT;
    7461             :         }
    7462           3 :         if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
    7463           0 :                 status = check_password_complexity(req->account.string,
    7464             :                                                    NULL, /* full_name */
    7465           0 :                                                    req->password.string,
    7466             :                                                    NULL);
    7467           0 :                 if (!NT_STATUS_IS_OK(status)) {
    7468           0 :                         ZERO_STRUCT(rep->info);
    7469           0 :                         return SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH;
    7470             :                 }
    7471             :         }
    7472             : 
    7473           3 :         return SAMR_VALIDATION_STATUS_SUCCESS;
    7474             : }
    7475             : 
    7476             : /****************************************************************
    7477             :  _samr_ValidatePassword
    7478             : ****************************************************************/
    7479             : 
    7480           3 : NTSTATUS _samr_ValidatePassword(struct pipes_struct *p,
    7481             :                                 struct samr_ValidatePassword *r)
    7482             : {
    7483           3 :         struct dcesrv_call_state *dce_call = p->dce_call;
    7484           3 :         enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
    7485           0 :         union samr_ValidatePasswordRep *rep;
    7486           0 :         NTSTATUS status;
    7487           0 :         struct samr_GetDomPwInfo pw;
    7488           0 :         struct samr_PwInfo dom_pw_info;
    7489             : 
    7490           3 :         if (p->transport != NCACN_IP_TCP && p->transport != NCALRPC) {
    7491           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    7492           0 :                 return NT_STATUS_ACCESS_DENIED;
    7493             :         }
    7494             : 
    7495           3 :         dcesrv_call_auth_info(dce_call, NULL, &auth_level);
    7496             : 
    7497           3 :         if (auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
    7498           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    7499           0 :                 return NT_STATUS_ACCESS_DENIED;
    7500             :         }
    7501             : 
    7502           3 :         if (r->in.level < 1 || r->in.level > 3) {
    7503           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    7504             :         }
    7505             : 
    7506           3 :         pw.in.domain_name = NULL;
    7507           3 :         pw.out.info = &dom_pw_info;
    7508             : 
    7509           3 :         status = _samr_GetDomPwInfo(p, &pw);
    7510           3 :         if (!NT_STATUS_IS_OK(status)) {
    7511           0 :                 return status;
    7512             :         }
    7513             : 
    7514           3 :         rep = talloc_zero(p->mem_ctx, union samr_ValidatePasswordRep);
    7515           3 :         if (!rep) {
    7516           0 :                 return NT_STATUS_NO_MEMORY;
    7517             :         }
    7518             : 
    7519           3 :         switch (r->in.level) {
    7520           0 :         case 1:
    7521           0 :                 status = NT_STATUS_NOT_SUPPORTED;
    7522           0 :                 break;
    7523           0 :         case 2:
    7524           0 :                 rep->ctr2.status = samr_ValidatePassword_Change(p->mem_ctx,
    7525             :                                                                 &dom_pw_info,
    7526           0 :                                                                 &r->in.req->req2,
    7527             :                                                                 &rep->ctr2);
    7528           0 :                 break;
    7529           3 :         case 3:
    7530           6 :                 rep->ctr3.status = samr_ValidatePassword_Reset(p->mem_ctx,
    7531             :                                                                &dom_pw_info,
    7532           3 :                                                                &r->in.req->req3,
    7533             :                                                                &rep->ctr3);
    7534           3 :                 break;
    7535           0 :         default:
    7536           0 :                 status = NT_STATUS_INVALID_INFO_CLASS;
    7537           0 :                 break;
    7538             :         }
    7539             : 
    7540           3 :         if (!NT_STATUS_IS_OK(status)) {
    7541           0 :                 talloc_free(rep);
    7542           0 :                 return status;
    7543             :         }
    7544             : 
    7545           3 :         *r->out.rep = rep;
    7546             : 
    7547           3 :         return NT_STATUS_OK;
    7548             : }
    7549             : 
    7550             : /****************************************************************
    7551             : ****************************************************************/
    7552             : 
    7553           0 : NTSTATUS _samr_Shutdown(struct pipes_struct *p,
    7554             :                         struct samr_Shutdown *r)
    7555             : {
    7556           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7557           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    7558             : }
    7559             : 
    7560             : /****************************************************************
    7561             : ****************************************************************/
    7562             : 
    7563           0 : NTSTATUS _samr_SetMemberAttributesOfGroup(struct pipes_struct *p,
    7564             :                                           struct samr_SetMemberAttributesOfGroup *r)
    7565             : {
    7566           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7567           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    7568             : }
    7569             : 
    7570             : /****************************************************************
    7571             : ****************************************************************/
    7572             : 
    7573           2 : NTSTATUS _samr_TestPrivateFunctionsDomain(struct pipes_struct *p,
    7574             :                                           struct samr_TestPrivateFunctionsDomain *r)
    7575             : {
    7576           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7577           2 :         return NT_STATUS_NOT_IMPLEMENTED;
    7578             : }
    7579             : 
    7580             : /****************************************************************
    7581             : ****************************************************************/
    7582             : 
    7583           1 : NTSTATUS _samr_TestPrivateFunctionsUser(struct pipes_struct *p,
    7584             :                                         struct samr_TestPrivateFunctionsUser *r)
    7585             : {
    7586           1 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7587           1 :         return NT_STATUS_NOT_IMPLEMENTED;
    7588             : }
    7589             : 
    7590             : /****************************************************************
    7591             : ****************************************************************/
    7592             : 
    7593           0 : NTSTATUS _samr_AddMultipleMembersToAlias(struct pipes_struct *p,
    7594             :                                          struct samr_AddMultipleMembersToAlias *r)
    7595             : {
    7596           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7597           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    7598             : }
    7599             : 
    7600             : /****************************************************************
    7601             : ****************************************************************/
    7602             : 
    7603           0 : NTSTATUS _samr_RemoveMultipleMembersFromAlias(struct pipes_struct *p,
    7604             :                                               struct samr_RemoveMultipleMembersFromAlias *r)
    7605             : {
    7606           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7607           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    7608             : }
    7609             : 
    7610             : /****************************************************************
    7611             : ****************************************************************/
    7612             : 
    7613           0 : NTSTATUS _samr_SetBootKeyInformation(struct pipes_struct *p,
    7614             :                                      struct samr_SetBootKeyInformation *r)
    7615             : {
    7616           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7617           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    7618             : }
    7619             : 
    7620             : /****************************************************************
    7621             : ****************************************************************/
    7622             : 
    7623           2 : NTSTATUS _samr_GetBootKeyInformation(struct pipes_struct *p,
    7624             :                                      struct samr_GetBootKeyInformation *r)
    7625             : {
    7626           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7627           2 :         return NT_STATUS_NOT_IMPLEMENTED;
    7628             : }
    7629             : 
    7630             : /****************************************************************
    7631             : ****************************************************************/
    7632             : 
    7633           0 : NTSTATUS _samr_SetDsrmPassword(struct pipes_struct *p,
    7634             :                                struct samr_SetDsrmPassword *r)
    7635             : {
    7636           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7637           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    7638             : }
    7639             : 
    7640           0 : void _samr_Opnum68NotUsedOnWire(struct pipes_struct *p,
    7641             :                                 struct samr_Opnum68NotUsedOnWire *r)
    7642             : {
    7643           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7644           0 : }
    7645             : 
    7646           0 : void _samr_Opnum69NotUsedOnWire(struct pipes_struct *p,
    7647             :                                 struct samr_Opnum69NotUsedOnWire *r)
    7648             : {
    7649           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7650           0 : }
    7651             : 
    7652           0 : void _samr_Opnum70NotUsedOnWire(struct pipes_struct *p,
    7653             :                                 struct samr_Opnum70NotUsedOnWire *r)
    7654             : {
    7655           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7656           0 : }
    7657             : 
    7658           0 : void _samr_Opnum71NotUsedOnWire(struct pipes_struct *p,
    7659             :                                 struct samr_Opnum71NotUsedOnWire *r)
    7660             : {
    7661           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7662           0 : }
    7663             : 
    7664           0 : void _samr_Opnum72NotUsedOnWire(struct pipes_struct *p,
    7665             :                                 struct samr_Opnum72NotUsedOnWire *r)
    7666             : {
    7667           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    7668           0 : }
    7669             : 
    7670           8 : NTSTATUS _samr_ChangePasswordUser4(struct pipes_struct *p,
    7671             :                                    struct samr_ChangePasswordUser4 *r)
    7672             : {
    7673           8 :         TALLOC_CTX *frame = talloc_stackframe();
    7674           8 :         struct dcesrv_call_state *dce_call = p->dce_call;
    7675           8 :         struct dcesrv_connection *dcesrv_conn = dce_call->conn;
    7676           0 :         const struct tsocket_address *remote_address =
    7677           8 :                 dcesrv_connection_get_remote_address(dcesrv_conn);
    7678           8 :         char *rhost = NULL;
    7679           8 :         struct samu *sampass = NULL;
    7680           8 :         char *username = NULL;
    7681           8 :         uint32_t acct_ctrl = 0;
    7682           8 :         const uint8_t *nt_pw = NULL;
    7683           0 :         gnutls_datum_t nt_key;
    7684           8 :         gnutls_datum_t salt = {
    7685           8 :                 .data = r->in.password->salt,
    7686             :                 .size = sizeof(r->in.password->salt),
    7687             :         };
    7688           8 :         uint8_t cdk_data[16] = {0};
    7689           8 :         DATA_BLOB cdk = {
    7690             :                 .data = cdk_data,
    7691             :                 .length = sizeof(cdk_data),
    7692             :         };
    7693           8 :         char *new_passwd = NULL;
    7694           8 :         bool updated_badpw = false;
    7695           0 :         NTSTATUS update_login_attempts_status;
    7696           8 :         char *mutex_name_by_user = NULL;
    7697           8 :         struct named_mutex *mtx = NULL;
    7698           8 :         NTSTATUS status = NT_STATUS_WRONG_PASSWORD;
    7699           0 :         bool ok;
    7700           0 :         int rc;
    7701             : 
    7702           8 :         r->out.result = NT_STATUS_WRONG_PASSWORD;
    7703             : 
    7704           8 :         DBG_NOTICE("_samr_ChangePasswordUser4\n");
    7705             : 
    7706           8 :         if (r->in.account->string == NULL) {
    7707           0 :                 return NT_STATUS_INVALID_PARAMETER;
    7708             :         }
    7709           8 :         if (r->in.password == NULL) {
    7710           0 :                 return NT_STATUS_INVALID_PARAMETER;
    7711             :         }
    7712             : 
    7713           8 :         if (r->in.password->PBKDF2Iterations < 5000 ||
    7714           8 :             r->in.password->PBKDF2Iterations > 1000000) {
    7715           0 :                 return NT_STATUS_INVALID_PARAMETER;
    7716             :         }
    7717             : 
    7718           8 :         (void)map_username(frame, r->in.account->string, &username);
    7719           8 :         if (username == NULL) {
    7720           0 :                 return NT_STATUS_NO_MEMORY;
    7721             :         }
    7722             : 
    7723           8 :         rhost = tsocket_address_inet_addr_string(remote_address, frame);
    7724           8 :         if (rhost == NULL) {
    7725           0 :                 status = NT_STATUS_NO_MEMORY;
    7726           0 :                 goto done;
    7727             :         }
    7728           8 :         sampass = samu_new(frame);
    7729           8 :         if (sampass == NULL) {
    7730           0 :                 status = NT_STATUS_NO_MEMORY;
    7731           0 :                 goto done;
    7732             :         }
    7733             : 
    7734           8 :         become_root();
    7735           8 :         ok = pdb_getsampwnam(sampass, username);
    7736           8 :         unbecome_root();
    7737           8 :         if (!ok) {
    7738           0 :                 status = NT_STATUS_NO_SUCH_USER;
    7739           0 :                 goto done;
    7740             :         }
    7741             : 
    7742           8 :         acct_ctrl = pdb_get_acct_ctrl(sampass);
    7743           8 :         if (acct_ctrl & ACB_AUTOLOCK) {
    7744           0 :                 status = NT_STATUS_ACCOUNT_LOCKED_OUT;
    7745           0 :                 goto done;
    7746             :         }
    7747             : 
    7748           8 :         nt_pw = pdb_get_nt_passwd(sampass);
    7749           8 :         nt_key = (gnutls_datum_t){
    7750             :                 .data = discard_const_p(uint8_t, nt_pw),
    7751             :                 .size = NT_HASH_LEN,
    7752             :         };
    7753             : 
    7754           8 :         rc = gnutls_pbkdf2(GNUTLS_MAC_SHA512,
    7755             :                            &nt_key,
    7756             :                            &salt,
    7757           8 :                            r->in.password->PBKDF2Iterations,
    7758           8 :                            cdk.data,
    7759             :                            cdk.length);
    7760           8 :         if (rc < 0) {
    7761           0 :                 BURN_DATA(cdk_data);
    7762           0 :                 status = NT_STATUS_WRONG_PASSWORD;
    7763           0 :                 goto done;
    7764             :         }
    7765             : 
    7766           8 :         status = samr_set_password_aes(frame,
    7767             :                                        &cdk,
    7768             :                                        r->in.password,
    7769             :                                        &new_passwd);
    7770           8 :         BURN_DATA(cdk_data);
    7771             : 
    7772             :         /*
    7773             :          * We must re-load the sam account information under a mutex
    7774             :          * lock to ensure we don't miss any concurrent account lockout
    7775             :          * changes.
    7776             :          */
    7777             : 
    7778             :         /* Clear out old sampass info. */
    7779           8 :         TALLOC_FREE(sampass);
    7780             : 
    7781           8 :         sampass = samu_new(frame);
    7782           8 :         if (sampass == NULL) {
    7783           0 :                 status = NT_STATUS_NO_MEMORY;
    7784           0 :                 goto done;
    7785             :         }
    7786             : 
    7787           8 :         mutex_name_by_user = talloc_asprintf(frame,
    7788             :                                              "check_sam_security_mutex_%s",
    7789             :                                              username);
    7790           8 :         if (mutex_name_by_user == NULL) {
    7791           0 :                 status = NT_STATUS_NO_MEMORY;
    7792           0 :                 goto done;
    7793             :         }
    7794             : 
    7795             :         /* Grab the named mutex under root with 30 second timeout. */
    7796           8 :         become_root();
    7797           8 :         mtx = grab_named_mutex(frame, mutex_name_by_user, 30);
    7798           8 :         if (mtx != NULL) {
    7799             :                 /* Re-load the account information if we got the mutex. */
    7800           8 :                 ok = pdb_getsampwnam(sampass, username);
    7801             :         }
    7802           8 :         unbecome_root();
    7803             : 
    7804             :         /* Everything from here on until mtx is freed is done under the mutex.*/
    7805             : 
    7806           8 :         if (mtx == NULL) {
    7807           0 :                 DBG_ERR("Acquisition of mutex %s failed "
    7808             :                         "for user %s\n",
    7809             :                         mutex_name_by_user,
    7810             :                         username);
    7811           0 :                 status = NT_STATUS_INTERNAL_ERROR;
    7812           0 :                 goto done;
    7813             :         }
    7814             : 
    7815           8 :         if (!ok) {
    7816             :                 /*
    7817             :                  * Re-load of account failed. This could only happen if the
    7818             :                  * user was deleted in the meantime.
    7819             :                  */
    7820           0 :                 DBG_NOTICE("reload of user '%s' in passdb failed.\n",
    7821             :                            username);
    7822           0 :                 status = NT_STATUS_NO_SUCH_USER;
    7823           0 :                 goto done;
    7824             :         }
    7825             : 
    7826             :         /*
    7827             :          * Check if the account is now locked out - now under the mutex.
    7828             :          * This can happen if the server is under
    7829             :          * a password guess attack and the ACB_AUTOLOCK is set by
    7830             :          * another process.
    7831             :          */
    7832           8 :         if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) {
    7833           0 :                 DBG_NOTICE("Account for user %s was locked out.\n", username);
    7834           0 :                 status = NT_STATUS_ACCOUNT_LOCKED_OUT;
    7835           0 :                 goto done;
    7836             :         }
    7837             : 
    7838             :         /*
    7839             :          * Notify passdb backend of login success/failure. If not
    7840             :          * NT_STATUS_OK the backend doesn't like the login
    7841             :          */
    7842           8 :         update_login_attempts_status = pdb_update_login_attempts(
    7843           8 :                 sampass, NT_STATUS_IS_OK(status));
    7844             : 
    7845           8 :         if (!NT_STATUS_IS_OK(status)) {
    7846           0 :                 bool increment_bad_pw_count = false;
    7847             : 
    7848           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD) &&
    7849           0 :                     (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) &&
    7850           0 :                     NT_STATUS_IS_OK(update_login_attempts_status))
    7851             :                 {
    7852           0 :                         increment_bad_pw_count = true;
    7853             :                 }
    7854             : 
    7855           0 :                 if (increment_bad_pw_count) {
    7856           0 :                         pdb_increment_bad_password_count(sampass);
    7857           0 :                         updated_badpw = true;
    7858             :                 } else {
    7859           0 :                         pdb_update_bad_password_count(sampass,
    7860             :                                                       &updated_badpw);
    7861             :                 }
    7862             :         } else {
    7863          16 :                 if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) &&
    7864           8 :                     (pdb_get_bad_password_count(sampass) > 0))
    7865             :                 {
    7866           0 :                         pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
    7867           0 :                         pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
    7868           0 :                         updated_badpw = true;
    7869             :                 }
    7870             :         }
    7871             : 
    7872           8 :         if (updated_badpw) {
    7873           0 :                 NTSTATUS update_status;
    7874           0 :                 become_root();
    7875           0 :                 update_status = pdb_update_sam_account(sampass);
    7876           0 :                 unbecome_root();
    7877             : 
    7878           0 :                 if (!NT_STATUS_IS_OK(update_status)) {
    7879           0 :                         DEBUG(1, ("Failed to modify entry: %s\n",
    7880             :                                   nt_errstr(update_status)));
    7881             :                 }
    7882             :         }
    7883             : 
    7884           8 :         if (!NT_STATUS_IS_OK(status)) {
    7885           0 :                 goto done;
    7886             :         }
    7887             : 
    7888           8 :         become_root();
    7889           8 :         status = change_oem_password(sampass,
    7890             :                                      rhost,
    7891             :                                      NULL,
    7892             :                                      new_passwd,
    7893             :                                      true,
    7894             :                                      NULL);
    7895           8 :         unbecome_root();
    7896           8 :         TALLOC_FREE(new_passwd);
    7897             : 
    7898           0 : done:
    7899           8 :         TALLOC_FREE(frame);
    7900             : 
    7901           8 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
    7902           0 :                 return NT_STATUS_WRONG_PASSWORD;
    7903             :         }
    7904             : 
    7905           8 :         return status;
    7906             : }
    7907             : 
    7908             : /* include the generated boilerplate */
    7909             : #include "librpc/gen_ndr/ndr_samr_scompat.c"

Generated by: LCOV version 1.14