root/source3/rpc_server/srv_samr_nt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. make_samr_object_sd
  2. access_check_object
  3. access_check_samr_function
  4. map_max_allowed_access
  5. get_samr_dispinfo_by_sid
  6. get_samr_info_by_sid
  7. free_samr_cache
  8. samr_info_destructor
  9. disp_info_cache_idle_timeout_handler
  10. set_disp_info_cache_timeout
  11. force_flush_samr_cache
  12. samr_clear_sam_passwd
  13. count_sam_users
  14. count_sam_groups
  15. count_sam_aliases
  16. _samr_Close
  17. _samr_OpenDomain
  18. _samr_GetUserPwInfo
  19. get_lsa_policy_samr_sid
  20. _samr_SetSecurity
  21. check_change_pw_access
  22. _samr_QuerySecurity
  23. make_user_sam_entry_list
  24. _samr_EnumDomainUsers
  25. make_group_sam_entry_list
  26. _samr_EnumDomainGroups
  27. _samr_EnumDomainAliases
  28. init_samr_dispinfo_1
  29. init_samr_dispinfo_2
  30. init_samr_dispinfo_3
  31. init_samr_dispinfo_4
  32. init_samr_dispinfo_5
  33. _samr_QueryDisplayInfo
  34. _samr_QueryDisplayInfo2
  35. _samr_QueryDisplayInfo3
  36. _samr_QueryAliasInfo
  37. _samr_LookupNames
  38. _samr_ChangePasswordUser
  39. _samr_ChangePasswordUser2
  40. _samr_OemChangePasswordUser2
  41. _samr_ChangePasswordUser3
  42. make_samr_lookup_rids
  43. _samr_LookupRids
  44. _samr_OpenUser
  45. init_samr_parameters_string
  46. get_user_info_1
  47. get_user_info_2
  48. get_user_info_3
  49. get_user_info_4
  50. get_user_info_5
  51. get_user_info_6
  52. get_user_info_7
  53. get_user_info_8
  54. get_user_info_9
  55. get_user_info_10
  56. get_user_info_11
  57. get_user_info_12
  58. get_user_info_13
  59. get_user_info_14
  60. get_user_info_16
  61. get_user_info_17
  62. get_user_info_18
  63. get_user_info_20
  64. get_user_info_21
  65. _samr_QueryUserInfo
  66. _samr_QueryUserInfo2
  67. _samr_GetGroupsForUser
  68. _samr_QueryDomainInfo
  69. can_create
  70. _samr_CreateUser2
  71. _samr_CreateUser
  72. _samr_Connect
  73. _samr_Connect2
  74. _samr_Connect3
  75. _samr_Connect4
  76. _samr_Connect5
  77. _samr_LookupDomain
  78. _samr_EnumDomains
  79. _samr_OpenAlias
  80. set_user_info_2
  81. set_user_info_4
  82. set_user_info_6
  83. set_user_info_7
  84. set_user_info_8
  85. set_user_info_10
  86. set_user_info_11
  87. set_user_info_12
  88. set_user_info_13
  89. set_user_info_14
  90. set_user_info_16
  91. set_user_info_17
  92. set_user_info_18
  93. set_user_info_20
  94. set_user_info_21
  95. set_user_info_23
  96. set_user_info_pw
  97. set_user_info_24
  98. set_user_info_25
  99. set_user_info_26
  100. samr_set_user_info_map_fields_to_access_mask
  101. _samr_SetUserInfo
  102. _samr_SetUserInfo2
  103. _samr_GetAliasMembership
  104. _samr_GetMembersInAlias
  105. _samr_QueryGroupMember
  106. _samr_AddAliasMember
  107. _samr_DeleteAliasMember
  108. _samr_AddGroupMember
  109. _samr_DeleteGroupMember
  110. _samr_DeleteUser
  111. _samr_DeleteDomainGroup
  112. _samr_DeleteDomAlias
  113. _samr_CreateDomainGroup
  114. _samr_CreateDomAlias
  115. _samr_QueryGroupInfo
  116. _samr_SetGroupInfo
  117. _samr_SetAliasInfo
  118. _samr_GetDomPwInfo
  119. _samr_OpenGroup
  120. _samr_RemoveMemberFromForeignDomain
  121. _samr_QueryDomainInfo2
  122. _samr_SetDomainInfo
  123. _samr_GetDisplayEnumerationIndex
  124. _samr_GetDisplayEnumerationIndex2
  125. _samr_RidToSid
  126. _samr_Shutdown
  127. _samr_SetMemberAttributesOfGroup
  128. _samr_TestPrivateFunctionsDomain
  129. _samr_TestPrivateFunctionsUser
  130. _samr_AddMultipleMembersToAlias
  131. _samr_RemoveMultipleMembersFromAlias
  132. _samr_SetBootKeyInformation
  133. _samr_GetBootKeyInformation
  134. _samr_SetDsrmPassword
  135. _samr_ValidatePassword

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

/* [<][>][^][v][top][bottom][index][help] */