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