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