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 master 2f515e9b Lines: 2623 3617 72.5 %
Date: 2024-04-21 15:09:00 Functions: 149 161 92.5 %

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

Generated by: LCOV version 1.14