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 v4-17-test 1498b464 Lines: 870 3315 26.2 %
Date: 2024-06-13 04:01:37 Functions: 44 161 27.3 %

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

Generated by: LCOV version 1.13