r4904: sync up with 3.0 for 3.0.11pre2
[Samba.git] / source / rpc_server / srv_samr_nt.c
blob462a646329334a78be4369de91ff1dd2c6c4bb84
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-2002,
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,
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
32 #include "includes.h"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
44 typedef struct _disp_info {
45 BOOL user_dbloaded;
46 uint32 num_user_account;
47 SAM_ACCOUNT *disp_user_info;
48 BOOL group_dbloaded;
49 uint32 num_group_account;
50 DOMAIN_GRP *disp_group_info;
51 } DISP_INFO;
53 struct samr_info {
54 /* for use by the \PIPE\samr policy */
55 DOM_SID sid;
56 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
57 uint32 acc_granted;
58 uint16 acb_mask;
59 BOOL only_machines;
60 DISP_INFO disp_info;
62 TALLOC_CTX *mem_ctx;
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 static NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
79 uint32 *acc_granted, const char *debug)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
83 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84 *acc_granted = des_access;
85 if (geteuid() == sec_initial_uid()) {
86 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
87 debug, des_access));
88 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89 status = NT_STATUS_OK;
91 else {
92 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
93 debug, des_access));
96 return status;
99 /*******************************************************************
100 Checks if access to a function can be granted
101 ********************************************************************/
103 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
105 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
106 debug, acc_granted, acc_required));
107 if ((acc_granted & acc_required) != acc_required) {
108 if (geteuid() == sec_initial_uid()) {
109 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
110 debug, acc_granted, acc_required));
111 DEBUGADD(4,("but overwritten by euid == 0\n"));
112 return NT_STATUS_OK;
114 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
115 debug, acc_granted, acc_required));
116 return NT_STATUS_ACCESS_DENIED;
118 return NT_STATUS_OK;
122 /*******************************************************************
123 Create a samr_info struct.
124 ********************************************************************/
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
128 struct samr_info *info;
129 fstring sid_str;
130 TALLOC_CTX *mem_ctx;
132 if (psid) {
133 sid_to_string(sid_str, psid);
134 } else {
135 fstrcpy(sid_str,"(NULL)");
138 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
140 if ((info = TALLOC_P(mem_ctx, struct samr_info)) == NULL)
141 return NULL;
143 ZERO_STRUCTP(info);
144 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
145 if (psid) {
146 sid_copy( &info->sid, psid);
147 } else {
148 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
150 info->mem_ctx = mem_ctx;
151 return info;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
158 static void free_samr_users(struct samr_info *info)
160 int i;
162 if (info->disp_info.user_dbloaded){
163 for (i=0; i<info->disp_info.num_user_account; i++) {
164 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165 /* Not really a free, actually a 'clear' */
166 pdb_free_sam(&sam);
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
187 static void free_samr_info(void *ptr)
189 struct samr_info *info=(struct samr_info *) ptr;
191 free_samr_db(info);
192 talloc_destroy(info->mem_ctx);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
202 if (!sam_pass)
203 return;
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL only_machines)
214 SAM_ACCOUNT *pwd = NULL;
215 SAM_ACCOUNT *pwd_array = NULL;
216 NTSTATUS nt_status = NT_STATUS_OK;
217 TALLOC_CTX *mem_ctx = info->mem_ctx;
218 uint16 query_acb_mask = acb_mask;
220 DEBUG(10,("load_sampwd_entries\n"));
222 /* if the snapshoot is already loaded, return */
223 if ((info->disp_info.user_dbloaded==True)
224 && (info->acb_mask == acb_mask)
225 && (info->only_machines == only_machines)) {
226 DEBUG(10,("load_sampwd_entries: already in memory\n"));
227 return NT_STATUS_OK;
230 free_samr_users(info);
232 if (only_machines) {
233 query_acb_mask |= ACB_WSTRUST;
234 query_acb_mask |= ACB_SVRTRUST;
237 if (!pdb_setsampwent(False, query_acb_mask)) {
238 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
239 return NT_STATUS_ACCESS_DENIED;
242 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
243 && pdb_getsampwent(pwd) == True; pwd=NULL) {
245 if (only_machines) {
246 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
247 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
248 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
249 pdb_free_sam(&pwd);
250 continue;
252 } else {
253 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
254 pdb_free_sam(&pwd);
255 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
256 continue;
260 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
261 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
263 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
264 pwd_array=TALLOC_REALLOC_ARRAY(mem_ctx, info->disp_info.disp_user_info, SAM_ACCOUNT,
265 info->disp_info.num_user_account+MAX_SAM_ENTRIES);
267 if (pwd_array==NULL)
268 return NT_STATUS_NO_MEMORY;
270 info->disp_info.disp_user_info=pwd_array;
273 /* Copy the SAM_ACCOUNT into the array */
274 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
276 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
278 info->disp_info.num_user_account++;
281 pdb_endsampwent();
283 /* the snapshoot is in memory, we're ready to enumerate fast */
285 info->acb_mask = acb_mask;
286 info->only_machines = only_machines;
287 info->disp_info.user_dbloaded=True;
289 DEBUG(10,("load_sampwd_entries: done\n"));
291 return nt_status;
294 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
296 GROUP_MAP *map=NULL;
297 DOMAIN_GRP *grp_array = NULL;
298 uint32 group_entries = 0;
299 uint32 i;
300 TALLOC_CTX *mem_ctx = info->mem_ctx;
301 BOOL ret;
303 DEBUG(10,("load_group_domain_entries\n"));
305 /* if the snapshoot is already loaded, return */
306 if (info->disp_info.group_dbloaded==True) {
307 DEBUG(10,("load_group_domain_entries: already in memory\n"));
308 return NT_STATUS_OK;
311 if (sid_equal(sid, &global_sid_Builtin)) {
312 /* No domain groups for now in the BUILTIN domain */
313 info->disp_info.num_group_account=0;
314 info->disp_info.disp_group_info=NULL;
315 info->disp_info.group_dbloaded=True;
316 return NT_STATUS_OK;
319 become_root();
320 ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
321 unbecome_root();
323 if ( !ret ) {
324 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
325 return NT_STATUS_NO_MEMORY;
329 info->disp_info.num_group_account=group_entries;
331 grp_array=TALLOC_ARRAY(mem_ctx, DOMAIN_GRP, info->disp_info.num_group_account);
332 if (group_entries!=0 && grp_array==NULL) {
333 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
334 SAFE_FREE(map);
335 return NT_STATUS_NO_MEMORY;
338 info->disp_info.disp_group_info=grp_array;
340 for (i=0; i<group_entries; i++) {
341 fstrcpy(grp_array[i].name, map[i].nt_name);
342 fstrcpy(grp_array[i].comment, map[i].comment);
343 sid_split_rid(&map[i].sid, &grp_array[i].rid);
344 grp_array[i].attr=SID_NAME_DOM_GRP;
347 SAFE_FREE(map);
349 /* the snapshoot is in memory, we're ready to enumerate fast */
351 info->disp_info.group_dbloaded=True;
353 DEBUG(10,("load_group_domain_entries: done\n"));
355 return NT_STATUS_OK;
359 /*******************************************************************
360 _samr_close_hnd
361 ********************************************************************/
363 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
365 r_u->status = NT_STATUS_OK;
367 /* close the policy handle */
368 if (!close_policy_hnd(p, &q_u->pol))
369 return NT_STATUS_OBJECT_NAME_INVALID;
371 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
373 return r_u->status;
376 /*******************************************************************
377 samr_reply_open_domain
378 ********************************************************************/
380 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
382 struct samr_info *info;
383 SEC_DESC *psd = NULL;
384 uint32 acc_granted;
385 uint32 des_access = q_u->flags;
386 size_t sd_size;
387 NTSTATUS status;
389 r_u->status = NT_STATUS_OK;
391 /* find the connection policy handle. */
392 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
393 return NT_STATUS_INVALID_HANDLE;
395 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
396 return status;
399 /*check if access can be granted as requested by client. */
400 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
401 se_map_generic(&des_access,&dom_generic_mapping);
403 if (!NT_STATUS_IS_OK(status =
404 access_check_samr_object(psd, p->pipe_user.nt_user_token,
405 des_access, &acc_granted, "_samr_open_domain"))) {
406 return status;
409 /* associate the domain SID with the (unique) handle. */
410 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
411 return NT_STATUS_NO_MEMORY;
412 info->acc_granted = acc_granted;
414 /* get a (unique) handle. open a policy on it. */
415 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
416 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
418 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
420 return r_u->status;
423 /*******************************************************************
424 _samr_get_usrdom_pwinfo
425 ********************************************************************/
427 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
429 struct samr_info *info = NULL;
431 r_u->status = NT_STATUS_OK;
433 /* find the policy handle. open a policy on it. */
434 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
435 return NT_STATUS_INVALID_HANDLE;
437 if (!sid_check_is_in_our_domain(&info->sid))
438 return NT_STATUS_OBJECT_TYPE_MISMATCH;
440 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
442 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
445 * NT sometimes return NT_STATUS_ACCESS_DENIED
446 * I don't know yet why.
449 return r_u->status;
452 /*******************************************************************
453 samr_make_dom_obj_sd
454 ********************************************************************/
456 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
458 extern DOM_SID global_sid_World;
459 DOM_SID adm_sid, act_sid, domadmin_sid;
460 SEC_ACE ace[4];
461 SEC_ACCESS mask;
462 size_t i = 0;
464 SEC_ACL *psa = NULL;
466 sid_copy(&adm_sid, &global_sid_Builtin);
467 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
469 sid_copy(&act_sid, &global_sid_Builtin);
470 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
472 /*basic access for every one*/
473 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
474 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
476 /*full access for builtin aliases Administrators and Account Operators*/
478 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
480 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
481 init_sec_ace(&ace[i++], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
483 /* add domain admins if we are a DC */
485 if ( IS_DC ) {
486 sid_copy( &domadmin_sid, get_global_sam_sid() );
487 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
488 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
491 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
492 return NT_STATUS_NO_MEMORY;
494 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
495 return NT_STATUS_NO_MEMORY;
497 return NT_STATUS_OK;
500 /*******************************************************************
501 samr_make_usr_obj_sd
502 ********************************************************************/
504 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
506 extern DOM_SID global_sid_World;
507 DOM_SID adm_sid, act_sid, domadmin_sid;
508 size_t i = 0;
510 SEC_ACE ace[5];
511 SEC_ACCESS mask;
513 SEC_ACL *psa = NULL;
515 sid_copy(&adm_sid, &global_sid_Builtin);
516 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
518 sid_copy(&act_sid, &global_sid_Builtin);
519 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
521 /*basic access for every one*/
523 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
524 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
526 /*full access for builtin aliases Administrators and Account Operators*/
528 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
529 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
530 init_sec_ace(&ace[i++], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
532 /* add domain admins if we are a DC */
534 if ( IS_DC ) {
535 sid_copy( &domadmin_sid, get_global_sam_sid() );
536 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
537 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
540 /*extended access for the user*/
542 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
543 init_sec_ace(&ace[i++], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
545 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
546 return NT_STATUS_NO_MEMORY;
548 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
549 return NT_STATUS_NO_MEMORY;
551 return NT_STATUS_OK;
554 /*******************************************************************
555 samr_make_grp_obj_sd
556 ********************************************************************/
558 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
560 extern DOM_SID global_sid_World;
561 DOM_SID adm_sid;
562 DOM_SID act_sid;
564 SEC_ACE ace[3];
565 SEC_ACCESS mask;
567 SEC_ACL *psa = NULL;
569 sid_copy(&adm_sid, &global_sid_Builtin);
570 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
572 sid_copy(&act_sid, &global_sid_Builtin);
573 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
575 /*basic access for every one*/
576 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
577 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
579 /*full access for builtin aliases Administrators and Account Operators*/
580 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
581 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
582 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
584 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
585 return NT_STATUS_NO_MEMORY;
587 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
588 return NT_STATUS_NO_MEMORY;
590 return NT_STATUS_OK;
593 /*******************************************************************
594 samr_make_ali_obj_sd
595 ********************************************************************/
597 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
599 extern DOM_SID global_sid_World;
600 DOM_SID adm_sid;
601 DOM_SID act_sid;
603 SEC_ACE ace[3];
604 SEC_ACCESS mask;
606 SEC_ACL *psa = NULL;
608 sid_copy(&adm_sid, &global_sid_Builtin);
609 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
611 sid_copy(&act_sid, &global_sid_Builtin);
612 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
614 /*basic access for every one*/
615 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
616 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
618 /*full access for builtin aliases Administrators and Account Operators*/
619 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
620 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
621 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
623 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
624 return NT_STATUS_NO_MEMORY;
626 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
627 return NT_STATUS_NO_MEMORY;
629 return NT_STATUS_OK;
632 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
634 struct samr_info *info = NULL;
636 /* find the policy handle. open a policy on it. */
637 if (!find_policy_by_hnd(p, pol, (void **)&info))
638 return False;
640 if (!info)
641 return False;
643 *sid = info->sid;
644 *acc_granted = info->acc_granted;
645 return True;
648 /*******************************************************************
649 _samr_set_sec_obj
650 ********************************************************************/
652 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
654 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
655 return NT_STATUS_NOT_IMPLEMENTED;
659 /*******************************************************************
660 _samr_query_sec_obj
661 ********************************************************************/
663 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
665 DOM_SID pol_sid;
666 fstring str_sid;
667 SEC_DESC * psd = NULL;
668 size_t sd_size;
669 uint32 acc_granted;
671 r_u->status = NT_STATUS_OK;
673 /* Get the SID. */
674 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
675 return NT_STATUS_INVALID_HANDLE;
679 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
681 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
683 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
684 if (pol_sid.sid_rev_num == 0)
686 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
687 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
689 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
692 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
693 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
695 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
697 /* TODO: Builtin probably needs a different SD with restricted write access*/
698 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
699 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
701 else if (sid_check_is_in_our_domain(&pol_sid) ||
702 sid_check_is_in_builtin(&pol_sid))
704 /* TODO: different SDs have to be generated for aliases groups and users.
705 Currently all three get a default user SD */
706 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
707 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
709 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
711 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
712 return NT_STATUS_NO_MEMORY;
714 if (NT_STATUS_IS_OK(r_u->status))
715 r_u->ptr = 1;
717 return r_u->status;
720 /*******************************************************************
721 makes a SAM_ENTRY / UNISTR2* structure from a user list.
722 ********************************************************************/
724 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
725 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
726 DOM_SID *domain_sid)
728 uint32 i;
729 SAM_ENTRY *sam;
730 UNISTR2 *uni_name;
731 SAM_ACCOUNT *pwd = NULL;
732 UNISTR2 uni_temp_name;
733 const char *temp_name;
734 const DOM_SID *user_sid;
735 uint32 user_rid;
736 fstring user_sid_string;
737 fstring domain_sid_string;
739 *sam_pp = NULL;
740 *uni_name_pp = NULL;
742 if (num_entries == 0)
743 return NT_STATUS_OK;
745 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries);
747 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_entries);
749 if (sam == NULL || uni_name == NULL) {
750 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
751 return NT_STATUS_NO_MEMORY;
754 for (i = 0; i < num_entries; i++) {
755 pwd = &disp_user_info[i+start_idx];
756 temp_name = pdb_get_username(pwd);
759 * usrmgr expects a non-NULL terminated string with
760 * trust relationships
762 if (pdb_get_acct_ctrl(pwd) & ACB_DOMTRUST) {
763 init_unistr2(&uni_temp_name, temp_name, UNI_FLAGS_NONE);
764 } else {
765 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
768 user_sid = pdb_get_user_sid(pwd);
770 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
771 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
772 "the domain sid %s. Failing operation.\n",
773 temp_name,
774 sid_to_string(user_sid_string, user_sid),
775 sid_to_string(domain_sid_string, domain_sid)));
776 return NT_STATUS_UNSUCCESSFUL;
779 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
780 copy_unistr2(&uni_name[i], &uni_temp_name);
783 *sam_pp = sam;
784 *uni_name_pp = uni_name;
785 return NT_STATUS_OK;
788 /*******************************************************************
789 samr_reply_enum_dom_users
790 ********************************************************************/
792 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
793 SAMR_R_ENUM_DOM_USERS *r_u)
795 struct samr_info *info = NULL;
796 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
797 int num_account;
798 uint32 enum_context=q_u->start_idx;
799 uint32 max_size=q_u->max_size;
800 uint32 temp_size;
801 enum remote_arch_types ra_type = get_remote_arch();
802 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
803 uint32 max_entries = max_sam_entries;
804 DOM_SID domain_sid;
806 r_u->status = NT_STATUS_OK;
808 /* find the policy handle. open a policy on it. */
809 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
810 return NT_STATUS_INVALID_HANDLE;
812 domain_sid = info->sid;
814 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
815 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
816 "_samr_enum_dom_users"))) {
817 return r_u->status;
820 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
822 become_root();
823 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
824 unbecome_root();
826 if (!NT_STATUS_IS_OK(r_u->status))
827 return r_u->status;
829 num_account = info->disp_info.num_user_account;
831 if (enum_context > num_account) {
832 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
833 return NT_STATUS_OK;
836 /* verify we won't overflow */
837 if (max_entries > num_account-enum_context) {
838 max_entries = num_account-enum_context;
839 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
842 /* calculate the size and limit on the number of entries we will return */
843 temp_size=max_entries*struct_size;
845 if (temp_size>max_size) {
846 max_entries=MIN((max_size/struct_size),max_entries);;
847 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
851 * Note from JRA. total_entries is not being used here. Currently if there is a
852 * large user base then it looks like NT will enumerate until get_sampwd_entries
853 * returns False due to num_entries being zero. This will cause an access denied
854 * return. I don't think this is right and needs further investigation. Note that
855 * this is also the same in the TNG code (I don't think that has been tested with
856 * a very large user list as MAX_SAM_ENTRIES is set to 600).
858 * I also think that one of the 'num_entries' return parameters is probably
859 * the "max entries" parameter - but in the TNG code they're all currently set to the same
860 * value (again I think this is wrong).
863 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
864 max_entries, enum_context,
865 info->disp_info.disp_user_info,
866 &domain_sid);
868 if (!NT_STATUS_IS_OK(r_u->status))
869 return r_u->status;
871 if (enum_context+max_entries < num_account)
872 r_u->status = STATUS_MORE_ENTRIES;
874 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
876 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
878 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
880 return r_u->status;
883 /*******************************************************************
884 makes a SAM_ENTRY / UNISTR2* structure from a group list.
885 ********************************************************************/
887 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
888 uint32 num_sam_entries, DOMAIN_GRP *grp)
890 uint32 i;
891 SAM_ENTRY *sam;
892 UNISTR2 *uni_name;
894 *sam_pp = NULL;
895 *uni_name_pp = NULL;
897 if (num_sam_entries == 0)
898 return;
900 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
901 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
903 if (sam == NULL || uni_name == NULL) {
904 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
905 return;
908 for (i = 0; i < num_sam_entries; i++) {
910 * JRA. I think this should include the null. TNG does not.
912 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
913 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
916 *sam_pp = sam;
917 *uni_name_pp = uni_name;
920 /*******************************************************************
921 Get the group entries - similar to get_sampwd_entries().
922 ******************************************************************/
924 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
925 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
926 uint32 *p_num_entries, uint32 max_entries )
928 GROUP_MAP *map=NULL;
929 int i;
930 uint32 group_entries = 0;
931 uint32 num_entries = 0;
933 *p_num_entries = 0;
935 /* access checks for the users were performed higher up. become/unbecome_root()
936 needed for some passdb backends to enumerate groups */
938 become_root();
939 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
940 ENUM_ONLY_MAPPED);
941 unbecome_root();
943 num_entries=group_entries-start_idx;
945 /* limit the number of entries */
946 if (num_entries>max_entries) {
947 DEBUG(5,("Limiting to %d entries\n", max_entries));
948 num_entries=max_entries;
951 *d_grp=TALLOC_ZERO_ARRAY(ctx, DOMAIN_GRP, num_entries);
952 if (num_entries!=0 && *d_grp==NULL){
953 SAFE_FREE(map);
954 return NT_STATUS_NO_MEMORY;
957 for (i=0; i<num_entries; i++) {
958 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
959 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
960 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
961 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
964 SAFE_FREE(map);
966 *p_num_entries = num_entries;
968 DEBUG(10,("get_group_domain_entries: returning %d entries\n",
969 *p_num_entries));
971 return NT_STATUS_OK;
974 /*******************************************************************
975 Wrapper for enumerating local groups
976 ******************************************************************/
978 static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
979 const DOM_SID *sid, uint32 start_idx,
980 uint32 *p_num_entries, uint32 max_entries )
982 struct acct_info *info;
983 int i;
984 BOOL res;
986 become_root();
987 res = pdb_enum_aliases(sid, start_idx, max_entries,
988 p_num_entries, &info);
989 unbecome_root();
991 if (!res)
992 return NT_STATUS_ACCESS_DENIED;
994 if (*p_num_entries == 0)
995 return NT_STATUS_OK;
997 *d_grp = TALLOC_ARRAY(ctx, DOMAIN_GRP, *p_num_entries);
999 if (*d_grp == NULL) {
1000 SAFE_FREE(info);
1001 return NT_STATUS_NO_MEMORY;
1004 for (i=0; i<*p_num_entries; i++) {
1005 fstrcpy((*d_grp)[i].name, info[i].acct_name);
1006 fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
1007 (*d_grp)[i].rid = info[i].rid;
1008 (*d_grp)[i].attr = SID_NAME_ALIAS;
1011 SAFE_FREE(info);
1012 return NT_STATUS_OK;
1015 /*******************************************************************
1016 samr_reply_enum_dom_groups
1017 ********************************************************************/
1019 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1021 DOMAIN_GRP *grp=NULL;
1022 uint32 num_entries;
1023 DOM_SID sid;
1024 uint32 acc_granted;
1026 r_u->status = NT_STATUS_OK;
1028 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1029 return NT_STATUS_INVALID_HANDLE;
1031 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1032 return r_u->status;
1035 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1037 /* the domain group array is being allocated in the function below */
1038 if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
1039 return r_u->status;
1042 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1044 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1046 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1048 return r_u->status;
1052 /*******************************************************************
1053 samr_reply_enum_dom_aliases
1054 ********************************************************************/
1056 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1058 DOMAIN_GRP *grp=NULL;
1059 uint32 num_entries = 0;
1060 fstring sid_str;
1061 DOM_SID sid;
1062 NTSTATUS status;
1063 uint32 acc_granted;
1065 r_u->status = NT_STATUS_OK;
1067 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1068 return NT_STATUS_INVALID_HANDLE;
1070 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1071 return r_u->status;
1074 sid_to_string(sid_str, &sid);
1075 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1077 status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1078 &num_entries, MAX_SAM_ENTRIES);
1079 if (!NT_STATUS_IS_OK(status)) return status;
1081 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1083 /*safe_free(grp);*/
1085 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1087 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1089 return r_u->status;
1092 /*******************************************************************
1093 samr_reply_query_dispinfo
1094 ********************************************************************/
1096 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1097 SAMR_R_QUERY_DISPINFO *r_u)
1099 struct samr_info *info = NULL;
1100 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1102 uint32 max_entries=q_u->max_entries;
1103 uint32 enum_context=q_u->start_idx;
1104 uint32 max_size=q_u->max_size;
1106 SAM_DISPINFO_CTR *ctr;
1107 uint32 temp_size=0, total_data_size=0;
1108 NTSTATUS disp_ret;
1109 uint32 num_account = 0;
1110 enum remote_arch_types ra_type = get_remote_arch();
1111 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1112 DOM_SID domain_sid;
1114 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1115 r_u->status = NT_STATUS_OK;
1117 /* find the policy handle. open a policy on it. */
1118 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1119 return NT_STATUS_INVALID_HANDLE;
1121 domain_sid = info->sid;
1124 * calculate how many entries we will return.
1125 * based on
1126 * - the number of entries the client asked
1127 * - our limit on that
1128 * - the starting point (enumeration context)
1129 * - the buffer size the client will accept
1133 * We are a lot more like W2K. Instead of reading the SAM
1134 * each time to find the records we need to send back,
1135 * we read it once and link that copy to the sam handle.
1136 * For large user list (over the MAX_SAM_ENTRIES)
1137 * it's a definitive win.
1138 * second point to notice: between enumerations
1139 * our sam is now the same as it's a snapshoot.
1140 * third point: got rid of the static SAM_USER_21 struct
1141 * no more intermediate.
1142 * con: it uses much more memory, as a full copy is stored
1143 * in memory.
1145 * If you want to change it, think twice and think
1146 * of the second point , that's really important.
1148 * JFM, 12/20/2001
1151 /* Get what we need from the password database */
1152 switch (q_u->switch_level) {
1153 case 0x1:
1154 /* When playing with usrmgr, this is necessary
1155 if you want immediate refresh after editing
1156 a user. I would like to do this after the
1157 setuserinfo2, but we do not have access to
1158 the domain handle in that call, only to the
1159 user handle. Where else does this hurt?
1160 -- Volker
1162 #if 0
1163 /* We cannot do this here - it kills performace. JRA. */
1164 free_samr_users(info);
1165 #endif
1166 case 0x2:
1167 case 0x4:
1168 become_root();
1169 /* Level 2 is for all machines, otherwise only 'normal' users */
1170 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1171 unbecome_root();
1172 if (!NT_STATUS_IS_OK(r_u->status)) {
1173 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1174 return r_u->status;
1176 num_account = info->disp_info.num_user_account;
1177 break;
1178 case 0x3:
1179 case 0x5:
1180 r_u->status = load_group_domain_entries(info, &info->sid);
1181 if (!NT_STATUS_IS_OK(r_u->status))
1182 return r_u->status;
1183 num_account = info->disp_info.num_group_account;
1184 break;
1185 default:
1186 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1187 return NT_STATUS_INVALID_INFO_CLASS;
1190 /* first limit the number of entries we will return */
1191 if(max_entries > max_sam_entries) {
1192 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1193 max_entries = max_sam_entries;
1196 if (enum_context > num_account) {
1197 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1198 return NT_STATUS_NO_MORE_ENTRIES;
1201 /* verify we won't overflow */
1202 if (max_entries > num_account-enum_context) {
1203 max_entries = num_account-enum_context;
1204 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1207 /* calculate the size and limit on the number of entries we will return */
1208 temp_size=max_entries*struct_size;
1210 if (temp_size>max_size) {
1211 max_entries=MIN((max_size/struct_size),max_entries);;
1212 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1215 if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
1216 return NT_STATUS_NO_MEMORY;
1218 ZERO_STRUCTP(ctr);
1220 /* Now create reply structure */
1221 switch (q_u->switch_level) {
1222 case 0x1:
1223 if (max_entries) {
1224 if (!(ctr->sam.info1 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_1,max_entries)))
1225 return NT_STATUS_NO_MEMORY;
1227 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1228 info->disp_info.disp_user_info, &domain_sid);
1229 if (!NT_STATUS_IS_OK(disp_ret))
1230 return disp_ret;
1231 break;
1232 case 0x2:
1233 if (max_entries) {
1234 if (!(ctr->sam.info2 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_2,max_entries)))
1235 return NT_STATUS_NO_MEMORY;
1237 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1238 info->disp_info.disp_user_info, &domain_sid);
1239 if (!NT_STATUS_IS_OK(disp_ret))
1240 return disp_ret;
1241 break;
1242 case 0x3:
1243 if (max_entries) {
1244 if (!(ctr->sam.info3 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_3,max_entries)))
1245 return NT_STATUS_NO_MEMORY;
1247 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1248 if (!NT_STATUS_IS_OK(disp_ret))
1249 return disp_ret;
1250 break;
1251 case 0x4:
1252 if (max_entries) {
1253 if (!(ctr->sam.info4 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_4,max_entries)))
1254 return NT_STATUS_NO_MEMORY;
1256 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1257 if (!NT_STATUS_IS_OK(disp_ret))
1258 return disp_ret;
1259 break;
1260 case 0x5:
1261 if (max_entries) {
1262 if (!(ctr->sam.info5 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_5,max_entries)))
1263 return NT_STATUS_NO_MEMORY;
1265 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1266 if (!NT_STATUS_IS_OK(disp_ret))
1267 return disp_ret;
1268 break;
1270 default:
1271 ctr->sam.info = NULL;
1272 return NT_STATUS_INVALID_INFO_CLASS;
1275 /* calculate the total size */
1276 total_data_size=num_account*struct_size;
1278 if (enum_context+max_entries < num_account)
1279 r_u->status = STATUS_MORE_ENTRIES;
1281 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1283 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1285 return r_u->status;
1289 /*******************************************************************
1290 samr_reply_query_aliasinfo
1291 ********************************************************************/
1293 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1295 DOM_SID sid;
1296 struct acct_info info;
1297 uint32 acc_granted;
1298 BOOL ret;
1300 r_u->status = NT_STATUS_OK;
1302 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1304 /* find the policy handle. open a policy on it. */
1305 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1306 return NT_STATUS_INVALID_HANDLE;
1307 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1308 return r_u->status;
1311 become_root();
1312 ret = pdb_get_aliasinfo(&sid, &info);
1313 unbecome_root();
1315 if ( !ret )
1316 return NT_STATUS_NO_SUCH_ALIAS;
1318 switch (q_u->switch_level) {
1319 case 1:
1320 r_u->ptr = 1;
1321 r_u->ctr.switch_value1 = 1;
1322 init_samr_alias_info1(&r_u->ctr.alias.info1,
1323 info.acct_name, 1, info.acct_desc);
1324 break;
1325 case 3:
1326 r_u->ptr = 1;
1327 r_u->ctr.switch_value1 = 3;
1328 init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1329 break;
1330 default:
1331 return NT_STATUS_INVALID_INFO_CLASS;
1334 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1336 return r_u->status;
1339 #if 0
1340 /*******************************************************************
1341 samr_reply_lookup_ids
1342 ********************************************************************/
1344 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1346 uint32 rid[MAX_SAM_ENTRIES];
1347 int num_rids = q_u->num_sids1;
1349 r_u->status = NT_STATUS_OK;
1351 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1353 if (num_rids > MAX_SAM_ENTRIES) {
1354 num_rids = MAX_SAM_ENTRIES;
1355 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1358 #if 0
1359 int i;
1360 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1362 for (i = 0; i < num_rids && status == 0; i++)
1364 struct sam_passwd *sam_pass;
1365 fstring user_name;
1368 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1369 q_u->uni_user_name[i].uni_str_len));
1371 /* find the user account */
1372 become_root();
1373 sam_pass = get_smb21pwd_entry(user_name, 0);
1374 unbecome_root();
1376 if (sam_pass == NULL)
1378 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1379 rid[i] = 0;
1381 else
1383 rid[i] = sam_pass->user_rid;
1386 #endif
1388 num_rids = 1;
1389 rid[0] = BUILTIN_ALIAS_RID_USERS;
1391 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1393 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1395 return r_u->status;
1397 #endif
1399 /*******************************************************************
1400 _samr_lookup_names
1401 ********************************************************************/
1403 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1405 uint32 rid[MAX_SAM_ENTRIES];
1406 uint32 local_rid;
1407 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1408 enum SID_NAME_USE local_type;
1409 int i;
1410 int num_rids = q_u->num_names2;
1411 DOM_SID pol_sid;
1412 fstring sid_str;
1413 uint32 acc_granted;
1415 r_u->status = NT_STATUS_OK;
1417 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1419 ZERO_ARRAY(rid);
1420 ZERO_ARRAY(type);
1422 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1423 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1424 return r_u->status;
1427 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1428 return r_u->status;
1431 if (num_rids > MAX_SAM_ENTRIES) {
1432 num_rids = MAX_SAM_ENTRIES;
1433 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1436 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1438 for (i = 0; i < num_rids; i++) {
1439 fstring name;
1440 DOM_SID sid;
1441 int ret;
1443 r_u->status = NT_STATUS_NONE_MAPPED;
1445 rid [i] = 0xffffffff;
1446 type[i] = SID_NAME_UNKNOWN;
1448 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1451 * we are only looking for a name
1452 * the SID we get back can be outside
1453 * the scope of the pol_sid
1455 * in clear: it prevents to reply to domain\group: yes
1456 * when only builtin\group exists.
1458 * a cleaner code is to add the sid of the domain we're looking in
1459 * to the local_lookup_name function.
1462 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1463 sid_split_rid(&sid, &local_rid);
1465 if (sid_equal(&sid, &pol_sid)) {
1466 rid[i]=local_rid;
1468 /* Windows does not return WKN_GRP here, even
1469 * on lookups in builtin */
1470 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1471 SID_NAME_ALIAS : local_type;
1473 r_u->status = NT_STATUS_OK;
1478 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1480 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1482 return r_u->status;
1485 /*******************************************************************
1486 _samr_chgpasswd_user
1487 ********************************************************************/
1489 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1491 fstring user_name;
1492 fstring wks;
1494 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1496 r_u->status = NT_STATUS_OK;
1498 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1499 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1501 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1504 * Pass the user through the NT -> unix user mapping
1505 * function.
1508 (void)map_username(user_name);
1511 * UNIX username case mangling not required, pass_oem_change
1512 * is case insensitive.
1515 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1516 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1518 init_samr_r_chgpasswd_user(r_u, r_u->status);
1520 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1522 return r_u->status;
1525 /*******************************************************************
1526 makes a SAMR_R_LOOKUP_RIDS structure.
1527 ********************************************************************/
1529 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1530 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1532 uint32 i;
1533 UNIHDR *hdr_name=NULL;
1534 UNISTR2 *uni_name=NULL;
1536 *pp_uni_name = NULL;
1537 *pp_hdr_name = NULL;
1539 if (num_names != 0) {
1540 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1541 if (hdr_name == NULL)
1542 return False;
1544 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1545 if (uni_name == NULL)
1546 return False;
1549 for (i = 0; i < num_names; i++) {
1550 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1551 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1552 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1555 *pp_uni_name = uni_name;
1556 *pp_hdr_name = hdr_name;
1558 return True;
1561 /*******************************************************************
1562 _samr_lookup_rids
1563 ********************************************************************/
1565 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1567 fstring group_names[MAX_SAM_ENTRIES];
1568 uint32 *group_attrs = NULL;
1569 UNIHDR *hdr_name = NULL;
1570 UNISTR2 *uni_name = NULL;
1571 DOM_SID pol_sid;
1572 int num_rids = q_u->num_rids1;
1573 int i;
1574 uint32 acc_granted;
1576 r_u->status = NT_STATUS_OK;
1578 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1580 /* find the policy handle. open a policy on it. */
1581 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1582 return NT_STATUS_INVALID_HANDLE;
1584 if (num_rids > MAX_SAM_ENTRIES) {
1585 num_rids = MAX_SAM_ENTRIES;
1586 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1589 if (num_rids) {
1590 if ((group_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids )) == NULL)
1591 return NT_STATUS_NO_MEMORY;
1594 r_u->status = NT_STATUS_NONE_MAPPED;
1596 become_root(); /* lookup_sid can require root privs */
1598 for (i = 0; i < num_rids; i++) {
1599 fstring tmpname;
1600 fstring domname;
1601 DOM_SID sid;
1602 enum SID_NAME_USE type;
1604 group_attrs[i] = SID_NAME_UNKNOWN;
1605 *group_names[i] = '\0';
1607 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1608 sid_copy(&sid, &pol_sid);
1609 sid_append_rid(&sid, q_u->rid[i]);
1611 if (lookup_sid(&sid, domname, tmpname, &type)) {
1612 r_u->status = NT_STATUS_OK;
1613 group_attrs[i] = (uint32)type;
1614 fstrcpy(group_names[i],tmpname);
1615 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1620 unbecome_root();
1622 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1623 return NT_STATUS_NO_MEMORY;
1625 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1627 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1629 return r_u->status;
1632 /*******************************************************************
1633 _samr_open_user. Safe - gives out no passwd info.
1634 ********************************************************************/
1636 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1638 SAM_ACCOUNT *sampass=NULL;
1639 DOM_SID sid;
1640 POLICY_HND domain_pol = q_u->domain_pol;
1641 POLICY_HND *user_pol = &r_u->user_pol;
1642 struct samr_info *info = NULL;
1643 SEC_DESC *psd = NULL;
1644 uint32 acc_granted;
1645 uint32 des_access = q_u->access_mask;
1646 size_t sd_size;
1647 BOOL ret;
1648 NTSTATUS nt_status;
1650 r_u->status = NT_STATUS_OK;
1652 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1653 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1654 return NT_STATUS_INVALID_HANDLE;
1656 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1657 return nt_status;
1660 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1661 if (!NT_STATUS_IS_OK(nt_status)) {
1662 return nt_status;
1665 /* append the user's RID to it */
1666 if (!sid_append_rid(&sid, q_u->user_rid))
1667 return NT_STATUS_NO_SUCH_USER;
1669 /* check if access can be granted as requested by client. */
1670 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1671 se_map_generic(&des_access, &usr_generic_mapping);
1672 if (!NT_STATUS_IS_OK(nt_status =
1673 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1674 des_access, &acc_granted, "_samr_open_user"))) {
1675 return nt_status;
1678 become_root();
1679 ret=pdb_getsampwsid(sampass, &sid);
1680 unbecome_root();
1682 /* check that the SID exists in our domain. */
1683 if (ret == False) {
1684 return NT_STATUS_NO_SUCH_USER;
1687 pdb_free_sam(&sampass);
1689 /* associate the user's SID and access bits with the new handle. */
1690 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1691 return NT_STATUS_NO_MEMORY;
1692 info->acc_granted = acc_granted;
1694 /* get a (unique) handle. open a policy on it. */
1695 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1696 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1698 return r_u->status;
1701 /*************************************************************************
1702 get_user_info_10. Safe. Only gives out acb bits.
1703 *************************************************************************/
1705 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1707 SAM_ACCOUNT *smbpass=NULL;
1708 BOOL ret;
1709 NTSTATUS nt_status;
1711 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1713 if (!NT_STATUS_IS_OK(nt_status)) {
1714 return nt_status;
1717 become_root();
1718 ret = pdb_getsampwsid(smbpass, user_sid);
1719 unbecome_root();
1721 if (ret==False) {
1722 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1723 return NT_STATUS_NO_SUCH_USER;
1726 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1728 ZERO_STRUCTP(id10);
1729 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1731 pdb_free_sam(&smbpass);
1733 return NT_STATUS_OK;
1736 /*************************************************************************
1737 get_user_info_12. OK - this is the killer as it gives out password info.
1738 Ensure that this is only allowed on an encrypted connection with a root
1739 user. JRA.
1740 *************************************************************************/
1742 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1744 SAM_ACCOUNT *smbpass=NULL;
1745 BOOL ret;
1746 NTSTATUS nt_status;
1748 if (!p->ntlmssp_auth_validated)
1749 return NT_STATUS_ACCESS_DENIED;
1751 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1752 return NT_STATUS_ACCESS_DENIED;
1755 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1758 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1760 if (!NT_STATUS_IS_OK(nt_status)) {
1761 return nt_status;
1764 ret = pdb_getsampwsid(smbpass, user_sid);
1766 if (ret == False) {
1767 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1768 pdb_free_sam(&smbpass);
1769 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1772 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1774 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1775 pdb_free_sam(&smbpass);
1776 return NT_STATUS_ACCOUNT_DISABLED;
1779 ZERO_STRUCTP(id12);
1780 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1782 pdb_free_sam(&smbpass);
1784 return NT_STATUS_OK;
1787 /*************************************************************************
1788 get_user_info_20
1789 *************************************************************************/
1791 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1793 SAM_ACCOUNT *sampass=NULL;
1794 BOOL ret;
1796 pdb_init_sam_talloc(mem_ctx, &sampass);
1798 become_root();
1799 ret = pdb_getsampwsid(sampass, user_sid);
1800 unbecome_root();
1802 if (ret == False) {
1803 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1804 return NT_STATUS_NO_SUCH_USER;
1807 samr_clear_sam_passwd(sampass);
1809 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1811 ZERO_STRUCTP(id20);
1812 init_sam_user_info20A(id20, sampass);
1814 pdb_free_sam(&sampass);
1816 return NT_STATUS_OK;
1819 /*************************************************************************
1820 get_user_info_21
1821 *************************************************************************/
1823 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1824 DOM_SID *user_sid, DOM_SID *domain_sid)
1826 SAM_ACCOUNT *sampass=NULL;
1827 BOOL ret;
1828 NTSTATUS nt_status;
1830 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1831 if (!NT_STATUS_IS_OK(nt_status)) {
1832 return nt_status;
1835 become_root();
1836 ret = pdb_getsampwsid(sampass, user_sid);
1837 unbecome_root();
1839 if (ret == False) {
1840 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1841 return NT_STATUS_NO_SUCH_USER;
1844 samr_clear_sam_passwd(sampass);
1846 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1848 ZERO_STRUCTP(id21);
1849 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1851 pdb_free_sam(&sampass);
1853 return NT_STATUS_OK;
1856 /*******************************************************************
1857 _samr_query_userinfo
1858 ********************************************************************/
1860 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1862 SAM_USERINFO_CTR *ctr;
1863 struct samr_info *info = NULL;
1864 DOM_SID domain_sid;
1865 uint32 rid;
1867 r_u->status=NT_STATUS_OK;
1869 /* search for the handle */
1870 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1871 return NT_STATUS_INVALID_HANDLE;
1873 domain_sid = info->sid;
1875 sid_split_rid(&domain_sid, &rid);
1877 if (!sid_check_is_in_our_domain(&info->sid))
1878 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1880 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1882 ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
1883 if (!ctr)
1884 return NT_STATUS_NO_MEMORY;
1886 ZERO_STRUCTP(ctr);
1888 /* ok! user info levels (lots: see MSDEV help), off we go... */
1889 ctr->switch_value = q_u->switch_value;
1891 switch (q_u->switch_value) {
1892 case 0x10:
1893 ctr->info.id10 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_10);
1894 if (ctr->info.id10 == NULL)
1895 return NT_STATUS_NO_MEMORY;
1897 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1898 return r_u->status;
1899 break;
1901 #if 0
1902 /* whoops - got this wrong. i think. or don't understand what's happening. */
1903 case 0x11:
1905 NTTIME expire;
1906 info = (void *)&id11;
1908 expire.low = 0xffffffff;
1909 expire.high = 0x7fffffff;
1911 ctr->info.id = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_11));
1912 ZERO_STRUCTP(ctr->info.id11);
1913 init_sam_user_info11(ctr->info.id11, &expire,
1914 "BROOKFIELDS$", /* name */
1915 0x03ef, /* user rid */
1916 0x201, /* group rid */
1917 0x0080); /* acb info */
1919 break;
1921 #endif
1923 case 0x12:
1924 ctr->info.id12 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_12);
1925 if (ctr->info.id12 == NULL)
1926 return NT_STATUS_NO_MEMORY;
1928 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1929 return r_u->status;
1930 break;
1932 case 20:
1933 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
1934 if (ctr->info.id20 == NULL)
1935 return NT_STATUS_NO_MEMORY;
1936 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1937 return r_u->status;
1938 break;
1940 case 21:
1941 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
1942 if (ctr->info.id21 == NULL)
1943 return NT_STATUS_NO_MEMORY;
1944 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1945 &info->sid, &domain_sid)))
1946 return r_u->status;
1947 break;
1949 default:
1950 return NT_STATUS_INVALID_INFO_CLASS;
1953 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1955 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1957 return r_u->status;
1960 /*******************************************************************
1961 samr_reply_query_usergroups
1962 ********************************************************************/
1964 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1966 SAM_ACCOUNT *sam_pass=NULL;
1967 struct passwd *passwd;
1968 DOM_SID sid;
1969 DOM_SID *sids;
1970 DOM_GID *gids = NULL;
1971 int num_groups = 0;
1972 gid_t *unix_gids;
1973 int i, num_gids, num_sids;
1974 uint32 acc_granted;
1975 BOOL ret;
1976 NTSTATUS result;
1979 * from the SID in the request:
1980 * we should send back the list of DOMAIN GROUPS
1981 * the user is a member of
1983 * and only the DOMAIN GROUPS
1984 * no ALIASES !!! neither aliases of the domain
1985 * nor aliases of the builtin SID
1987 * JFM, 12/2/2001
1990 r_u->status = NT_STATUS_OK;
1992 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1994 /* find the policy handle. open a policy on it. */
1995 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1996 return NT_STATUS_INVALID_HANDLE;
1998 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1999 return r_u->status;
2002 if (!sid_check_is_in_our_domain(&sid))
2003 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2005 pdb_init_sam(&sam_pass);
2007 become_root();
2008 ret = pdb_getsampwsid(sam_pass, &sid);
2009 unbecome_root();
2011 if (ret == False) {
2012 pdb_free_sam(&sam_pass);
2013 return NT_STATUS_NO_SUCH_USER;
2016 passwd = getpwnam_alloc(pdb_get_username(sam_pass));
2017 if (passwd == NULL) {
2018 pdb_free_sam(&sam_pass);
2019 return NT_STATUS_NO_SUCH_USER;
2022 sids = NULL;
2023 num_sids = 0;
2025 become_root();
2026 result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
2027 passwd->pw_gid,
2028 &sids, &unix_gids, &num_groups);
2029 unbecome_root();
2031 pdb_free_sam(&sam_pass);
2032 passwd_free(&passwd);
2034 if (!NT_STATUS_IS_OK(result))
2035 return result;
2037 SAFE_FREE(unix_gids);
2039 gids = NULL;
2040 num_gids = 0;
2042 for (i=0; i<num_groups; i++) {
2043 uint32 rid;
2045 if (!sid_peek_check_rid(get_global_sam_sid(),
2046 &(sids[i]), &rid))
2047 continue;
2049 gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1);
2050 gids[num_gids].attr=7;
2051 gids[num_gids].g_rid = rid;
2052 num_gids += 1;
2054 SAFE_FREE(sids);
2056 /* construct the response. lkclXXXX: gids are not copied! */
2057 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2059 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2061 return r_u->status;
2064 /*******************************************************************
2065 _samr_query_dom_info
2066 ********************************************************************/
2068 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2070 struct samr_info *info = NULL;
2071 SAM_UNK_CTR *ctr;
2072 uint32 min_pass_len,pass_hist,flag;
2073 time_t u_expire, u_min_age;
2074 NTTIME nt_expire, nt_min_age;
2076 time_t u_lock_duration, u_reset_time;
2077 NTTIME nt_lock_duration, nt_reset_time;
2078 uint32 lockout;
2080 time_t u_logout;
2081 NTTIME nt_logout;
2083 uint32 account_policy_temp;
2085 uint32 num_users=0, num_groups=0, num_aliases=0;
2087 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2088 return NT_STATUS_NO_MEMORY;
2090 ZERO_STRUCTP(ctr);
2092 r_u->status = NT_STATUS_OK;
2094 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2096 /* find the policy handle. open a policy on it. */
2097 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2098 return NT_STATUS_INVALID_HANDLE;
2100 switch (q_u->switch_value) {
2101 case 0x01:
2103 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2104 min_pass_len = account_policy_temp;
2106 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2107 pass_hist = account_policy_temp;
2109 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2110 flag = account_policy_temp;
2112 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2113 u_expire = account_policy_temp;
2115 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2116 u_min_age = account_policy_temp;
2118 unix_to_nt_time_abs(&nt_expire, u_expire);
2119 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2121 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2122 flag, nt_expire, nt_min_age);
2123 break;
2124 case 0x02:
2125 become_root();
2126 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2127 unbecome_root();
2128 if (!NT_STATUS_IS_OK(r_u->status)) {
2129 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2130 return r_u->status;
2132 num_users=info->disp_info.num_user_account;
2133 free_samr_db(info);
2135 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2136 if (!NT_STATUS_IS_OK(r_u->status)) {
2137 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2138 return r_u->status;
2140 num_groups=info->disp_info.num_group_account;
2141 free_samr_db(info);
2143 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
2144 u_logout = account_policy_temp;
2146 unix_to_nt_time_abs(&nt_logout, u_logout);
2148 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2149 init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
2150 num_users, num_groups, num_aliases, nt_logout);
2151 break;
2152 case 0x03:
2153 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2154 unix_to_nt_time_abs(&nt_logout, u_logout);
2156 init_unk_info3(&ctr->info.inf3, nt_logout);
2157 break;
2158 case 0x05:
2159 init_unk_info5(&ctr->info.inf5, global_myname());
2160 break;
2161 case 0x06:
2162 init_unk_info6(&ctr->info.inf6);
2163 break;
2164 case 0x07:
2165 init_unk_info7(&ctr->info.inf7);
2166 break;
2167 case 0x08:
2168 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
2169 break;
2170 case 0x0c:
2171 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2172 u_lock_duration = account_policy_temp;
2173 if (u_lock_duration != -1)
2174 u_lock_duration *= 60;
2176 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2177 u_reset_time = account_policy_temp * 60;
2179 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2180 lockout = account_policy_temp;
2182 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2183 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2185 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2186 break;
2187 default:
2188 return NT_STATUS_INVALID_INFO_CLASS;
2191 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2193 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2195 return r_u->status;
2198 /*******************************************************************
2199 _samr_create_user
2200 Create an account, can be either a normal user or a machine.
2201 This funcion will need to be updated for bdc/domain trusts.
2202 ********************************************************************/
2204 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2206 SAM_ACCOUNT *sam_pass=NULL;
2207 fstring account;
2208 DOM_SID sid;
2209 pstring add_script;
2210 POLICY_HND dom_pol = q_u->domain_pol;
2211 UNISTR2 user_account = q_u->uni_name;
2212 uint16 acb_info = q_u->acb_info;
2213 POLICY_HND *user_pol = &r_u->user_pol;
2214 struct samr_info *info = NULL;
2215 BOOL ret;
2216 NTSTATUS nt_status;
2217 struct passwd *pw;
2218 uint32 acc_granted;
2219 SEC_DESC *psd;
2220 size_t sd_size;
2221 uint32 new_rid = 0;
2222 /* check this, when giving away 'add computer to domain' privs */
2223 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2224 BOOL can_add_account;
2225 SE_PRIV se_rights;
2227 /* Get the domain SID stored in the domain policy */
2228 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2229 return NT_STATUS_INVALID_HANDLE;
2231 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2232 return nt_status;
2235 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2236 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2237 this parameter is not an account type */
2238 return NT_STATUS_INVALID_PARAMETER;
2241 /* find the account: tell the caller if it exists.
2242 lkclXXXX i have *no* idea if this is a problem or not
2243 or even if you are supposed to construct a different
2244 reply if the account already exists...
2247 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2248 strlower_m(account);
2250 pdb_init_sam(&sam_pass);
2252 become_root();
2253 ret = pdb_getsampwnam(sam_pass, account);
2254 unbecome_root();
2255 if (ret == True) {
2256 /* this account exists: say so */
2257 pdb_free_sam(&sam_pass);
2258 return NT_STATUS_USER_EXISTS;
2261 pdb_free_sam(&sam_pass);
2263 /*********************************************************************
2264 * HEADS UP! If we have to create a new user account, we have to get
2265 * a new RID from somewhere. This used to be done by the passdb
2266 * backend. It has been moved into idmap now. Since idmap is now
2267 * wrapped up behind winbind, this means you have to run winbindd if you
2268 * want new accounts to get a new RID when "enable rid algorithm = no".
2269 * Tough. We now have a uniform way of allocating RIDs regardless
2270 * of what ever passdb backend people may use.
2271 * --jerry (2003-07-10)
2272 *********************************************************************/
2274 pw = Get_Pwnam(account);
2277 * we can't check both the ending $ and the acb_info.
2279 * UserManager creates trust accounts (ending in $,
2280 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2281 * JFM, 11/29/2001
2284 if (account[strlen(account)-1] == '$') {
2285 se_priv_copy( &se_rights, &se_machine_account );
2286 pstrcpy(add_script, lp_addmachine_script());
2288 else {
2289 se_priv_copy( &se_rights, &se_add_users );
2290 pstrcpy(add_script, lp_adduser_script());
2293 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2295 DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2296 p->pipe_user_name, can_add_account ? "True":"False" ));
2298 /********** BEGIN Admin BLOCK **********/
2300 if ( can_add_account )
2301 become_root();
2303 if ( !pw ) {
2304 if (*add_script) {
2305 int add_ret;
2307 all_string_sub(add_script, "%u", account, sizeof(add_script));
2308 add_ret = smbrun(add_script,NULL);
2309 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2311 else /* no add user script -- ask winbindd to do it */
2313 if ( !winbind_create_user( account, &new_rid ) ) {
2314 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2315 account));
2321 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2323 nt_status = pdb_init_sam_new(&sam_pass, account, new_rid);
2325 /* this code is order such that we have no unnecessary retuns
2326 out of the admin block of code */
2328 if ( NT_STATUS_IS_OK(nt_status) ) {
2329 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2331 if ( !(ret = pdb_add_sam_account(sam_pass)) ) {
2332 pdb_free_sam(&sam_pass);
2333 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2334 account));
2335 nt_status = NT_STATUS_ACCESS_DENIED;
2339 if ( can_add_account )
2340 unbecome_root();
2342 /********** END Admin BLOCK **********/
2344 /* now check for failure */
2346 if ( !NT_STATUS_IS_OK(nt_status) )
2347 return nt_status;
2349 /* Get the user's SID */
2351 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2353 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2354 se_map_generic(&des_access, &usr_generic_mapping);
2356 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2357 des_access, &acc_granted, "_samr_create_user");
2359 if ( !NT_STATUS_IS_OK(nt_status) ) {
2360 return nt_status;
2363 /* associate the user's SID with the new handle. */
2364 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2365 pdb_free_sam(&sam_pass);
2366 return NT_STATUS_NO_MEMORY;
2369 ZERO_STRUCTP(info);
2370 info->sid = sid;
2371 info->acc_granted = acc_granted;
2373 /* get a (unique) handle. open a policy on it. */
2374 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2375 pdb_free_sam(&sam_pass);
2376 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2379 r_u->user_rid=pdb_get_user_rid(sam_pass);
2381 r_u->access_granted = acc_granted;
2383 pdb_free_sam(&sam_pass);
2385 return NT_STATUS_OK;
2388 /*******************************************************************
2389 samr_reply_connect_anon
2390 ********************************************************************/
2392 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2394 struct samr_info *info = NULL;
2395 uint32 des_access = q_u->access_mask;
2397 /* Access check */
2399 if (!pipe_access_check(p)) {
2400 DEBUG(3, ("access denied to samr_connect_anon\n"));
2401 r_u->status = NT_STATUS_ACCESS_DENIED;
2402 return r_u->status;
2405 /* set up the SAMR connect_anon response */
2407 r_u->status = NT_STATUS_OK;
2409 /* associate the user's SID with the new handle. */
2410 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2411 return NT_STATUS_NO_MEMORY;
2413 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2414 was observed from a win98 client trying to enumerate users (when configured
2415 user level access control on shares) --jerry */
2417 se_map_generic( &des_access, &sam_generic_mapping );
2418 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2420 info->status = q_u->unknown_0;
2422 /* get a (unique) handle. open a policy on it. */
2423 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2424 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2426 return r_u->status;
2429 /*******************************************************************
2430 samr_reply_connect
2431 ********************************************************************/
2433 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2435 struct samr_info *info = NULL;
2436 SEC_DESC *psd = NULL;
2437 uint32 acc_granted;
2438 uint32 des_access = q_u->access_mask;
2439 size_t sd_size;
2440 NTSTATUS nt_status;
2443 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2445 /* Access check */
2447 if (!pipe_access_check(p)) {
2448 DEBUG(3, ("access denied to samr_connect\n"));
2449 r_u->status = NT_STATUS_ACCESS_DENIED;
2450 return r_u->status;
2453 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2454 se_map_generic(&des_access, &sam_generic_mapping);
2455 if (!NT_STATUS_IS_OK(nt_status =
2456 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2457 des_access, &acc_granted, "_samr_connect"))) {
2458 return nt_status;
2461 r_u->status = NT_STATUS_OK;
2463 /* associate the user's SID and access granted with the new handle. */
2464 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2465 return NT_STATUS_NO_MEMORY;
2467 info->acc_granted = acc_granted;
2468 info->status = q_u->access_mask;
2470 /* get a (unique) handle. open a policy on it. */
2471 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2472 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2474 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2476 return r_u->status;
2479 /*******************************************************************
2480 samr_connect4
2481 ********************************************************************/
2483 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2485 struct samr_info *info = NULL;
2486 SEC_DESC *psd = NULL;
2487 uint32 acc_granted;
2488 uint32 des_access = q_u->access_mask;
2489 size_t sd_size;
2490 NTSTATUS nt_status;
2493 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2495 /* Access check */
2497 if (!pipe_access_check(p)) {
2498 DEBUG(3, ("access denied to samr_connect4\n"));
2499 r_u->status = NT_STATUS_ACCESS_DENIED;
2500 return r_u->status;
2503 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2504 se_map_generic(&des_access, &sam_generic_mapping);
2505 if (!NT_STATUS_IS_OK(nt_status =
2506 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2507 des_access, &acc_granted, "_samr_connect"))) {
2508 return nt_status;
2511 r_u->status = NT_STATUS_OK;
2513 /* associate the user's SID and access granted with the new handle. */
2514 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2515 return NT_STATUS_NO_MEMORY;
2517 info->acc_granted = acc_granted;
2518 info->status = q_u->access_mask;
2520 /* get a (unique) handle. open a policy on it. */
2521 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2522 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2524 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2526 return r_u->status;
2529 /**********************************************************************
2530 api_samr_lookup_domain
2531 **********************************************************************/
2533 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2535 struct samr_info *info;
2536 fstring domain_name;
2537 DOM_SID sid;
2539 r_u->status = NT_STATUS_OK;
2541 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2542 return NT_STATUS_INVALID_HANDLE;
2544 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
2545 Reverted that change so we will work with RAS servers again */
2547 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2548 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain")))
2550 return r_u->status;
2553 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2555 ZERO_STRUCT(sid);
2557 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2558 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2561 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2563 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2565 return r_u->status;
2568 /******************************************************************
2569 makes a SAMR_R_ENUM_DOMAINS structure.
2570 ********************************************************************/
2572 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2573 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2575 uint32 i;
2576 SAM_ENTRY *sam;
2577 UNISTR2 *uni_name;
2579 DEBUG(5, ("make_enum_domains\n"));
2581 *pp_sam = NULL;
2582 *pp_uni_name = NULL;
2584 if (num_sam_entries == 0)
2585 return True;
2587 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2588 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2590 if (sam == NULL || uni_name == NULL)
2591 return False;
2593 for (i = 0; i < num_sam_entries; i++) {
2594 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2595 init_sam_entry(&sam[i], &uni_name[i], 0);
2598 *pp_sam = sam;
2599 *pp_uni_name = uni_name;
2601 return True;
2604 /**********************************************************************
2605 api_samr_enum_domains
2606 **********************************************************************/
2608 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2610 struct samr_info *info;
2611 uint32 num_entries = 2;
2612 fstring dom[2];
2613 const char *name;
2615 r_u->status = NT_STATUS_OK;
2617 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2618 return NT_STATUS_INVALID_HANDLE;
2620 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2621 return r_u->status;
2624 name = get_global_sam_name();
2626 fstrcpy(dom[0],name);
2627 strupper_m(dom[0]);
2628 fstrcpy(dom[1],"Builtin");
2630 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2631 return NT_STATUS_NO_MEMORY;
2633 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2635 return r_u->status;
2638 /*******************************************************************
2639 api_samr_open_alias
2640 ********************************************************************/
2642 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2644 DOM_SID sid;
2645 POLICY_HND domain_pol = q_u->dom_pol;
2646 uint32 alias_rid = q_u->rid_alias;
2647 POLICY_HND *alias_pol = &r_u->pol;
2648 struct samr_info *info = NULL;
2649 SEC_DESC *psd = NULL;
2650 uint32 acc_granted;
2651 uint32 des_access = q_u->access_mask;
2652 size_t sd_size;
2653 NTSTATUS status;
2655 r_u->status = NT_STATUS_OK;
2657 /* find the domain policy and get the SID / access bits stored in the domain policy */
2658 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2659 return NT_STATUS_INVALID_HANDLE;
2661 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2662 return status;
2665 /* append the alias' RID to it */
2666 if (!sid_append_rid(&sid, alias_rid))
2667 return NT_STATUS_NO_SUCH_USER;
2669 /*check if access can be granted as requested by client. */
2670 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2671 se_map_generic(&des_access,&ali_generic_mapping);
2672 if (!NT_STATUS_IS_OK(status =
2673 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2674 des_access, &acc_granted, "_samr_open_alias"))) {
2675 return status;
2679 * we should check if the rid really exist !!!
2680 * JFM.
2683 /* associate the user's SID with the new handle. */
2684 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2685 return NT_STATUS_NO_MEMORY;
2687 info->acc_granted = acc_granted;
2689 /* get a (unique) handle. open a policy on it. */
2690 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2691 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2693 return r_u->status;
2696 /*******************************************************************
2697 set_user_info_10
2698 ********************************************************************/
2700 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2702 SAM_ACCOUNT *pwd =NULL;
2703 BOOL ret;
2705 pdb_init_sam(&pwd);
2707 ret = pdb_getsampwsid(pwd, sid);
2709 if(ret==False) {
2710 pdb_free_sam(&pwd);
2711 return False;
2714 if (id10 == NULL) {
2715 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2716 pdb_free_sam(&pwd);
2717 return False;
2720 /* FIX ME: check if the value is really changed --metze */
2721 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2722 pdb_free_sam(&pwd);
2723 return False;
2726 if(!pdb_update_sam_account(pwd)) {
2727 pdb_free_sam(&pwd);
2728 return False;
2731 pdb_free_sam(&pwd);
2733 return True;
2736 /*******************************************************************
2737 set_user_info_12
2738 ********************************************************************/
2740 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2742 SAM_ACCOUNT *pwd = NULL;
2744 pdb_init_sam(&pwd);
2746 if(!pdb_getsampwsid(pwd, sid)) {
2747 pdb_free_sam(&pwd);
2748 return False;
2751 if (id12 == NULL) {
2752 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2753 pdb_free_sam(&pwd);
2754 return False;
2757 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2758 pdb_free_sam(&pwd);
2759 return False;
2761 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2762 pdb_free_sam(&pwd);
2763 return False;
2765 if (!pdb_set_pass_changed_now (pwd)) {
2766 pdb_free_sam(&pwd);
2767 return False;
2770 if(!pdb_update_sam_account(pwd)) {
2771 pdb_free_sam(&pwd);
2772 return False;
2775 pdb_free_sam(&pwd);
2776 return True;
2779 /*******************************************************************
2780 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2781 ********************************************************************/
2782 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2784 struct group *grp;
2785 gid_t gid;
2787 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2788 &gid))) {
2789 DEBUG(2,("Could not get gid for primary group of "
2790 "user %s\n", pdb_get_username(sampass)));
2791 return False;
2794 grp = getgrgid(gid);
2796 if (grp == NULL) {
2797 DEBUG(2,("Could not find primary group %lu for "
2798 "user %s\n", (unsigned long)gid,
2799 pdb_get_username(sampass)));
2800 return False;
2803 if (smb_set_primary_group(grp->gr_name,
2804 pdb_get_username(sampass)) != 0) {
2805 DEBUG(2,("Could not set primary group for user %s to "
2806 "%s\n",
2807 pdb_get_username(sampass), grp->gr_name));
2808 return False;
2811 return True;
2815 /*******************************************************************
2816 set_user_info_20
2817 ********************************************************************/
2819 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2821 SAM_ACCOUNT *pwd = NULL;
2823 if (id20 == NULL) {
2824 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2825 return False;
2828 pdb_init_sam(&pwd);
2830 if (!pdb_getsampwsid(pwd, sid)) {
2831 pdb_free_sam(&pwd);
2832 return False;
2835 copy_id20_to_sam_passwd(pwd, id20);
2837 /* write the change out */
2838 if(!pdb_update_sam_account(pwd)) {
2839 pdb_free_sam(&pwd);
2840 return False;
2843 pdb_free_sam(&pwd);
2845 return True;
2847 /*******************************************************************
2848 set_user_info_21
2849 ********************************************************************/
2851 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2853 SAM_ACCOUNT *pwd = NULL;
2855 if (id21 == NULL) {
2856 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2857 return False;
2860 pdb_init_sam(&pwd);
2862 if (!pdb_getsampwsid(pwd, sid)) {
2863 pdb_free_sam(&pwd);
2864 return False;
2867 copy_id21_to_sam_passwd(pwd, id21);
2870 * The funny part about the previous two calls is
2871 * that pwd still has the password hashes from the
2872 * passdb entry. These have not been updated from
2873 * id21. I don't know if they need to be set. --jerry
2876 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2877 set_unix_primary_group(pwd);
2879 /* write the change out */
2880 if(!pdb_update_sam_account(pwd)) {
2881 pdb_free_sam(&pwd);
2882 return False;
2885 pdb_free_sam(&pwd);
2887 return True;
2890 /*******************************************************************
2891 set_user_info_23
2892 ********************************************************************/
2894 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2896 SAM_ACCOUNT *pwd = NULL;
2897 pstring plaintext_buf;
2898 uint32 len;
2899 uint16 acct_ctrl;
2901 if (id23 == NULL) {
2902 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2903 return False;
2906 pdb_init_sam(&pwd);
2908 if (!pdb_getsampwsid(pwd, sid)) {
2909 pdb_free_sam(&pwd);
2910 return False;
2913 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2914 pdb_get_username(pwd)));
2916 acct_ctrl = pdb_get_acct_ctrl(pwd);
2918 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2919 pdb_free_sam(&pwd);
2920 return False;
2923 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2924 pdb_free_sam(&pwd);
2925 return False;
2928 copy_id23_to_sam_passwd(pwd, id23);
2930 /* if it's a trust account, don't update /etc/passwd */
2931 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2932 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2933 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2934 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2935 } else {
2936 /* update the UNIX password */
2937 if (lp_unix_password_sync() ) {
2938 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2939 if (!passwd) {
2940 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2943 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2944 pdb_free_sam(&pwd);
2945 return False;
2950 ZERO_STRUCT(plaintext_buf);
2952 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2953 set_unix_primary_group(pwd);
2955 if(!pdb_update_sam_account(pwd)) {
2956 pdb_free_sam(&pwd);
2957 return False;
2960 pdb_free_sam(&pwd);
2962 return True;
2965 /*******************************************************************
2966 set_user_info_pw
2967 ********************************************************************/
2969 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2971 SAM_ACCOUNT *pwd = NULL;
2972 uint32 len;
2973 pstring plaintext_buf;
2974 uint16 acct_ctrl;
2976 pdb_init_sam(&pwd);
2978 if (!pdb_getsampwsid(pwd, sid)) {
2979 pdb_free_sam(&pwd);
2980 return False;
2983 DEBUG(5, ("Attempting administrator password change for user %s\n",
2984 pdb_get_username(pwd)));
2986 acct_ctrl = pdb_get_acct_ctrl(pwd);
2988 ZERO_STRUCT(plaintext_buf);
2990 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2991 pdb_free_sam(&pwd);
2992 return False;
2995 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2996 pdb_free_sam(&pwd);
2997 return False;
3000 /* if it's a trust account, don't update /etc/passwd */
3001 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
3002 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
3003 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
3004 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
3005 } else {
3006 /* update the UNIX password */
3007 if (lp_unix_password_sync()) {
3008 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
3009 if (!passwd) {
3010 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3013 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3014 pdb_free_sam(&pwd);
3015 return False;
3020 ZERO_STRUCT(plaintext_buf);
3022 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3024 /* update the SAMBA password */
3025 if(!pdb_update_sam_account(pwd)) {
3026 pdb_free_sam(&pwd);
3027 return False;
3030 pdb_free_sam(&pwd);
3032 return True;
3035 /*******************************************************************
3036 samr_reply_set_userinfo
3037 ********************************************************************/
3039 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3041 DOM_SID sid;
3042 POLICY_HND *pol = &q_u->pol;
3043 uint16 switch_value = q_u->switch_value;
3044 SAM_USERINFO_CTR *ctr = q_u->ctr;
3045 uint32 acc_granted;
3046 uint32 acc_required;
3047 BOOL can_add_machines;
3048 SE_PRIV se_machineop = SE_MACHINE_ACCOUNT;
3050 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3052 r_u->status = NT_STATUS_OK;
3054 /* find the policy handle. open a policy on it. */
3055 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3056 return NT_STATUS_INVALID_HANDLE;
3058 /* the access mask depends on what the caller wants to do */
3060 switch (switch_value) {
3061 case 24:
3062 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3063 break;
3064 default:
3065 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3066 break;
3069 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3070 return r_u->status;
3073 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3075 if (ctr == NULL) {
3076 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3077 return NT_STATUS_INVALID_INFO_CLASS;
3080 /* check to see if we are a domain admin */
3082 can_add_machines = user_has_privileges( p->pipe_user.nt_user_token, &se_machineop );
3084 DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
3085 p->pipe_user_name, can_add_machines ? "" : " not"));
3087 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3089 if ( can_add_machines )
3090 become_root();
3092 /* ok! user info levels (lots: see MSDEV help), off we go... */
3094 switch (switch_value) {
3095 case 0x12:
3096 if (!set_user_info_12(ctr->info.id12, &sid))
3097 r_u->status = NT_STATUS_ACCESS_DENIED;
3098 break;
3100 case 24:
3101 if (!p->session_key.length) {
3102 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3104 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3106 dump_data(100, (char *)ctr->info.id24->pass, 516);
3108 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3109 r_u->status = NT_STATUS_ACCESS_DENIED;
3110 break;
3112 case 25:
3113 #if 0
3115 * Currently we don't really know how to unmarshall
3116 * the level 25 struct, and the password encryption
3117 * is different. This is a placeholder for when we
3118 * do understand it. In the meantime just return INVALID
3119 * info level and W2K SP2 drops down to level 23... JRA.
3122 if (!p->session_key.length) {
3123 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3125 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3127 dump_data(100, (char *)ctr->info.id25->pass, 532);
3129 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3130 r_u->status = NT_STATUS_ACCESS_DENIED;
3131 break;
3132 #endif
3133 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3134 break;
3136 case 23:
3137 if (!p->session_key.length) {
3138 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3140 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3142 dump_data(100, (char *)ctr->info.id23->pass, 516);
3144 if (!set_user_info_23(ctr->info.id23, &sid))
3145 r_u->status = NT_STATUS_ACCESS_DENIED;
3146 break;
3148 default:
3149 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3153 if ( can_add_machines )
3154 unbecome_root();
3156 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3158 return r_u->status;
3161 /*******************************************************************
3162 samr_reply_set_userinfo2
3163 ********************************************************************/
3165 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3167 DOM_SID sid;
3168 SAM_USERINFO_CTR *ctr = q_u->ctr;
3169 POLICY_HND *pol = &q_u->pol;
3170 uint16 switch_value = q_u->switch_value;
3171 uint32 acc_granted;
3172 uint32 acc_required;
3173 BOOL can_add_machines;
3174 SE_PRIV se_machineop = SE_MACHINE_ACCOUNT;
3176 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3178 r_u->status = NT_STATUS_OK;
3180 /* find the policy handle. open a policy on it. */
3181 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3182 return NT_STATUS_INVALID_HANDLE;
3184 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3185 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3186 return r_u->status;
3189 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3191 if (ctr == NULL) {
3192 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3193 return NT_STATUS_INVALID_INFO_CLASS;
3196 switch_value=ctr->switch_value;
3198 /* check to see if we are a domain admin */
3200 can_add_machines = user_has_privileges( p->pipe_user.nt_user_token, &se_machineop );
3202 DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
3203 p->pipe_user_name, can_add_machines ? "" : " not"));
3205 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3207 if ( can_add_machines )
3208 become_root();
3210 /* ok! user info levels (lots: see MSDEV help), off we go... */
3212 switch (switch_value) {
3213 case 21:
3214 if (!set_user_info_21(ctr->info.id21, &sid))
3215 return NT_STATUS_ACCESS_DENIED;
3216 break;
3217 case 20:
3218 if (!set_user_info_20(ctr->info.id20, &sid))
3219 r_u->status = NT_STATUS_ACCESS_DENIED;
3220 break;
3221 case 16:
3222 if (!set_user_info_10(ctr->info.id10, &sid))
3223 r_u->status = NT_STATUS_ACCESS_DENIED;
3224 break;
3225 case 18:
3226 /* Used by AS/U JRA. */
3227 if (!set_user_info_12(ctr->info.id12, &sid))
3228 r_u->status = NT_STATUS_ACCESS_DENIED;
3229 break;
3230 default:
3231 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3234 if ( can_add_machines )
3235 unbecome_root();
3237 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3239 return r_u->status;
3242 /*********************************************************************
3243 _samr_query_aliasmem
3244 *********************************************************************/
3246 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3248 int num_groups = 0;
3249 uint32 *rids=NULL;
3250 struct samr_info *info = NULL;
3251 int i;
3253 NTSTATUS ntstatus1;
3254 NTSTATUS ntstatus2;
3256 DOM_SID *members;
3257 DOM_SID *aliases;
3258 int num_aliases;
3259 BOOL res;
3261 r_u->status = NT_STATUS_OK;
3263 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3265 /* find the policy handle. open a policy on it. */
3266 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3267 return NT_STATUS_INVALID_HANDLE;
3269 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3270 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3272 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3273 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3274 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3275 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3279 if (!sid_check_is_domain(&info->sid) &&
3280 !sid_check_is_builtin(&info->sid))
3281 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3283 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3285 if (members == NULL)
3286 return NT_STATUS_NO_MEMORY;
3288 for (i=0; i<q_u->num_sids1; i++)
3289 sid_copy(&members[i], &q_u->sid[i].sid);
3291 become_root();
3292 res = pdb_enum_alias_memberships(members,
3293 q_u->num_sids1, &aliases,
3294 &num_aliases);
3295 unbecome_root();
3297 if (!res)
3298 return NT_STATUS_UNSUCCESSFUL;
3300 rids = NULL;
3301 num_groups = 0;
3303 for (i=0; i<num_aliases; i++) {
3304 uint32 rid;
3306 if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
3307 continue;
3309 rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
3311 if (rids == NULL)
3312 return NT_STATUS_NO_MEMORY;
3314 rids[num_groups] = rid;
3315 num_groups += 1;
3317 SAFE_FREE(aliases);
3319 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3320 return NT_STATUS_OK;
3323 /*********************************************************************
3324 _samr_query_aliasmem
3325 *********************************************************************/
3327 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3329 int i;
3331 int num_sids = 0;
3332 DOM_SID2 *sid;
3333 DOM_SID *sids=NULL;
3335 DOM_SID alias_sid;
3337 uint32 acc_granted;
3339 /* find the policy handle. open a policy on it. */
3340 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3341 return NT_STATUS_INVALID_HANDLE;
3343 if (!NT_STATUS_IS_OK(r_u->status =
3344 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3345 return r_u->status;
3348 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3350 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3351 return NT_STATUS_NO_SUCH_ALIAS;
3353 sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);
3354 if (num_sids!=0 && sid == NULL) {
3355 SAFE_FREE(sids);
3356 return NT_STATUS_NO_MEMORY;
3359 for (i = 0; i < num_sids; i++) {
3360 init_dom_sid2(&sid[i], &sids[i]);
3363 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3365 SAFE_FREE(sids);
3367 return NT_STATUS_OK;
3370 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3372 int i;
3374 for (i=0; i<*num; i++) {
3375 if ((*uids)[i] == uid)
3376 return;
3379 *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3381 if (*uids == NULL)
3382 return;
3384 (*uids)[*num] = uid;
3385 *num += 1;
3389 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3391 struct group *grp;
3392 char **gr;
3393 struct sys_pwent *userlist, *user;
3395 *uids = NULL;
3396 *num = 0;
3398 /* We only look at our own sam, so don't care about imported stuff */
3400 winbind_off();
3402 if ((grp = getgrgid(gid)) == NULL) {
3403 winbind_on();
3404 return False;
3407 /* Primary group members */
3409 userlist = getpwent_list();
3411 for (user = userlist; user != NULL; user = user->next) {
3412 if (user->pw_gid != gid)
3413 continue;
3414 add_uid_to_array_unique(user->pw_uid, uids, num);
3417 pwent_free(userlist);
3419 /* Secondary group members */
3421 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3422 struct passwd *pw = getpwnam(*gr);
3424 if (pw == NULL)
3425 continue;
3426 add_uid_to_array_unique(pw->pw_uid, uids, num);
3429 winbind_on();
3431 return True;
3434 /*********************************************************************
3435 _samr_query_groupmem
3436 *********************************************************************/
3438 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3440 int final_num_rids, i;
3441 DOM_SID group_sid;
3442 fstring group_sid_str;
3443 uid_t *uids;
3444 int num;
3445 gid_t gid;
3447 uint32 *rid=NULL;
3448 uint32 *attr=NULL;
3450 uint32 acc_granted;
3452 /* find the policy handle. open a policy on it. */
3453 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3454 return NT_STATUS_INVALID_HANDLE;
3456 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3457 return r_u->status;
3460 sid_to_string(group_sid_str, &group_sid);
3461 DEBUG(10, ("sid is %s\n", group_sid_str));
3463 if (!sid_check_is_in_our_domain(&group_sid)) {
3464 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3465 return NT_STATUS_NO_SUCH_GROUP;
3468 DEBUG(10, ("lookup on Domain SID\n"));
3470 if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3471 return NT_STATUS_NO_SUCH_GROUP;
3473 if(!get_memberuids(gid, &uids, &num))
3474 return NT_STATUS_NO_SUCH_GROUP;
3476 rid=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3477 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3479 if (num!=0 && (rid==NULL || attr==NULL))
3480 return NT_STATUS_NO_MEMORY;
3482 final_num_rids = 0;
3484 for (i=0; i<num; i++) {
3485 DOM_SID sid;
3487 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3488 DEBUG(1, ("Could not map member uid to SID\n"));
3489 continue;
3492 if (!sid_check_is_in_our_domain(&sid)) {
3493 DEBUG(1, ("Inconsistent SAM -- group member uid not "
3494 "in our domain\n"));
3495 continue;
3498 sid_peek_rid(&sid, &rid[final_num_rids]);
3500 /* Hmm. In a trace I got the constant 7 here from NT. */
3501 attr[final_num_rids] = SID_NAME_USER;
3503 final_num_rids += 1;
3506 SAFE_FREE(uids);
3508 init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3509 NT_STATUS_OK);
3511 return NT_STATUS_OK;
3514 /*********************************************************************
3515 _samr_add_aliasmem
3516 *********************************************************************/
3518 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3520 DOM_SID alias_sid;
3521 uint32 acc_granted;
3522 SE_PRIV se_rights;
3523 BOOL can_add_accounts;
3524 BOOL ret;
3527 /* Find the policy handle. Open a policy on it. */
3528 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3529 return NT_STATUS_INVALID_HANDLE;
3531 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3532 return r_u->status;
3535 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3537 se_priv_copy( &se_rights, &se_add_users );
3538 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3540 /******** BEGIN SeAddUsers BLOCK *********/
3542 if ( can_add_accounts )
3543 become_root();
3545 ret = pdb_add_aliasmem(&alias_sid, &q_u->sid.sid);
3547 if ( can_add_accounts )
3548 unbecome_root();
3550 /******** END SeAddUsers BLOCK *********/
3552 return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3555 /*********************************************************************
3556 _samr_del_aliasmem
3557 *********************************************************************/
3559 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3561 DOM_SID alias_sid;
3562 uint32 acc_granted;
3563 SE_PRIV se_rights;
3564 BOOL can_add_accounts;
3565 BOOL ret;
3567 /* Find the policy handle. Open a policy on it. */
3568 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3569 return NT_STATUS_INVALID_HANDLE;
3571 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3572 return r_u->status;
3575 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3576 sid_string_static(&alias_sid)));
3578 se_priv_copy( &se_rights, &se_add_users );
3579 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3581 /******** BEGIN SeAddUsers BLOCK *********/
3583 if ( can_add_accounts )
3584 become_root();
3586 ret = pdb_del_aliasmem(&alias_sid, &q_u->sid.sid);
3588 if ( can_add_accounts )
3589 unbecome_root();
3591 /******** END SeAddUsers BLOCK *********/
3593 return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3596 /*********************************************************************
3597 _samr_add_groupmem
3598 *********************************************************************/
3600 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3602 DOM_SID group_sid;
3603 DOM_SID user_sid;
3604 fstring group_sid_str;
3605 uid_t uid;
3606 struct passwd *pwd;
3607 struct group *grp;
3608 fstring grp_name;
3609 GROUP_MAP map;
3610 NTSTATUS ret;
3611 SAM_ACCOUNT *sam_user=NULL;
3612 BOOL check;
3613 uint32 acc_granted;
3614 SE_PRIV se_rights;
3615 BOOL can_add_accounts;
3617 /* Find the policy handle. Open a policy on it. */
3618 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3619 return NT_STATUS_INVALID_HANDLE;
3621 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3622 return r_u->status;
3625 sid_to_string(group_sid_str, &group_sid);
3626 DEBUG(10, ("sid is %s\n", group_sid_str));
3628 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3629 return NT_STATUS_NO_SUCH_GROUP;
3631 DEBUG(10, ("lookup on Domain SID\n"));
3633 if(!get_domain_group_from_sid(group_sid, &map))
3634 return NT_STATUS_NO_SUCH_GROUP;
3636 sid_copy(&user_sid, get_global_sam_sid());
3637 sid_append_rid(&user_sid, q_u->rid);
3639 ret = pdb_init_sam(&sam_user);
3640 if (!NT_STATUS_IS_OK(ret))
3641 return ret;
3643 check = pdb_getsampwsid(sam_user, &user_sid);
3645 if (check != True) {
3646 pdb_free_sam(&sam_user);
3647 return NT_STATUS_NO_SUCH_USER;
3650 /* check a real user exist before we run the script to add a user to a group */
3651 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3652 pdb_free_sam(&sam_user);
3653 return NT_STATUS_NO_SUCH_USER;
3656 pdb_free_sam(&sam_user);
3658 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3659 return NT_STATUS_NO_SUCH_USER;
3662 if ((grp=getgrgid(map.gid)) == NULL) {
3663 passwd_free(&pwd);
3664 return NT_STATUS_NO_SUCH_GROUP;
3667 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3668 fstrcpy(grp_name, grp->gr_name);
3670 /* if the user is already in the group */
3671 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3672 passwd_free(&pwd);
3673 return NT_STATUS_MEMBER_IN_GROUP;
3676 se_priv_copy( &se_rights, &se_add_users );
3677 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3679 /******** BEGIN SeAddUsers BLOCK *********/
3681 if ( can_add_accounts )
3682 become_root();
3685 * ok, the group exist, the user exist, the user is not in the group,
3687 * we can (finally) add it to the group !
3690 smb_add_user_group(grp_name, pwd->pw_name);
3692 if ( can_add_accounts )
3693 unbecome_root();
3695 /******** END SeAddUsers BLOCK *********/
3697 /* check if the user has been added then ... */
3698 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3699 passwd_free(&pwd);
3700 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3703 passwd_free(&pwd);
3704 return NT_STATUS_OK;
3707 /*********************************************************************
3708 _samr_del_groupmem
3709 *********************************************************************/
3711 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3713 DOM_SID group_sid;
3714 DOM_SID user_sid;
3715 SAM_ACCOUNT *sam_pass=NULL;
3716 GROUP_MAP map;
3717 fstring grp_name;
3718 struct group *grp;
3719 uint32 acc_granted;
3720 SE_PRIV se_rights;
3721 BOOL can_add_accounts;
3724 * delete the group member named q_u->rid
3725 * who is a member of the sid associated with the handle
3726 * the rid is a user's rid as the group is a domain group.
3729 /* Find the policy handle. Open a policy on it. */
3730 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3731 return NT_STATUS_INVALID_HANDLE;
3733 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3734 return r_u->status;
3737 if (!sid_check_is_in_our_domain(&group_sid))
3738 return NT_STATUS_NO_SUCH_GROUP;
3740 sid_copy(&user_sid, get_global_sam_sid());
3741 sid_append_rid(&user_sid, q_u->rid);
3743 if (!get_domain_group_from_sid(group_sid, &map))
3744 return NT_STATUS_NO_SUCH_GROUP;
3746 if ((grp=getgrgid(map.gid)) == NULL)
3747 return NT_STATUS_NO_SUCH_GROUP;
3749 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3750 fstrcpy(grp_name, grp->gr_name);
3752 /* check if the user exists before trying to remove it from the group */
3753 pdb_init_sam(&sam_pass);
3754 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3755 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3756 pdb_free_sam(&sam_pass);
3757 return NT_STATUS_NO_SUCH_USER;
3760 /* if the user is not in the group */
3761 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3762 pdb_free_sam(&sam_pass);
3763 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3767 se_priv_copy( &se_rights, &se_add_users );
3768 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3770 /******** BEGIN SeAddUsers BLOCK *********/
3772 if ( can_add_accounts )
3773 become_root();
3775 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3777 if ( can_add_accounts )
3778 unbecome_root();
3780 /******** END SeAddUsers BLOCK *********/
3782 /* check if the user has been removed then ... */
3783 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3784 pdb_free_sam(&sam_pass);
3785 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3788 pdb_free_sam(&sam_pass);
3789 return NT_STATUS_OK;
3793 /****************************************************************************
3794 Delete a UNIX user on demand.
3795 ****************************************************************************/
3797 static int smb_delete_user(const char *unix_user)
3799 pstring del_script;
3800 int ret;
3802 /* try winbindd first since it is impossible to determine where
3803 a user came from via NSS. Try the delete user script if this fails
3804 meaning the user did not exist in winbindd's list of accounts */
3806 if ( winbind_delete_user( unix_user ) ) {
3807 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3808 return 0;
3812 /* fall back to 'delete user script' */
3814 pstrcpy(del_script, lp_deluser_script());
3815 if (! *del_script)
3816 return -1;
3817 all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3818 ret = smbrun(del_script,NULL);
3819 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3821 return ret;
3824 /*********************************************************************
3825 _samr_delete_dom_user
3826 *********************************************************************/
3828 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3830 DOM_SID user_sid;
3831 SAM_ACCOUNT *sam_pass=NULL;
3832 uint32 acc_granted;
3833 SE_PRIV se_rights;
3834 BOOL can_add_accounts;
3835 BOOL ret;
3837 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3839 /* Find the policy handle. Open a policy on it. */
3840 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3841 return NT_STATUS_INVALID_HANDLE;
3843 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3844 return r_u->status;
3847 if (!sid_check_is_in_our_domain(&user_sid))
3848 return NT_STATUS_CANNOT_DELETE;
3850 /* check if the user exists before trying to delete */
3851 pdb_init_sam(&sam_pass);
3852 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3853 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3854 sid_string_static(&user_sid)));
3855 pdb_free_sam(&sam_pass);
3856 return NT_STATUS_NO_SUCH_USER;
3859 se_priv_copy( &se_rights, &se_add_users );
3860 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3862 /******** BEGIN SeAddUsers BLOCK *********/
3864 if ( can_add_accounts )
3865 become_root();
3867 /* First delete the samba side....
3868 code is order to prevent unnecessary returns out of the admin
3869 block of code */
3871 if ( (ret = pdb_delete_sam_account(sam_pass)) == True ) {
3873 * Now delete the unix side ....
3874 * note: we don't check if the delete really happened
3875 * as the script is not necessary present
3876 * and maybe the sysadmin doesn't want to delete the unix side
3878 smb_delete_user( pdb_get_username(sam_pass) );
3881 if ( can_add_accounts )
3882 unbecome_root();
3884 /******** END SeAddUsers BLOCK *********/
3886 if ( !ret ) {
3887 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3888 pdb_free_sam(&sam_pass);
3889 return NT_STATUS_CANNOT_DELETE;
3893 pdb_free_sam(&sam_pass);
3895 if (!close_policy_hnd(p, &q_u->user_pol))
3896 return NT_STATUS_OBJECT_NAME_INVALID;
3898 return NT_STATUS_OK;
3901 /*********************************************************************
3902 _samr_delete_dom_group
3903 *********************************************************************/
3905 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3907 DOM_SID group_sid;
3908 DOM_SID dom_sid;
3909 uint32 group_rid;
3910 fstring group_sid_str;
3911 gid_t gid;
3912 struct group *grp;
3913 GROUP_MAP map;
3914 uint32 acc_granted;
3915 SE_PRIV se_rights;
3916 BOOL can_add_accounts;
3917 BOOL ret;
3919 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3921 /* Find the policy handle. Open a policy on it. */
3922 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3923 return NT_STATUS_INVALID_HANDLE;
3925 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3926 return r_u->status;
3929 sid_copy(&dom_sid, &group_sid);
3930 sid_to_string(group_sid_str, &dom_sid);
3931 sid_split_rid(&dom_sid, &group_rid);
3933 DEBUG(10, ("sid is %s\n", group_sid_str));
3935 /* we check if it's our SID before deleting */
3936 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3937 return NT_STATUS_NO_SUCH_GROUP;
3939 DEBUG(10, ("lookup on Domain SID\n"));
3941 if(!get_domain_group_from_sid(group_sid, &map))
3942 return NT_STATUS_NO_SUCH_GROUP;
3944 gid=map.gid;
3946 /* check if group really exists */
3947 if ( (grp=getgrgid(gid)) == NULL)
3948 return NT_STATUS_NO_SUCH_GROUP;
3950 se_priv_copy( &se_rights, &se_add_users );
3951 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3953 /******** BEGIN SeAddUsers BLOCK *********/
3955 if ( can_add_accounts )
3956 become_root();
3958 /* delete mapping first */
3960 if ( (ret = pdb_delete_group_mapping_entry(group_sid)) == True ) {
3961 smb_delete_group( grp->gr_name );
3964 if ( can_add_accounts )
3965 unbecome_root();
3967 /******** END SeAddUsers BLOCK *********/
3969 if ( !ret ) {
3970 DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n",
3971 group_sid_str));
3972 return NT_STATUS_ACCESS_DENIED;
3975 /* don't check that the unix group has been deleted. Work like
3976 _samr_delet_dom_user() */
3978 if (!close_policy_hnd(p, &q_u->group_pol))
3979 return NT_STATUS_OBJECT_NAME_INVALID;
3981 return NT_STATUS_OK;
3984 /*********************************************************************
3985 _samr_delete_dom_alias
3986 *********************************************************************/
3988 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3990 DOM_SID alias_sid;
3991 uint32 acc_granted;
3992 SE_PRIV se_rights;
3993 BOOL can_add_accounts;
3994 BOOL ret;
3996 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3998 /* Find the policy handle. Open a policy on it. */
3999 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
4000 return NT_STATUS_INVALID_HANDLE;
4002 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
4003 return r_u->status;
4006 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
4008 if (!sid_check_is_in_our_domain(&alias_sid))
4009 return NT_STATUS_NO_SUCH_ALIAS;
4011 DEBUG(10, ("lookup on Local SID\n"));
4013 se_priv_copy( &se_rights, &se_add_users );
4014 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4016 /******** BEGIN SeAddUsers BLOCK *********/
4018 if ( can_add_accounts )
4019 become_root();
4021 /* Have passdb delete the alias */
4022 ret = pdb_delete_alias(&alias_sid);
4024 if ( can_add_accounts )
4025 unbecome_root();
4027 /******** END SeAddUsers BLOCK *********/
4029 if ( !ret )
4030 return NT_STATUS_ACCESS_DENIED;
4032 if (!close_policy_hnd(p, &q_u->alias_pol))
4033 return NT_STATUS_OBJECT_NAME_INVALID;
4035 return NT_STATUS_OK;
4038 /*********************************************************************
4039 _samr_create_dom_group
4040 *********************************************************************/
4042 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
4044 DOM_SID dom_sid;
4045 DOM_SID info_sid;
4046 fstring name;
4047 fstring sid_string;
4048 struct group *grp;
4049 struct samr_info *info;
4050 uint32 acc_granted;
4051 gid_t gid;
4052 SE_PRIV se_rights;
4053 BOOL can_add_accounts;
4054 NTSTATUS result;
4056 /* Find the policy handle. Open a policy on it. */
4057 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
4058 return NT_STATUS_INVALID_HANDLE;
4060 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
4061 return r_u->status;
4064 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4065 return NT_STATUS_ACCESS_DENIED;
4067 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4069 /* check if group already exist */
4070 if ((grp=getgrnam(name)) != NULL)
4071 return NT_STATUS_GROUP_EXISTS;
4073 se_priv_copy( &se_rights, &se_add_users );
4074 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4076 /******** BEGIN SeAddUsers BLOCK *********/
4078 if ( can_add_accounts )
4079 become_root();
4081 /* check that we successfully create the UNIX group */
4083 result = NT_STATUS_ACCESS_DENIED;
4084 if ( (smb_create_group(name, &gid) == 0) && ((grp=getgrgid(gid)) != NULL) ) {
4086 /* so far, so good */
4088 result = NT_STATUS_OK;
4090 r_u->rid = pdb_gid_to_group_rid( grp->gr_gid );
4092 /* add the group to the mapping table */
4094 sid_copy( &info_sid, get_global_sam_sid() );
4095 sid_append_rid( &info_sid, r_u->rid );
4096 sid_to_string( sid_string, &info_sid );
4098 /* reset the error code if we fail to add the mapping entry */
4100 if ( !add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL) )
4101 result = NT_STATUS_ACCESS_DENIED;
4104 if ( can_add_accounts )
4105 unbecome_root();
4107 /******** END SeAddUsers BLOCK *********/
4109 /* check if we should bail out here */
4111 if ( !NT_STATUS_IS_OK(result) )
4112 return result;
4114 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4115 return NT_STATUS_NO_MEMORY;
4117 /* get a (unique) handle. open a policy on it. */
4118 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4119 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4121 return NT_STATUS_OK;
4124 /*********************************************************************
4125 _samr_create_dom_alias
4126 *********************************************************************/
4128 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4130 DOM_SID dom_sid;
4131 DOM_SID info_sid;
4132 fstring name;
4133 struct group *grp;
4134 struct samr_info *info;
4135 uint32 acc_granted;
4136 gid_t gid;
4137 NTSTATUS result;
4138 SE_PRIV se_rights;
4139 BOOL can_add_accounts;
4141 /* Find the policy handle. Open a policy on it. */
4142 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4143 return NT_STATUS_INVALID_HANDLE;
4145 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4146 return r_u->status;
4149 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4150 return NT_STATUS_ACCESS_DENIED;
4152 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4154 se_priv_copy( &se_rights, &se_add_users );
4155 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4157 /******** BEGIN SeAddUsers BLOCK *********/
4159 if ( can_add_accounts )
4160 become_root();
4162 /* Have passdb create the alias */
4163 result = pdb_create_alias(name, &r_u->rid);
4165 if ( can_add_accounts )
4166 unbecome_root();
4168 /******** END SeAddUsers BLOCK *********/
4170 if (!NT_STATUS_IS_OK(result))
4171 return result;
4173 sid_copy(&info_sid, get_global_sam_sid());
4174 sid_append_rid(&info_sid, r_u->rid);
4176 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
4177 return NT_STATUS_ACCESS_DENIED;
4179 /* check if the group has been successfully created */
4180 if ((grp=getgrgid(gid)) == NULL)
4181 return NT_STATUS_ACCESS_DENIED;
4183 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4184 return NT_STATUS_NO_MEMORY;
4186 /* get a (unique) handle. open a policy on it. */
4187 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4188 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4190 return NT_STATUS_OK;
4193 /*********************************************************************
4194 _samr_query_groupinfo
4196 sends the name/comment pair of a domain group
4197 level 1 send also the number of users of that group
4198 *********************************************************************/
4200 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4202 DOM_SID group_sid;
4203 GROUP_MAP map;
4204 DOM_SID *sids=NULL;
4205 uid_t *uids;
4206 int num=0;
4207 GROUP_INFO_CTR *ctr;
4208 uint32 acc_granted;
4209 BOOL ret;
4211 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4212 return NT_STATUS_INVALID_HANDLE;
4214 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4215 return r_u->status;
4218 become_root();
4219 ret = get_domain_group_from_sid(group_sid, &map);
4220 unbecome_root();
4221 if (!ret)
4222 return NT_STATUS_INVALID_HANDLE;
4224 ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
4225 if (ctr==NULL)
4226 return NT_STATUS_NO_MEMORY;
4228 switch (q_u->switch_level) {
4229 case 1:
4230 ctr->switch_value1 = 1;
4231 if(!get_memberuids(map.gid, &uids, &num))
4232 return NT_STATUS_NO_SUCH_GROUP;
4233 SAFE_FREE(uids);
4234 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
4235 SAFE_FREE(sids);
4236 break;
4237 case 3:
4238 ctr->switch_value1 = 3;
4239 init_samr_group_info3(&ctr->group.info3);
4240 break;
4241 case 4:
4242 ctr->switch_value1 = 4;
4243 init_samr_group_info4(&ctr->group.info4, map.comment);
4244 break;
4245 default:
4246 return NT_STATUS_INVALID_INFO_CLASS;
4249 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4251 return NT_STATUS_OK;
4254 /*********************************************************************
4255 _samr_set_groupinfo
4257 update a domain group's comment.
4258 *********************************************************************/
4260 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4262 DOM_SID group_sid;
4263 GROUP_MAP map;
4264 GROUP_INFO_CTR *ctr;
4265 uint32 acc_granted;
4267 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4268 return NT_STATUS_INVALID_HANDLE;
4270 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4271 return r_u->status;
4274 if (!get_domain_group_from_sid(group_sid, &map))
4275 return NT_STATUS_NO_SUCH_GROUP;
4277 ctr=q_u->ctr;
4279 switch (ctr->switch_value1) {
4280 case 1:
4281 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4282 break;
4283 case 4:
4284 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4285 break;
4286 default:
4287 return NT_STATUS_INVALID_INFO_CLASS;
4290 if(!pdb_update_group_mapping_entry(&map)) {
4291 return NT_STATUS_NO_SUCH_GROUP;
4294 return NT_STATUS_OK;
4297 /*********************************************************************
4298 _samr_set_aliasinfo
4300 update an alias's comment.
4301 *********************************************************************/
4303 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4305 DOM_SID group_sid;
4306 struct acct_info info;
4307 ALIAS_INFO_CTR *ctr;
4308 uint32 acc_granted;
4310 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4311 return NT_STATUS_INVALID_HANDLE;
4313 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4314 return r_u->status;
4317 ctr=&q_u->ctr;
4319 switch (ctr->switch_value1) {
4320 case 3:
4321 unistr2_to_ascii(info.acct_desc,
4322 &(ctr->alias.info3.uni_acct_desc),
4323 sizeof(info.acct_desc)-1);
4324 break;
4325 default:
4326 return NT_STATUS_INVALID_INFO_CLASS;
4329 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4330 return NT_STATUS_ACCESS_DENIED;
4333 return NT_STATUS_OK;
4336 /*********************************************************************
4337 _samr_get_dom_pwinfo
4338 *********************************************************************/
4340 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4342 /* Perform access check. Since this rpc does not require a
4343 policy handle it will not be caught by the access checks on
4344 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4346 if (!pipe_access_check(p)) {
4347 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4348 r_u->status = NT_STATUS_ACCESS_DENIED;
4349 return r_u->status;
4352 /* Actually, returning zeros here works quite well :-). */
4354 return NT_STATUS_OK;
4357 /*********************************************************************
4358 _samr_open_group
4359 *********************************************************************/
4361 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4363 DOM_SID sid;
4364 DOM_SID info_sid;
4365 GROUP_MAP map;
4366 struct samr_info *info;
4367 SEC_DESC *psd = NULL;
4368 uint32 acc_granted;
4369 uint32 des_access = q_u->access_mask;
4370 size_t sd_size;
4371 NTSTATUS status;
4372 fstring sid_string;
4373 BOOL ret;
4375 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4376 return NT_STATUS_INVALID_HANDLE;
4378 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4379 return status;
4382 /*check if access can be granted as requested by client. */
4383 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4384 se_map_generic(&des_access,&grp_generic_mapping);
4385 if (!NT_STATUS_IS_OK(status =
4386 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4387 des_access, &acc_granted, "_samr_open_group"))) {
4388 return status;
4392 /* this should not be hard-coded like this */
4393 if (!sid_equal(&sid, get_global_sam_sid()))
4394 return NT_STATUS_ACCESS_DENIED;
4396 sid_copy(&info_sid, get_global_sam_sid());
4397 sid_append_rid(&info_sid, q_u->rid_group);
4398 sid_to_string(sid_string, &info_sid);
4400 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4401 return NT_STATUS_NO_MEMORY;
4403 info->acc_granted = acc_granted;
4405 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4407 /* check if that group really exists */
4408 become_root();
4409 ret = get_domain_group_from_sid(info->sid, &map);
4410 unbecome_root();
4411 if (!ret)
4412 return NT_STATUS_NO_SUCH_GROUP;
4414 /* get a (unique) handle. open a policy on it. */
4415 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4416 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4418 return NT_STATUS_OK;
4421 /*********************************************************************
4422 _samr_remove_sid_foreign_domain
4423 *********************************************************************/
4425 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4426 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4427 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4429 DOM_SID delete_sid, alias_sid;
4430 SAM_ACCOUNT *sam_pass=NULL;
4431 uint32 acc_granted;
4432 GROUP_MAP map;
4433 BOOL is_user = False;
4434 NTSTATUS result;
4435 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4437 sid_copy( &delete_sid, &q_u->sid.sid );
4439 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4440 sid_string_static(&delete_sid)));
4442 /* Find the policy handle. Open a policy on it. */
4444 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4445 return NT_STATUS_INVALID_HANDLE;
4447 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4448 "_samr_remove_sid_foreign_domain");
4450 if (!NT_STATUS_IS_OK(result))
4451 return result;
4453 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4454 sid_string_static(&alias_sid)));
4456 /* make sure we can handle this */
4458 if ( sid_check_is_domain(&alias_sid) )
4459 type = SID_NAME_DOM_GRP;
4460 else if ( sid_check_is_builtin(&alias_sid) )
4461 type = SID_NAME_ALIAS;
4463 if ( type == SID_NAME_UNKNOWN ) {
4464 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4465 return NT_STATUS_OK;
4468 /* check if the user exists before trying to delete */
4470 pdb_init_sam(&sam_pass);
4472 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4473 is_user = True;
4474 } else {
4475 /* maybe it is a group */
4476 if( !pdb_getgrsid(&map, delete_sid) ) {
4477 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4478 sid_string_static(&delete_sid)));
4479 result = NT_STATUS_INVALID_SID;
4480 goto done;
4484 /* we can only delete a user from a group since we don't have
4485 nested groups anyways. So in the latter case, just say OK */
4487 if ( is_user ) {
4488 GROUP_MAP *mappings = NULL;
4489 int num_groups, i;
4490 struct group *grp2;
4492 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4494 /* interate over the groups */
4495 for ( i=0; i<num_groups; i++ ) {
4497 grp2 = getgrgid(mappings[i].gid);
4499 if ( !grp2 ) {
4500 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4501 continue;
4504 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4505 continue;
4507 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4509 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4510 /* should we fail here ? */
4511 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4512 pdb_get_username(sam_pass), grp2->gr_name ));
4513 continue;
4516 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4517 pdb_get_username(sam_pass), grp2->gr_name ));
4520 SAFE_FREE(mappings);
4524 result = NT_STATUS_OK;
4525 done:
4527 pdb_free_sam(&sam_pass);
4529 return result;
4532 /*******************************************************************
4533 _samr_unknown_2e
4534 ********************************************************************/
4536 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4538 struct samr_info *info = NULL;
4539 SAM_UNK_CTR *ctr;
4540 uint32 min_pass_len,pass_hist,flag;
4541 time_t u_expire, u_min_age;
4542 NTTIME nt_expire, nt_min_age;
4544 time_t u_lock_duration, u_reset_time;
4545 NTTIME nt_lock_duration, nt_reset_time;
4546 uint32 lockout;
4548 time_t u_logout;
4549 NTTIME nt_logout;
4551 uint32 num_users=0, num_groups=0, num_aliases=0;
4553 uint32 account_policy_temp;
4555 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4556 return NT_STATUS_NO_MEMORY;
4558 ZERO_STRUCTP(ctr);
4560 r_u->status = NT_STATUS_OK;
4562 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4564 /* find the policy handle. open a policy on it. */
4565 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4566 return NT_STATUS_INVALID_HANDLE;
4568 switch (q_u->switch_value) {
4569 case 0x01:
4570 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4571 min_pass_len = account_policy_temp;
4573 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4574 pass_hist = account_policy_temp;
4576 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4577 flag = account_policy_temp;
4579 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4580 u_expire = account_policy_temp;
4582 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4583 u_min_age = account_policy_temp;
4585 unix_to_nt_time_abs(&nt_expire, u_expire);
4586 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4588 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4589 flag, nt_expire, nt_min_age);
4590 break;
4591 case 0x02:
4592 become_root();
4593 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4594 unbecome_root();
4595 if (!NT_STATUS_IS_OK(r_u->status)) {
4596 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4597 return r_u->status;
4599 num_users=info->disp_info.num_user_account;
4600 free_samr_db(info);
4602 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4603 if (NT_STATUS_IS_ERR(r_u->status)) {
4604 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4605 return r_u->status;
4607 num_groups=info->disp_info.num_group_account;
4608 free_samr_db(info);
4610 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4611 u_logout = account_policy_temp;
4613 unix_to_nt_time_abs(&nt_logout, u_logout);
4615 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4616 init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
4617 num_users, num_groups, num_aliases, nt_logout);
4618 break;
4619 case 0x03:
4620 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4621 u_logout = account_policy_temp;
4623 unix_to_nt_time_abs(&nt_logout, u_logout);
4625 init_unk_info3(&ctr->info.inf3, nt_logout);
4626 break;
4627 case 0x05:
4628 init_unk_info5(&ctr->info.inf5, global_myname());
4629 break;
4630 case 0x06:
4631 init_unk_info6(&ctr->info.inf6);
4632 break;
4633 case 0x07:
4634 init_unk_info7(&ctr->info.inf7);
4635 break;
4636 case 0x08:
4637 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
4638 break;
4639 case 0x0c:
4640 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4641 u_lock_duration = account_policy_temp;
4642 if (u_lock_duration != -1)
4643 u_lock_duration *= 60;
4645 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4646 u_reset_time = account_policy_temp * 60;
4648 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4649 lockout = account_policy_temp;
4651 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4652 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4654 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4655 break;
4656 default:
4657 return NT_STATUS_INVALID_INFO_CLASS;
4660 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4662 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4664 return r_u->status;
4667 /*******************************************************************
4668 _samr_
4669 ********************************************************************/
4671 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4673 time_t u_expire, u_min_age;
4674 time_t u_logout;
4675 time_t u_lock_duration, u_reset_time;
4677 r_u->status = NT_STATUS_OK;
4679 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4681 /* find the policy handle. open a policy on it. */
4682 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4683 return NT_STATUS_INVALID_HANDLE;
4685 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4687 switch (q_u->switch_value) {
4688 case 0x01:
4689 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4690 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4692 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4693 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4694 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4695 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4696 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4697 break;
4698 case 0x02:
4699 break;
4700 case 0x03:
4701 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4702 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4703 break;
4704 case 0x05:
4705 break;
4706 case 0x06:
4707 break;
4708 case 0x07:
4709 break;
4710 case 0x0c:
4711 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4712 if (u_lock_duration != -1)
4713 u_lock_duration /= 60;
4714 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4716 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4717 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4718 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4719 break;
4720 default:
4721 return NT_STATUS_INVALID_INFO_CLASS;
4724 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4726 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4728 return r_u->status;