reset time and duration are set in minutes, not seconds. Works from usrmgr.
[Samba/nascimento.git] / source3 / rpc_server / srv_samr_nt.c
blob10069abb76c50310a7d7a7d66f42c4bc5351ad00
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.
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 all_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 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 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 = (struct samr_info *)talloc(mem_ctx, sizeof(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 all_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;
219 DEBUG(10,("load_sampwd_entries\n"));
221 /* if the snapshoot is already loaded, return */
222 if ((info->disp_info.user_dbloaded==True)
223 && (info->acb_mask == acb_mask)
224 && (info->all_machines == all_machines)) {
225 DEBUG(10,("load_sampwd_entries: already in memory\n"));
226 return NT_STATUS_OK;
229 free_samr_users(info);
231 if (!pdb_setsampwent(False)) {
232 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233 return NT_STATUS_ACCESS_DENIED;
236 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
237 && pdb_getsampwent(pwd) == True; pwd=NULL) {
239 if (all_machines) {
240 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
241 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
243 pdb_free_sam(&pwd);
244 continue;
246 } else {
247 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
248 pdb_free_sam(&pwd);
249 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
250 continue;
254 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
257 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258 pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
259 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
261 if (pwd_array==NULL)
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* Copy the SAM_ACCOUNT into the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
270 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
272 info->disp_info.num_user_account++;
275 pdb_endsampwent();
277 /* the snapshoot is in memory, we're ready to enumerate fast */
279 info->acb_mask = acb_mask;
280 info->all_machines = all_machines;
281 info->disp_info.user_dbloaded=True;
283 DEBUG(10,("load_sampwd_entries: done\n"));
285 return nt_status;
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
290 GROUP_MAP *map=NULL;
291 DOMAIN_GRP *grp_array = NULL;
292 uint32 group_entries = 0;
293 uint32 i;
294 TALLOC_CTX *mem_ctx = info->mem_ctx;
295 BOOL ret;
297 DEBUG(10,("load_group_domain_entries\n"));
299 /* if the snapshoot is already loaded, return */
300 if (info->disp_info.group_dbloaded==True) {
301 DEBUG(10,("load_group_domain_entries: already in memory\n"));
302 return NT_STATUS_OK;
306 become_root();
307 ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
308 unbecome_root();
310 if ( !ret ) {
311 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
312 return NT_STATUS_NO_MEMORY;
316 info->disp_info.num_group_account=group_entries;
318 grp_array=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
319 if (group_entries!=0 && grp_array==NULL) {
320 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
321 SAFE_FREE(map);
322 return NT_STATUS_NO_MEMORY;
325 info->disp_info.disp_group_info=grp_array;
327 for (i=0; i<group_entries; i++) {
328 fstrcpy(grp_array[i].name, map[i].nt_name);
329 fstrcpy(grp_array[i].comment, map[i].comment);
330 sid_split_rid(&map[i].sid, &grp_array[i].rid);
331 grp_array[i].attr=SID_NAME_DOM_GRP;
334 SAFE_FREE(map);
336 /* the snapshoot is in memory, we're ready to enumerate fast */
338 info->disp_info.group_dbloaded=True;
340 DEBUG(10,("load_group_domain_entries: done\n"));
342 return NT_STATUS_OK;
346 /*******************************************************************
347 _samr_close_hnd
348 ********************************************************************/
350 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
352 r_u->status = NT_STATUS_OK;
354 /* close the policy handle */
355 if (!close_policy_hnd(p, &q_u->pol))
356 return NT_STATUS_OBJECT_NAME_INVALID;
358 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
360 return r_u->status;
363 /*******************************************************************
364 samr_reply_open_domain
365 ********************************************************************/
367 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
369 struct samr_info *info;
370 SEC_DESC *psd = NULL;
371 uint32 acc_granted;
372 uint32 des_access = q_u->flags;
373 size_t sd_size;
374 NTSTATUS status;
376 r_u->status = NT_STATUS_OK;
378 /* find the connection policy handle. */
379 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
380 return NT_STATUS_INVALID_HANDLE;
382 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
383 return status;
386 /*check if access can be granted as requested by client. */
387 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
388 se_map_generic(&des_access,&dom_generic_mapping);
390 if (!NT_STATUS_IS_OK(status =
391 access_check_samr_object(psd, p->pipe_user.nt_user_token,
392 des_access, &acc_granted, "_samr_open_domain"))) {
393 return status;
396 /* associate the domain SID with the (unique) handle. */
397 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
398 return NT_STATUS_NO_MEMORY;
399 info->acc_granted = acc_granted;
401 /* get a (unique) handle. open a policy on it. */
402 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
403 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
405 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
407 return r_u->status;
410 /*******************************************************************
411 _samr_get_usrdom_pwinfo
412 ********************************************************************/
414 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
416 struct samr_info *info = NULL;
418 r_u->status = NT_STATUS_OK;
420 /* find the policy handle. open a policy on it. */
421 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
422 return NT_STATUS_INVALID_HANDLE;
424 if (!sid_check_is_in_our_domain(&info->sid))
425 return NT_STATUS_OBJECT_TYPE_MISMATCH;
427 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
429 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
432 * NT sometimes return NT_STATUS_ACCESS_DENIED
433 * I don't know yet why.
436 return r_u->status;
439 /*******************************************************************
440 samr_make_dom_obj_sd
441 ********************************************************************/
443 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
445 extern DOM_SID global_sid_World;
446 DOM_SID adm_sid;
447 DOM_SID act_sid;
449 SEC_ACE ace[3];
450 SEC_ACCESS mask;
452 SEC_ACL *psa = NULL;
454 sid_copy(&adm_sid, &global_sid_Builtin);
455 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
457 sid_copy(&act_sid, &global_sid_Builtin);
458 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
460 /*basic access for every one*/
461 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
462 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
464 /*full access for builtin aliases Administrators and Account Operators*/
465 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
466 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
467 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
469 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
470 return NT_STATUS_NO_MEMORY;
472 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
473 return NT_STATUS_NO_MEMORY;
475 return NT_STATUS_OK;
478 /*******************************************************************
479 samr_make_usr_obj_sd
480 ********************************************************************/
482 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
484 extern DOM_SID global_sid_World;
485 DOM_SID adm_sid;
486 DOM_SID act_sid;
488 SEC_ACE ace[4];
489 SEC_ACCESS mask;
491 SEC_ACL *psa = NULL;
493 sid_copy(&adm_sid, &global_sid_Builtin);
494 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
496 sid_copy(&act_sid, &global_sid_Builtin);
497 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
499 /*basic access for every one*/
500 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
501 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
503 /*full access for builtin aliases Administrators and Account Operators*/
504 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
505 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
506 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
508 /*extended access for the user*/
509 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
510 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
512 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
513 return NT_STATUS_NO_MEMORY;
515 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
516 return NT_STATUS_NO_MEMORY;
518 return NT_STATUS_OK;
521 /*******************************************************************
522 samr_make_grp_obj_sd
523 ********************************************************************/
525 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
527 extern DOM_SID global_sid_World;
528 DOM_SID adm_sid;
529 DOM_SID act_sid;
531 SEC_ACE ace[3];
532 SEC_ACCESS mask;
534 SEC_ACL *psa = NULL;
536 sid_copy(&adm_sid, &global_sid_Builtin);
537 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
539 sid_copy(&act_sid, &global_sid_Builtin);
540 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
542 /*basic access for every one*/
543 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
544 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
546 /*full access for builtin aliases Administrators and Account Operators*/
547 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
548 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
549 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
551 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
552 return NT_STATUS_NO_MEMORY;
554 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
555 return NT_STATUS_NO_MEMORY;
557 return NT_STATUS_OK;
560 /*******************************************************************
561 samr_make_ali_obj_sd
562 ********************************************************************/
564 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
566 extern DOM_SID global_sid_World;
567 DOM_SID adm_sid;
568 DOM_SID act_sid;
570 SEC_ACE ace[3];
571 SEC_ACCESS mask;
573 SEC_ACL *psa = NULL;
575 sid_copy(&adm_sid, &global_sid_Builtin);
576 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
578 sid_copy(&act_sid, &global_sid_Builtin);
579 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
581 /*basic access for every one*/
582 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
583 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
585 /*full access for builtin aliases Administrators and Account Operators*/
586 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
587 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
588 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
590 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
591 return NT_STATUS_NO_MEMORY;
593 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
594 return NT_STATUS_NO_MEMORY;
596 return NT_STATUS_OK;
599 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
601 struct samr_info *info = NULL;
603 /* find the policy handle. open a policy on it. */
604 if (!find_policy_by_hnd(p, pol, (void **)&info))
605 return False;
607 if (!info)
608 return False;
610 *sid = info->sid;
611 *acc_granted = info->acc_granted;
612 return True;
615 /*******************************************************************
616 _samr_set_sec_obj
617 ********************************************************************/
619 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
621 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
622 return NT_STATUS_NOT_IMPLEMENTED;
626 /*******************************************************************
627 _samr_query_sec_obj
628 ********************************************************************/
630 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
632 DOM_SID pol_sid;
633 fstring str_sid;
634 SEC_DESC * psd = NULL;
635 size_t sd_size;
636 uint32 acc_granted;
638 r_u->status = NT_STATUS_OK;
640 /* Get the SID. */
641 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
642 return NT_STATUS_INVALID_HANDLE;
646 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
648 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
650 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
651 if (pol_sid.sid_rev_num == 0)
653 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
654 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
656 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
659 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
660 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
662 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
664 /* TODO: Builtin probably needs a different SD with restricted write access*/
665 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
666 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
668 else if (sid_check_is_in_our_domain(&pol_sid) ||
669 sid_check_is_in_builtin(&pol_sid))
671 /* TODO: different SDs have to be generated for aliases groups and users.
672 Currently all three get a default user SD */
673 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
674 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
676 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
678 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
679 return NT_STATUS_NO_MEMORY;
681 if (NT_STATUS_IS_OK(r_u->status))
682 r_u->ptr = 1;
684 return r_u->status;
687 /*******************************************************************
688 makes a SAM_ENTRY / UNISTR2* structure from a user list.
689 ********************************************************************/
691 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
692 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
693 DOM_SID *domain_sid)
695 uint32 i;
696 SAM_ENTRY *sam;
697 UNISTR2 *uni_name;
698 SAM_ACCOUNT *pwd = NULL;
699 UNISTR2 uni_temp_name;
700 const char *temp_name;
701 const DOM_SID *user_sid;
702 uint32 user_rid;
703 fstring user_sid_string;
704 fstring domain_sid_string;
706 *sam_pp = NULL;
707 *uni_name_pp = NULL;
709 if (num_entries == 0)
710 return NT_STATUS_OK;
712 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
714 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
716 if (sam == NULL || uni_name == NULL) {
717 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
718 return NT_STATUS_NO_MEMORY;
721 for (i = 0; i < num_entries; i++) {
722 pwd = &disp_user_info[i+start_idx];
723 temp_name = pdb_get_username(pwd);
724 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
725 user_sid = pdb_get_user_sid(pwd);
727 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
728 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
729 "the domain sid %s. Failing operation.\n",
730 temp_name,
731 sid_to_string(user_sid_string, user_sid),
732 sid_to_string(domain_sid_string, domain_sid)));
733 return NT_STATUS_UNSUCCESSFUL;
736 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
737 copy_unistr2(&uni_name[i], &uni_temp_name);
740 *sam_pp = sam;
741 *uni_name_pp = uni_name;
742 return NT_STATUS_OK;
745 /*******************************************************************
746 samr_reply_enum_dom_users
747 ********************************************************************/
749 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
750 SAMR_R_ENUM_DOM_USERS *r_u)
752 struct samr_info *info = NULL;
753 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
754 int num_account;
755 uint32 enum_context=q_u->start_idx;
756 uint32 max_size=q_u->max_size;
757 uint32 temp_size;
758 enum remote_arch_types ra_type = get_remote_arch();
759 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
760 uint32 max_entries = max_sam_entries;
761 DOM_SID domain_sid;
763 r_u->status = NT_STATUS_OK;
765 /* find the policy handle. open a policy on it. */
766 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
767 return NT_STATUS_INVALID_HANDLE;
769 domain_sid = info->sid;
771 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
772 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
773 "_samr_enum_dom_users"))) {
774 return r_u->status;
777 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
779 become_root();
780 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
781 unbecome_root();
783 if (!NT_STATUS_IS_OK(r_u->status))
784 return r_u->status;
786 num_account = info->disp_info.num_user_account;
788 if (enum_context > num_account) {
789 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
790 return NT_STATUS_OK;
793 /* verify we won't overflow */
794 if (max_entries > num_account-enum_context) {
795 max_entries = num_account-enum_context;
796 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
799 /* calculate the size and limit on the number of entries we will return */
800 temp_size=max_entries*struct_size;
802 if (temp_size>max_size) {
803 max_entries=MIN((max_size/struct_size),max_entries);;
804 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
808 * Note from JRA. total_entries is not being used here. Currently if there is a
809 * large user base then it looks like NT will enumerate until get_sampwd_entries
810 * returns False due to num_entries being zero. This will cause an access denied
811 * return. I don't think this is right and needs further investigation. Note that
812 * this is also the same in the TNG code (I don't think that has been tested with
813 * a very large user list as MAX_SAM_ENTRIES is set to 600).
815 * I also think that one of the 'num_entries' return parameters is probably
816 * the "max entries" parameter - but in the TNG code they're all currently set to the same
817 * value (again I think this is wrong).
820 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
821 max_entries, enum_context,
822 info->disp_info.disp_user_info,
823 &domain_sid);
825 if (!NT_STATUS_IS_OK(r_u->status))
826 return r_u->status;
828 if (enum_context+max_entries < num_account)
829 r_u->status = STATUS_MORE_ENTRIES;
831 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
833 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
835 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
837 return r_u->status;
840 /*******************************************************************
841 makes a SAM_ENTRY / UNISTR2* structure from a group list.
842 ********************************************************************/
844 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
845 uint32 num_sam_entries, DOMAIN_GRP *grp)
847 uint32 i;
848 SAM_ENTRY *sam;
849 UNISTR2 *uni_name;
851 *sam_pp = NULL;
852 *uni_name_pp = NULL;
854 if (num_sam_entries == 0)
855 return;
857 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
859 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
861 if (sam == NULL || uni_name == NULL) {
862 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
863 return;
866 for (i = 0; i < num_sam_entries; i++) {
868 * JRA. I think this should include the null. TNG does not.
870 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
871 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
874 *sam_pp = sam;
875 *uni_name_pp = uni_name;
878 /*******************************************************************
879 Get the group entries - similar to get_sampwd_entries().
880 ******************************************************************/
882 static NTSTATUS get_group_entries( enum SID_NAME_USE type, TALLOC_CTX *ctx,
883 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
884 uint32 *p_num_entries, uint32 max_entries )
886 GROUP_MAP *map=NULL;
887 int i;
888 uint32 group_entries = 0;
889 uint32 num_entries = 0;
891 *p_num_entries = 0;
893 /* access checks for the users were performed higher up. become/unbecome_root()
894 needed for some passdb backends to enumerate groups */
896 become_root();
897 pdb_enum_group_mapping(type, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
898 unbecome_root();
900 num_entries=group_entries-start_idx;
902 /* limit the number of entries */
903 if (num_entries>max_entries) {
904 DEBUG(5,("Limiting to %d entries\n", max_entries));
905 num_entries=max_entries;
908 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
909 if (num_entries!=0 && *d_grp==NULL){
910 SAFE_FREE(map);
911 return NT_STATUS_NO_MEMORY;
914 for (i=0; i<num_entries; i++) {
915 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
916 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
917 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
918 (*d_grp)[i].attr=type;
921 SAFE_FREE(map);
923 *p_num_entries = num_entries;
925 DEBUG(10,("get_group_entries: returning %d entries\n", *p_num_entries));
927 return NT_STATUS_OK;
930 /*******************************************************************
931 Wrapper for enuemrating domain groups
932 ******************************************************************/
934 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
935 DOM_SID *sid, uint32 start_idx,
936 uint32 *p_num_entries, uint32 max_entries )
938 return get_group_entries( SID_NAME_DOM_GRP, ctx, d_grp, sid, start_idx,
939 p_num_entries, max_entries );
942 /*******************************************************************
943 Wrapper for enumerating local groups
944 ******************************************************************/
946 static NTSTATUS get_group_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
947 DOM_SID *sid, uint32 start_idx,
948 uint32 *p_num_entries, uint32 max_entries)
950 if ( sid_equal(sid, &global_sid_Builtin) ) {
951 return get_group_entries( SID_NAME_WKN_GRP, ctx, d_grp,
952 sid, start_idx, p_num_entries, max_entries );
954 else if ( sid_equal(sid, get_global_sam_sid()) ) {
955 return get_group_entries( SID_NAME_ALIAS, ctx, d_grp,
956 sid, start_idx, p_num_entries, max_entries );
959 /* can't do anything with this SID */
961 *p_num_entries = 0;
963 return NT_STATUS_OK;
966 /*******************************************************************
967 samr_reply_enum_dom_groups
968 ********************************************************************/
970 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
972 DOMAIN_GRP *grp=NULL;
973 uint32 num_entries;
974 DOM_SID sid;
975 uint32 acc_granted;
977 r_u->status = NT_STATUS_OK;
979 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
980 return NT_STATUS_INVALID_HANDLE;
982 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
983 return r_u->status;
986 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
988 /* the domain group array is being allocated in the function below */
989 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))) {
990 return r_u->status;
993 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
995 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
997 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
999 return r_u->status;
1003 /*******************************************************************
1004 samr_reply_enum_dom_aliases
1005 ********************************************************************/
1007 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1009 DOMAIN_GRP *grp=NULL;
1010 uint32 num_entries = 0;
1011 fstring sid_str;
1012 DOM_SID sid;
1013 NTSTATUS status;
1014 uint32 acc_granted;
1016 r_u->status = NT_STATUS_OK;
1018 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1019 return NT_STATUS_INVALID_HANDLE;
1021 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1022 return r_u->status;
1025 sid_to_string(sid_str, &sid);
1026 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1028 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1029 &num_entries, MAX_SAM_ENTRIES);
1030 if (NT_STATUS_IS_ERR(status)) return status;
1032 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1034 /*safe_free(grp);*/
1036 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1038 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1040 return r_u->status;
1043 /*******************************************************************
1044 samr_reply_query_dispinfo
1045 ********************************************************************/
1047 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1048 SAMR_R_QUERY_DISPINFO *r_u)
1050 struct samr_info *info = NULL;
1051 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1053 uint32 max_entries=q_u->max_entries;
1054 uint32 enum_context=q_u->start_idx;
1055 uint32 max_size=q_u->max_size;
1057 SAM_DISPINFO_CTR *ctr;
1058 uint32 temp_size=0, total_data_size=0;
1059 NTSTATUS disp_ret;
1060 uint32 num_account = 0;
1061 enum remote_arch_types ra_type = get_remote_arch();
1062 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1063 DOM_SID domain_sid;
1065 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1066 r_u->status = NT_STATUS_OK;
1068 /* find the policy handle. open a policy on it. */
1069 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1070 return NT_STATUS_INVALID_HANDLE;
1072 domain_sid = info->sid;
1075 * calculate how many entries we will return.
1076 * based on
1077 * - the number of entries the client asked
1078 * - our limit on that
1079 * - the starting point (enumeration context)
1080 * - the buffer size the client will accept
1084 * We are a lot more like W2K. Instead of reading the SAM
1085 * each time to find the records we need to send back,
1086 * we read it once and link that copy to the sam handle.
1087 * For large user list (over the MAX_SAM_ENTRIES)
1088 * it's a definitive win.
1089 * second point to notice: between enumerations
1090 * our sam is now the same as it's a snapshoot.
1091 * third point: got rid of the static SAM_USER_21 struct
1092 * no more intermediate.
1093 * con: it uses much more memory, as a full copy is stored
1094 * in memory.
1096 * If you want to change it, think twice and think
1097 * of the second point , that's really important.
1099 * JFM, 12/20/2001
1102 /* Get what we need from the password database */
1103 switch (q_u->switch_level) {
1104 case 0x1:
1105 /* When playing with usrmgr, this is necessary
1106 if you want immediate refresh after editing
1107 a user. I would like to do this after the
1108 setuserinfo2, but we do not have access to
1109 the domain handle in that call, only to the
1110 user handle. Where else does this hurt?
1111 -- Volker
1113 #if 0
1114 /* We cannot do this here - it kills performace. JRA. */
1115 free_samr_users(info);
1116 #endif
1117 case 0x2:
1118 case 0x4:
1119 become_root();
1120 /* Level 2 is for all machines, otherwise only 'normal' users */
1121 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1122 unbecome_root();
1123 if (!NT_STATUS_IS_OK(r_u->status)) {
1124 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1125 return r_u->status;
1127 num_account = info->disp_info.num_user_account;
1128 break;
1129 case 0x3:
1130 case 0x5:
1131 r_u->status = load_group_domain_entries(info, &info->sid);
1132 if (!NT_STATUS_IS_OK(r_u->status))
1133 return r_u->status;
1134 num_account = info->disp_info.num_group_account;
1135 break;
1136 default:
1137 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1138 return NT_STATUS_INVALID_INFO_CLASS;
1141 /* first limit the number of entries we will return */
1142 if(max_entries > max_sam_entries) {
1143 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1144 max_entries = max_sam_entries;
1147 if (enum_context > num_account) {
1148 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1149 return NT_STATUS_NO_MORE_ENTRIES;
1152 /* verify we won't overflow */
1153 if (max_entries > num_account-enum_context) {
1154 max_entries = num_account-enum_context;
1155 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1158 /* calculate the size and limit on the number of entries we will return */
1159 temp_size=max_entries*struct_size;
1161 if (temp_size>max_size) {
1162 max_entries=MIN((max_size/struct_size),max_entries);;
1163 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1166 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1167 return NT_STATUS_NO_MEMORY;
1169 ZERO_STRUCTP(ctr);
1171 /* Now create reply structure */
1172 switch (q_u->switch_level) {
1173 case 0x1:
1174 if (max_entries) {
1175 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1176 return NT_STATUS_NO_MEMORY;
1178 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1179 info->disp_info.disp_user_info, &domain_sid);
1180 if (!NT_STATUS_IS_OK(disp_ret))
1181 return disp_ret;
1182 break;
1183 case 0x2:
1184 if (max_entries) {
1185 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1186 return NT_STATUS_NO_MEMORY;
1188 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1189 info->disp_info.disp_user_info, &domain_sid);
1190 if (!NT_STATUS_IS_OK(disp_ret))
1191 return disp_ret;
1192 break;
1193 case 0x3:
1194 if (max_entries) {
1195 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1196 return NT_STATUS_NO_MEMORY;
1198 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1199 if (!NT_STATUS_IS_OK(disp_ret))
1200 return disp_ret;
1201 break;
1202 case 0x4:
1203 if (max_entries) {
1204 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1205 return NT_STATUS_NO_MEMORY;
1207 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1208 if (!NT_STATUS_IS_OK(disp_ret))
1209 return disp_ret;
1210 break;
1211 case 0x5:
1212 if (max_entries) {
1213 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1214 return NT_STATUS_NO_MEMORY;
1216 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1217 if (!NT_STATUS_IS_OK(disp_ret))
1218 return disp_ret;
1219 break;
1221 default:
1222 ctr->sam.info = NULL;
1223 return NT_STATUS_INVALID_INFO_CLASS;
1226 /* calculate the total size */
1227 total_data_size=num_account*struct_size;
1229 if (enum_context+max_entries < num_account)
1230 r_u->status = STATUS_MORE_ENTRIES;
1232 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1234 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1236 return r_u->status;
1240 /*******************************************************************
1241 samr_reply_query_aliasinfo
1242 ********************************************************************/
1244 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1246 DOM_SID sid;
1247 GROUP_MAP map;
1248 uint32 acc_granted;
1249 BOOL ret;
1251 r_u->status = NT_STATUS_OK;
1253 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1255 /* find the policy handle. open a policy on it. */
1256 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1257 return NT_STATUS_INVALID_HANDLE;
1258 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1259 return r_u->status;
1262 if (!sid_check_is_in_our_domain(&sid) &&
1263 !sid_check_is_in_builtin(&sid))
1264 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1266 become_root();
1267 ret = pdb_getgrsid(&map, sid);
1268 unbecome_root();
1270 if ( !ret )
1271 return NT_STATUS_NO_SUCH_ALIAS;
1273 switch (q_u->switch_level) {
1274 case 1:
1275 r_u->ptr = 1;
1276 r_u->ctr.switch_value1 = 1;
1277 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1278 break;
1279 case 3:
1280 r_u->ptr = 1;
1281 r_u->ctr.switch_value1 = 3;
1282 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1283 break;
1284 default:
1285 return NT_STATUS_INVALID_INFO_CLASS;
1288 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1290 return r_u->status;
1293 #if 0
1294 /*******************************************************************
1295 samr_reply_lookup_ids
1296 ********************************************************************/
1298 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1300 uint32 rid[MAX_SAM_ENTRIES];
1301 int num_rids = q_u->num_sids1;
1303 r_u->status = NT_STATUS_OK;
1305 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1307 if (num_rids > MAX_SAM_ENTRIES) {
1308 num_rids = MAX_SAM_ENTRIES;
1309 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1312 #if 0
1313 int i;
1314 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1316 for (i = 0; i < num_rids && status == 0; i++)
1318 struct sam_passwd *sam_pass;
1319 fstring user_name;
1322 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1323 q_u->uni_user_name[i].uni_str_len));
1325 /* find the user account */
1326 become_root();
1327 sam_pass = get_smb21pwd_entry(user_name, 0);
1328 unbecome_root();
1330 if (sam_pass == NULL)
1332 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1333 rid[i] = 0;
1335 else
1337 rid[i] = sam_pass->user_rid;
1340 #endif
1342 num_rids = 1;
1343 rid[0] = BUILTIN_ALIAS_RID_USERS;
1345 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1347 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1349 return r_u->status;
1351 #endif
1353 /*******************************************************************
1354 _samr_lookup_names
1355 ********************************************************************/
1357 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1359 uint32 rid[MAX_SAM_ENTRIES];
1360 uint32 local_rid;
1361 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1362 enum SID_NAME_USE local_type;
1363 int i;
1364 int num_rids = q_u->num_names2;
1365 DOM_SID pol_sid;
1366 fstring sid_str;
1367 uint32 acc_granted;
1369 r_u->status = NT_STATUS_OK;
1371 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1373 ZERO_ARRAY(rid);
1374 ZERO_ARRAY(type);
1376 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1377 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1378 return r_u->status;
1381 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 */
1382 return r_u->status;
1385 if (num_rids > MAX_SAM_ENTRIES) {
1386 num_rids = MAX_SAM_ENTRIES;
1387 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1390 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1392 for (i = 0; i < num_rids; i++) {
1393 fstring name;
1394 DOM_SID sid;
1395 int ret;
1397 r_u->status = NT_STATUS_NONE_MAPPED;
1399 rid [i] = 0xffffffff;
1400 type[i] = SID_NAME_UNKNOWN;
1402 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1405 * we are only looking for a name
1406 * the SID we get back can be outside
1407 * the scope of the pol_sid
1409 * in clear: it prevents to reply to domain\group: yes
1410 * when only builtin\group exists.
1412 * a cleaner code is to add the sid of the domain we're looking in
1413 * to the local_lookup_name function.
1416 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1417 sid_split_rid(&sid, &local_rid);
1419 if (sid_equal(&sid, &pol_sid)) {
1420 rid[i]=local_rid;
1422 /* Windows does not return WKN_GRP here, even
1423 * on lookups in builtin */
1424 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1425 SID_NAME_ALIAS : local_type;
1427 r_u->status = NT_STATUS_OK;
1432 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1434 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1436 return r_u->status;
1439 /*******************************************************************
1440 _samr_chgpasswd_user
1441 ********************************************************************/
1443 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1445 fstring user_name;
1446 fstring wks;
1448 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1450 r_u->status = NT_STATUS_OK;
1452 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1453 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1455 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1458 * Pass the user through the NT -> unix user mapping
1459 * function.
1462 (void)map_username(user_name);
1465 * UNIX username case mangling not required, pass_oem_change
1466 * is case insensitive.
1469 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1470 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1472 init_samr_r_chgpasswd_user(r_u, r_u->status);
1474 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1476 return r_u->status;
1479 /*******************************************************************
1480 makes a SAMR_R_LOOKUP_RIDS structure.
1481 ********************************************************************/
1483 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1484 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1486 uint32 i;
1487 UNIHDR *hdr_name=NULL;
1488 UNISTR2 *uni_name=NULL;
1490 *pp_uni_name = NULL;
1491 *pp_hdr_name = NULL;
1493 if (num_names != 0) {
1494 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1495 if (hdr_name == NULL)
1496 return False;
1498 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1499 if (uni_name == NULL)
1500 return False;
1503 for (i = 0; i < num_names; i++) {
1504 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1505 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1506 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1509 *pp_uni_name = uni_name;
1510 *pp_hdr_name = hdr_name;
1512 return True;
1515 /*******************************************************************
1516 _samr_lookup_rids
1517 ********************************************************************/
1519 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1521 fstring group_names[MAX_SAM_ENTRIES];
1522 uint32 *group_attrs = NULL;
1523 UNIHDR *hdr_name = NULL;
1524 UNISTR2 *uni_name = NULL;
1525 DOM_SID pol_sid;
1526 int num_rids = q_u->num_rids1;
1527 int i;
1528 uint32 acc_granted;
1530 r_u->status = NT_STATUS_OK;
1532 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1534 /* find the policy handle. open a policy on it. */
1535 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1536 return NT_STATUS_INVALID_HANDLE;
1538 if (num_rids > MAX_SAM_ENTRIES) {
1539 num_rids = MAX_SAM_ENTRIES;
1540 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1543 if (num_rids) {
1544 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1545 return NT_STATUS_NO_MEMORY;
1548 r_u->status = NT_STATUS_NONE_MAPPED;
1550 become_root(); /* lookup_sid can require root privs */
1552 for (i = 0; i < num_rids; i++) {
1553 fstring tmpname;
1554 fstring domname;
1555 DOM_SID sid;
1556 enum SID_NAME_USE type;
1558 group_attrs[i] = SID_NAME_UNKNOWN;
1559 *group_names[i] = '\0';
1561 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1562 sid_copy(&sid, &pol_sid);
1563 sid_append_rid(&sid, q_u->rid[i]);
1565 if (lookup_sid(&sid, domname, tmpname, &type)) {
1566 r_u->status = NT_STATUS_OK;
1567 group_attrs[i] = (uint32)type;
1568 fstrcpy(group_names[i],tmpname);
1569 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1574 unbecome_root();
1576 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1577 return NT_STATUS_NO_MEMORY;
1579 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1581 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1583 return r_u->status;
1586 /*******************************************************************
1587 _samr_open_user. Safe - gives out no passwd info.
1588 ********************************************************************/
1590 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1592 SAM_ACCOUNT *sampass=NULL;
1593 DOM_SID sid;
1594 POLICY_HND domain_pol = q_u->domain_pol;
1595 POLICY_HND *user_pol = &r_u->user_pol;
1596 struct samr_info *info = NULL;
1597 SEC_DESC *psd = NULL;
1598 uint32 acc_granted;
1599 uint32 des_access = q_u->access_mask;
1600 size_t sd_size;
1601 BOOL ret;
1602 NTSTATUS nt_status;
1604 r_u->status = NT_STATUS_OK;
1606 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1607 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1608 return NT_STATUS_INVALID_HANDLE;
1610 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1611 return nt_status;
1614 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1615 if (!NT_STATUS_IS_OK(nt_status)) {
1616 return nt_status;
1619 /* append the user's RID to it */
1620 if (!sid_append_rid(&sid, q_u->user_rid))
1621 return NT_STATUS_NO_SUCH_USER;
1623 /* check if access can be granted as requested by client. */
1624 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1625 se_map_generic(&des_access, &usr_generic_mapping);
1626 if (!NT_STATUS_IS_OK(nt_status =
1627 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1628 des_access, &acc_granted, "_samr_open_user"))) {
1629 return nt_status;
1632 become_root();
1633 ret=pdb_getsampwsid(sampass, &sid);
1634 unbecome_root();
1636 /* check that the SID exists in our domain. */
1637 if (ret == False) {
1638 return NT_STATUS_NO_SUCH_USER;
1641 pdb_free_sam(&sampass);
1643 /* associate the user's SID and access bits with the new handle. */
1644 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1645 return NT_STATUS_NO_MEMORY;
1646 info->acc_granted = acc_granted;
1648 /* get a (unique) handle. open a policy on it. */
1649 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1650 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1652 return r_u->status;
1655 /*************************************************************************
1656 get_user_info_10. Safe. Only gives out acb bits.
1657 *************************************************************************/
1659 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1661 SAM_ACCOUNT *smbpass=NULL;
1662 BOOL ret;
1663 NTSTATUS nt_status;
1665 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1667 if (!NT_STATUS_IS_OK(nt_status)) {
1668 return nt_status;
1671 become_root();
1672 ret = pdb_getsampwsid(smbpass, user_sid);
1673 unbecome_root();
1675 if (ret==False) {
1676 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1677 return NT_STATUS_NO_SUCH_USER;
1680 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1682 ZERO_STRUCTP(id10);
1683 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1685 pdb_free_sam(&smbpass);
1687 return NT_STATUS_OK;
1690 /*************************************************************************
1691 get_user_info_12. OK - this is the killer as it gives out password info.
1692 Ensure that this is only allowed on an encrypted connection with a root
1693 user. JRA.
1694 *************************************************************************/
1696 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1698 SAM_ACCOUNT *smbpass=NULL;
1699 BOOL ret;
1700 NTSTATUS nt_status;
1702 if (!p->ntlmssp_auth_validated)
1703 return NT_STATUS_ACCESS_DENIED;
1705 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1706 return NT_STATUS_ACCESS_DENIED;
1709 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1712 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1714 if (!NT_STATUS_IS_OK(nt_status)) {
1715 return nt_status;
1718 ret = pdb_getsampwsid(smbpass, user_sid);
1720 if (ret == False) {
1721 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1722 pdb_free_sam(&smbpass);
1723 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1726 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1728 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1729 pdb_free_sam(&smbpass);
1730 return NT_STATUS_ACCOUNT_DISABLED;
1733 ZERO_STRUCTP(id12);
1734 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1736 pdb_free_sam(&smbpass);
1738 return NT_STATUS_OK;
1741 /*************************************************************************
1742 get_user_info_20
1743 *************************************************************************/
1745 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1747 SAM_ACCOUNT *sampass=NULL;
1748 BOOL ret;
1750 pdb_init_sam_talloc(mem_ctx, &sampass);
1752 become_root();
1753 ret = pdb_getsampwsid(sampass, user_sid);
1754 unbecome_root();
1756 if (ret == False) {
1757 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1758 return NT_STATUS_NO_SUCH_USER;
1761 samr_clear_sam_passwd(sampass);
1763 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1765 ZERO_STRUCTP(id20);
1766 init_sam_user_info20A(id20, sampass);
1768 pdb_free_sam(&sampass);
1770 return NT_STATUS_OK;
1773 /*************************************************************************
1774 get_user_info_21
1775 *************************************************************************/
1777 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1778 DOM_SID *user_sid, DOM_SID *domain_sid)
1780 SAM_ACCOUNT *sampass=NULL;
1781 BOOL ret;
1782 NTSTATUS nt_status;
1784 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1785 if (!NT_STATUS_IS_OK(nt_status)) {
1786 return nt_status;
1789 become_root();
1790 ret = pdb_getsampwsid(sampass, user_sid);
1791 unbecome_root();
1793 if (ret == False) {
1794 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1795 return NT_STATUS_NO_SUCH_USER;
1798 samr_clear_sam_passwd(sampass);
1800 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1802 ZERO_STRUCTP(id21);
1803 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1805 pdb_free_sam(&sampass);
1807 return NT_STATUS_OK;
1810 /*******************************************************************
1811 _samr_query_userinfo
1812 ********************************************************************/
1814 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1816 SAM_USERINFO_CTR *ctr;
1817 struct samr_info *info = NULL;
1818 DOM_SID domain_sid;
1819 uint32 rid;
1821 r_u->status=NT_STATUS_OK;
1823 /* search for the handle */
1824 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1825 return NT_STATUS_INVALID_HANDLE;
1827 domain_sid = info->sid;
1829 sid_split_rid(&domain_sid, &rid);
1831 if (!sid_check_is_in_our_domain(&info->sid))
1832 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1834 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1836 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1837 if (!ctr)
1838 return NT_STATUS_NO_MEMORY;
1840 ZERO_STRUCTP(ctr);
1842 /* ok! user info levels (lots: see MSDEV help), off we go... */
1843 ctr->switch_value = q_u->switch_value;
1845 switch (q_u->switch_value) {
1846 case 0x10:
1847 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1848 if (ctr->info.id10 == NULL)
1849 return NT_STATUS_NO_MEMORY;
1851 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1852 return r_u->status;
1853 break;
1855 #if 0
1856 /* whoops - got this wrong. i think. or don't understand what's happening. */
1857 case 0x11:
1859 NTTIME expire;
1860 info = (void *)&id11;
1862 expire.low = 0xffffffff;
1863 expire.high = 0x7fffffff;
1865 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1866 sizeof
1867 (*ctr->
1868 info.
1869 id11));
1870 ZERO_STRUCTP(ctr->info.id11);
1871 init_sam_user_info11(ctr->info.id11, &expire,
1872 "BROOKFIELDS$", /* name */
1873 0x03ef, /* user rid */
1874 0x201, /* group rid */
1875 0x0080); /* acb info */
1877 break;
1879 #endif
1881 case 0x12:
1882 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1883 if (ctr->info.id12 == NULL)
1884 return NT_STATUS_NO_MEMORY;
1886 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1887 return r_u->status;
1888 break;
1890 case 20:
1891 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1892 if (ctr->info.id20 == NULL)
1893 return NT_STATUS_NO_MEMORY;
1894 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1895 return r_u->status;
1896 break;
1898 case 21:
1899 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1900 if (ctr->info.id21 == NULL)
1901 return NT_STATUS_NO_MEMORY;
1902 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1903 &info->sid, &domain_sid)))
1904 return r_u->status;
1905 break;
1907 default:
1908 return NT_STATUS_INVALID_INFO_CLASS;
1911 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1913 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1915 return r_u->status;
1918 /*******************************************************************
1919 samr_reply_query_usergroups
1920 ********************************************************************/
1922 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1924 SAM_ACCOUNT *sam_pass=NULL;
1925 DOM_SID sid;
1926 DOM_GID *gids = NULL;
1927 int num_groups = 0;
1928 uint32 acc_granted;
1929 BOOL ret;
1932 * from the SID in the request:
1933 * we should send back the list of DOMAIN GROUPS
1934 * the user is a member of
1936 * and only the DOMAIN GROUPS
1937 * no ALIASES !!! neither aliases of the domain
1938 * nor aliases of the builtin SID
1940 * JFM, 12/2/2001
1943 r_u->status = NT_STATUS_OK;
1945 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1947 /* find the policy handle. open a policy on it. */
1948 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1949 return NT_STATUS_INVALID_HANDLE;
1951 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1952 return r_u->status;
1955 if (!sid_check_is_in_our_domain(&sid))
1956 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1958 pdb_init_sam(&sam_pass);
1960 become_root();
1961 ret = pdb_getsampwsid(sam_pass, &sid);
1962 unbecome_root();
1964 if (ret == False) {
1965 pdb_free_sam(&sam_pass);
1966 return NT_STATUS_NO_SUCH_USER;
1969 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
1970 pdb_free_sam(&sam_pass);
1971 return NT_STATUS_NO_SUCH_GROUP;
1974 /* construct the response. lkclXXXX: gids are not copied! */
1975 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1977 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1979 pdb_free_sam(&sam_pass);
1981 return r_u->status;
1984 /*******************************************************************
1985 _samr_query_dom_info
1986 ********************************************************************/
1988 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1990 struct samr_info *info = NULL;
1991 SAM_UNK_CTR *ctr;
1992 uint32 min_pass_len,pass_hist,flag;
1993 time_t u_expire, u_min_age;
1994 NTTIME nt_expire, nt_min_age;
1996 time_t u_lock_duration, u_reset_time;
1997 NTTIME nt_lock_duration, nt_reset_time;
1998 uint32 lockout;
2000 time_t u_logout;
2001 NTTIME nt_logout;
2003 uint32 account_policy_temp;
2005 uint32 num_users=0, num_groups=0, num_aliases=0;
2007 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2008 return NT_STATUS_NO_MEMORY;
2010 ZERO_STRUCTP(ctr);
2012 r_u->status = NT_STATUS_OK;
2014 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2016 /* find the policy handle. open a policy on it. */
2017 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2018 return NT_STATUS_INVALID_HANDLE;
2020 switch (q_u->switch_value) {
2021 case 0x01:
2023 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2024 min_pass_len = account_policy_temp;
2026 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2027 pass_hist = account_policy_temp;
2029 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2030 flag = account_policy_temp;
2032 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2033 u_expire = account_policy_temp;
2035 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2036 u_min_age = account_policy_temp;
2038 unix_to_nt_time_abs(&nt_expire, u_expire);
2039 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2041 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2042 flag, nt_expire, nt_min_age);
2043 break;
2044 case 0x02:
2045 become_root();
2046 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2047 unbecome_root();
2048 if (!NT_STATUS_IS_OK(r_u->status)) {
2049 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2050 return r_u->status;
2052 num_users=info->disp_info.num_user_account;
2053 free_samr_db(info);
2055 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2056 if (!NT_STATUS_IS_OK(r_u->status)) {
2057 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2058 return r_u->status;
2060 num_groups=info->disp_info.num_group_account;
2061 free_samr_db(info);
2063 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2064 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2065 num_users, num_groups, num_aliases);
2066 break;
2067 case 0x03:
2068 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2069 unix_to_nt_time_abs(&nt_logout, u_logout);
2071 init_unk_info3(&ctr->info.inf3, nt_logout);
2072 break;
2073 case 0x05:
2074 init_unk_info5(&ctr->info.inf5, global_myname());
2075 break;
2076 case 0x06:
2077 init_unk_info6(&ctr->info.inf6);
2078 break;
2079 case 0x07:
2080 init_unk_info7(&ctr->info.inf7);
2081 break;
2082 case 0x0c:
2083 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2084 u_lock_duration = account_policy_temp;
2086 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2087 u_reset_time = account_policy_temp;
2089 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2090 lockout = account_policy_temp;
2092 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2093 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2095 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2096 break;
2097 default:
2098 return NT_STATUS_INVALID_INFO_CLASS;
2101 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2103 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2105 return r_u->status;
2108 /*******************************************************************
2109 _samr_create_user
2110 Create an account, can be either a normal user or a machine.
2111 This funcion will need to be updated for bdc/domain trusts.
2112 ********************************************************************/
2114 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2116 SAM_ACCOUNT *sam_pass=NULL;
2117 fstring account;
2118 DOM_SID sid;
2119 pstring add_script;
2120 POLICY_HND dom_pol = q_u->domain_pol;
2121 UNISTR2 user_account = q_u->uni_name;
2122 uint16 acb_info = q_u->acb_info;
2123 POLICY_HND *user_pol = &r_u->user_pol;
2124 struct samr_info *info = NULL;
2125 BOOL ret;
2126 NTSTATUS nt_status;
2127 struct passwd *pw;
2128 uint32 acc_granted;
2129 SEC_DESC *psd;
2130 size_t sd_size;
2131 uint32 new_rid = 0;
2132 /* check this, when giving away 'add computer to domain' privs */
2133 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2135 /* Get the domain SID stored in the domain policy */
2136 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2137 return NT_STATUS_INVALID_HANDLE;
2139 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2140 return nt_status;
2143 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2144 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2145 this parameter is not an account type */
2146 return NT_STATUS_INVALID_PARAMETER;
2149 /* find the account: tell the caller if it exists.
2150 lkclXXXX i have *no* idea if this is a problem or not
2151 or even if you are supposed to construct a different
2152 reply if the account already exists...
2155 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2156 strlower_m(account);
2158 pdb_init_sam(&sam_pass);
2160 become_root();
2161 ret = pdb_getsampwnam(sam_pass, account);
2162 unbecome_root();
2163 if (ret == True) {
2164 /* this account exists: say so */
2165 pdb_free_sam(&sam_pass);
2166 return NT_STATUS_USER_EXISTS;
2169 pdb_free_sam(&sam_pass);
2172 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2173 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2174 * that only people with write access to the smbpasswd file will be able
2175 * to create a user. JRA.
2179 * add the user in the /etc/passwd file or the unix authority system.
2180 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2181 * a) local_password_change() checks for us if the /etc/passwd account really exists
2182 * b) smb_create_user() would return an error if the account already exists
2183 * and as it could return an error also if it can't create the account, it would be tricky.
2185 * So we go the easy way, only check after if the account exists.
2186 * JFM (2/3/2001), to clear any possible bad understanding (-:
2188 * We now have seperate script paramaters for adding users/machines so we
2189 * now have some sainity-checking to match.
2192 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2195 * we used to have code here that made sure the acb_info flags
2196 * matched with the users named (e.g. an account flags as a machine
2197 * trust account ended in '$'). It has been ifdef'd out for a long
2198 * time, so I replaced it with this comment. --jerry
2201 /* the passdb lookup has failed; check to see if we need to run the
2202 add user/machine script */
2204 pw = Get_Pwnam(account);
2206 /*********************************************************************
2207 * HEADS UP! If we have to create a new user account, we have to get
2208 * a new RID from somewhere. This used to be done by the passdb
2209 * backend. It has been moved into idmap now. Since idmap is now
2210 * wrapped up behind winbind, this means you have to run winbindd if you
2211 * want new accounts to get a new RID when "enable rid algorithm = no".
2212 * Tough. We now have a uniform way of allocating RIDs regardless
2213 * of what ever passdb backend people may use.
2214 * --jerry (2003-07-10)
2215 *********************************************************************/
2217 if ( !pw ) {
2219 * we can't check both the ending $ and the acb_info.
2221 * UserManager creates trust accounts (ending in $,
2222 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2223 * JFM, 11/29/2001
2225 if (account[strlen(account)-1] == '$')
2226 pstrcpy(add_script, lp_addmachine_script());
2227 else
2228 pstrcpy(add_script, lp_adduser_script());
2230 if (*add_script) {
2231 int add_ret;
2232 all_string_sub(add_script, "%u", account, sizeof(account));
2233 add_ret = smbrun(add_script,NULL);
2234 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2236 else /* no add user script -- ask winbindd to do it */
2238 if ( !winbind_create_user( account, &new_rid ) ) {
2239 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2240 account));
2246 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2248 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2249 return nt_status;
2251 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2253 if (!pdb_add_sam_account(sam_pass)) {
2254 pdb_free_sam(&sam_pass);
2255 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2256 account));
2257 return NT_STATUS_ACCESS_DENIED;
2260 /* Get the user's SID */
2261 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2263 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2264 se_map_generic(&des_access, &usr_generic_mapping);
2265 if (!NT_STATUS_IS_OK(nt_status =
2266 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2267 des_access, &acc_granted, "_samr_create_user"))) {
2268 return nt_status;
2271 /* associate the user's SID with the new handle. */
2272 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2273 pdb_free_sam(&sam_pass);
2274 return NT_STATUS_NO_MEMORY;
2277 ZERO_STRUCTP(info);
2278 info->sid = sid;
2279 info->acc_granted = acc_granted;
2281 /* get a (unique) handle. open a policy on it. */
2282 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2283 pdb_free_sam(&sam_pass);
2284 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2287 r_u->user_rid=pdb_get_user_rid(sam_pass);
2289 r_u->access_granted = acc_granted;
2291 pdb_free_sam(&sam_pass);
2293 return NT_STATUS_OK;
2296 /*******************************************************************
2297 samr_reply_connect_anon
2298 ********************************************************************/
2300 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2302 struct samr_info *info = NULL;
2303 uint32 des_access = q_u->access_mask;
2305 /* Access check */
2307 if (!pipe_access_check(p)) {
2308 DEBUG(3, ("access denied to samr_connect_anon\n"));
2309 r_u->status = NT_STATUS_ACCESS_DENIED;
2310 return r_u->status;
2313 /* set up the SAMR connect_anon response */
2315 r_u->status = NT_STATUS_OK;
2317 /* associate the user's SID with the new handle. */
2318 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2319 return NT_STATUS_NO_MEMORY;
2321 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2322 was observed from a win98 client trying to enumerate users (when configured
2323 user level access control on shares) --jerry */
2325 se_map_generic( &des_access, &sam_generic_mapping );
2326 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2328 info->status = q_u->unknown_0;
2330 /* get a (unique) handle. open a policy on it. */
2331 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2332 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2334 return r_u->status;
2337 /*******************************************************************
2338 samr_reply_connect
2339 ********************************************************************/
2341 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2343 struct samr_info *info = NULL;
2344 SEC_DESC *psd = NULL;
2345 uint32 acc_granted;
2346 uint32 des_access = q_u->access_mask;
2347 size_t sd_size;
2348 NTSTATUS nt_status;
2351 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2353 /* Access check */
2355 if (!pipe_access_check(p)) {
2356 DEBUG(3, ("access denied to samr_connect\n"));
2357 r_u->status = NT_STATUS_ACCESS_DENIED;
2358 return r_u->status;
2361 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2362 se_map_generic(&des_access, &sam_generic_mapping);
2363 if (!NT_STATUS_IS_OK(nt_status =
2364 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2365 des_access, &acc_granted, "_samr_connect"))) {
2366 return nt_status;
2369 r_u->status = NT_STATUS_OK;
2371 /* associate the user's SID and access granted with the new handle. */
2372 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2373 return NT_STATUS_NO_MEMORY;
2375 info->acc_granted = acc_granted;
2376 info->status = q_u->access_mask;
2378 /* get a (unique) handle. open a policy on it. */
2379 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2380 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2382 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2384 return r_u->status;
2387 /*******************************************************************
2388 samr_connect4
2389 ********************************************************************/
2391 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2393 struct samr_info *info = NULL;
2394 SEC_DESC *psd = NULL;
2395 uint32 acc_granted;
2396 uint32 des_access = q_u->access_mask;
2397 size_t sd_size;
2398 NTSTATUS nt_status;
2401 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2403 /* Access check */
2405 if (!pipe_access_check(p)) {
2406 DEBUG(3, ("access denied to samr_connect4\n"));
2407 r_u->status = NT_STATUS_ACCESS_DENIED;
2408 return r_u->status;
2411 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2412 se_map_generic(&des_access, &sam_generic_mapping);
2413 if (!NT_STATUS_IS_OK(nt_status =
2414 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2415 des_access, &acc_granted, "_samr_connect"))) {
2416 return nt_status;
2419 r_u->status = NT_STATUS_OK;
2421 /* associate the user's SID and access granted with the new handle. */
2422 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2423 return NT_STATUS_NO_MEMORY;
2425 info->acc_granted = acc_granted;
2426 info->status = q_u->access_mask;
2428 /* get a (unique) handle. open a policy on it. */
2429 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2430 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2432 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2434 return r_u->status;
2437 /**********************************************************************
2438 api_samr_lookup_domain
2439 **********************************************************************/
2441 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2443 struct samr_info *info;
2444 fstring domain_name;
2445 DOM_SID sid;
2447 r_u->status = NT_STATUS_OK;
2449 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2450 return NT_STATUS_INVALID_HANDLE;
2452 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2453 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2455 return r_u->status;
2458 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2460 ZERO_STRUCT(sid);
2462 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2463 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2466 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2468 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2470 return r_u->status;
2473 /******************************************************************
2474 makes a SAMR_R_ENUM_DOMAINS structure.
2475 ********************************************************************/
2477 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2478 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2480 uint32 i;
2481 SAM_ENTRY *sam;
2482 UNISTR2 *uni_name;
2484 DEBUG(5, ("make_enum_domains\n"));
2486 *pp_sam = NULL;
2487 *pp_uni_name = NULL;
2489 if (num_sam_entries == 0)
2490 return True;
2492 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2493 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2495 if (sam == NULL || uni_name == NULL)
2496 return False;
2498 for (i = 0; i < num_sam_entries; i++) {
2499 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2500 init_sam_entry(&sam[i], &uni_name[i], 0);
2503 *pp_sam = sam;
2504 *pp_uni_name = uni_name;
2506 return True;
2509 /**********************************************************************
2510 api_samr_enum_domains
2511 **********************************************************************/
2513 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2515 struct samr_info *info;
2516 uint32 num_entries = 2;
2517 fstring dom[2];
2518 const char *name;
2520 r_u->status = NT_STATUS_OK;
2522 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2523 return NT_STATUS_INVALID_HANDLE;
2525 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2526 return r_u->status;
2529 name = get_global_sam_name();
2531 fstrcpy(dom[0],name);
2532 strupper_m(dom[0]);
2533 fstrcpy(dom[1],"Builtin");
2535 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2536 return NT_STATUS_NO_MEMORY;
2538 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2540 return r_u->status;
2543 /*******************************************************************
2544 api_samr_open_alias
2545 ********************************************************************/
2547 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2549 DOM_SID sid;
2550 POLICY_HND domain_pol = q_u->dom_pol;
2551 uint32 alias_rid = q_u->rid_alias;
2552 POLICY_HND *alias_pol = &r_u->pol;
2553 struct samr_info *info = NULL;
2554 SEC_DESC *psd = NULL;
2555 uint32 acc_granted;
2556 uint32 des_access = q_u->access_mask;
2557 size_t sd_size;
2558 NTSTATUS status;
2560 r_u->status = NT_STATUS_OK;
2562 /* find the domain policy and get the SID / access bits stored in the domain policy */
2563 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2564 return NT_STATUS_INVALID_HANDLE;
2566 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2567 return status;
2570 /* append the alias' RID to it */
2571 if (!sid_append_rid(&sid, alias_rid))
2572 return NT_STATUS_NO_SUCH_USER;
2574 /*check if access can be granted as requested by client. */
2575 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2576 se_map_generic(&des_access,&ali_generic_mapping);
2577 if (!NT_STATUS_IS_OK(status =
2578 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2579 des_access, &acc_granted, "_samr_open_alias"))) {
2580 return status;
2584 * we should check if the rid really exist !!!
2585 * JFM.
2588 /* associate the user's SID with the new handle. */
2589 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2590 return NT_STATUS_NO_MEMORY;
2592 info->acc_granted = acc_granted;
2594 /* get a (unique) handle. open a policy on it. */
2595 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2596 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2598 return r_u->status;
2601 /*******************************************************************
2602 set_user_info_10
2603 ********************************************************************/
2605 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2607 SAM_ACCOUNT *pwd =NULL;
2608 BOOL ret;
2610 pdb_init_sam(&pwd);
2612 ret = pdb_getsampwsid(pwd, sid);
2614 if(ret==False) {
2615 pdb_free_sam(&pwd);
2616 return False;
2619 if (id10 == NULL) {
2620 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2621 pdb_free_sam(&pwd);
2622 return False;
2625 /* FIX ME: check if the value is really changed --metze */
2626 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2627 pdb_free_sam(&pwd);
2628 return False;
2631 if(!pdb_update_sam_account(pwd)) {
2632 pdb_free_sam(&pwd);
2633 return False;
2636 pdb_free_sam(&pwd);
2638 return True;
2641 /*******************************************************************
2642 set_user_info_12
2643 ********************************************************************/
2645 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2647 SAM_ACCOUNT *pwd = NULL;
2649 pdb_init_sam(&pwd);
2651 if(!pdb_getsampwsid(pwd, sid)) {
2652 pdb_free_sam(&pwd);
2653 return False;
2656 if (id12 == NULL) {
2657 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2658 pdb_free_sam(&pwd);
2659 return False;
2662 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2663 pdb_free_sam(&pwd);
2664 return False;
2666 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2667 pdb_free_sam(&pwd);
2668 return False;
2670 if (!pdb_set_pass_changed_now (pwd)) {
2671 pdb_free_sam(&pwd);
2672 return False;
2675 if(!pdb_update_sam_account(pwd)) {
2676 pdb_free_sam(&pwd);
2677 return False;
2680 pdb_free_sam(&pwd);
2681 return True;
2684 /*******************************************************************
2685 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2686 ********************************************************************/
2687 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2689 struct group *grp;
2690 gid_t gid;
2692 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2693 &gid))) {
2694 DEBUG(2,("Could not get gid for primary group of "
2695 "user %s\n", pdb_get_username(sampass)));
2696 return False;
2699 grp = getgrgid(gid);
2701 if (grp == NULL) {
2702 DEBUG(2,("Could not find primary group %lu for "
2703 "user %s\n", (unsigned long)gid,
2704 pdb_get_username(sampass)));
2705 return False;
2708 if (smb_set_primary_group(grp->gr_name,
2709 pdb_get_username(sampass)) != 0) {
2710 DEBUG(2,("Could not set primary group for user %s to "
2711 "%s\n",
2712 pdb_get_username(sampass), grp->gr_name));
2713 return False;
2716 return True;
2720 /*******************************************************************
2721 set_user_info_20
2722 ********************************************************************/
2724 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2726 SAM_ACCOUNT *pwd = NULL;
2728 if (id20 == NULL) {
2729 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2730 return False;
2733 pdb_init_sam(&pwd);
2735 if (!pdb_getsampwsid(pwd, sid)) {
2736 pdb_free_sam(&pwd);
2737 return False;
2740 copy_id20_to_sam_passwd(pwd, id20);
2742 /* write the change out */
2743 if(!pdb_update_sam_account(pwd)) {
2744 pdb_free_sam(&pwd);
2745 return False;
2748 pdb_free_sam(&pwd);
2750 return True;
2752 /*******************************************************************
2753 set_user_info_21
2754 ********************************************************************/
2756 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2758 SAM_ACCOUNT *pwd = NULL;
2760 if (id21 == NULL) {
2761 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2762 return False;
2765 pdb_init_sam(&pwd);
2767 if (!pdb_getsampwsid(pwd, sid)) {
2768 pdb_free_sam(&pwd);
2769 return False;
2772 copy_id21_to_sam_passwd(pwd, id21);
2775 * The funny part about the previous two calls is
2776 * that pwd still has the password hashes from the
2777 * passdb entry. These have not been updated from
2778 * id21. I don't know if they need to be set. --jerry
2781 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2782 set_unix_primary_group(pwd);
2784 /* write the change out */
2785 if(!pdb_update_sam_account(pwd)) {
2786 pdb_free_sam(&pwd);
2787 return False;
2790 pdb_free_sam(&pwd);
2792 return True;
2795 /*******************************************************************
2796 set_user_info_23
2797 ********************************************************************/
2799 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2801 SAM_ACCOUNT *pwd = NULL;
2802 pstring plaintext_buf;
2803 uint32 len;
2804 uint16 acct_ctrl;
2806 if (id23 == NULL) {
2807 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2808 return False;
2811 pdb_init_sam(&pwd);
2813 if (!pdb_getsampwsid(pwd, sid)) {
2814 pdb_free_sam(&pwd);
2815 return False;
2818 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2819 pdb_get_username(pwd)));
2821 acct_ctrl = pdb_get_acct_ctrl(pwd);
2823 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2824 pdb_free_sam(&pwd);
2825 return False;
2828 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2829 pdb_free_sam(&pwd);
2830 return False;
2833 copy_id23_to_sam_passwd(pwd, id23);
2835 /* if it's a trust account, don't update /etc/passwd */
2836 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2837 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2838 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2839 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2840 } else {
2841 /* update the UNIX password */
2842 if (lp_unix_password_sync() ) {
2843 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2844 if (!passwd) {
2845 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2848 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2849 pdb_free_sam(&pwd);
2850 return False;
2855 ZERO_STRUCT(plaintext_buf);
2857 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2858 set_unix_primary_group(pwd);
2860 if(!pdb_update_sam_account(pwd)) {
2861 pdb_free_sam(&pwd);
2862 return False;
2865 pdb_free_sam(&pwd);
2867 return True;
2870 /*******************************************************************
2871 set_user_info_pw
2872 ********************************************************************/
2874 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2876 SAM_ACCOUNT *pwd = NULL;
2877 uint32 len;
2878 pstring plaintext_buf;
2879 uint16 acct_ctrl;
2881 pdb_init_sam(&pwd);
2883 if (!pdb_getsampwsid(pwd, sid)) {
2884 pdb_free_sam(&pwd);
2885 return False;
2888 DEBUG(5, ("Attempting administrator password change for user %s\n",
2889 pdb_get_username(pwd)));
2891 acct_ctrl = pdb_get_acct_ctrl(pwd);
2893 ZERO_STRUCT(plaintext_buf);
2895 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2896 pdb_free_sam(&pwd);
2897 return False;
2900 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2901 pdb_free_sam(&pwd);
2902 return False;
2905 /* if it's a trust account, don't update /etc/passwd */
2906 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2907 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2908 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2909 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2910 } else {
2911 /* update the UNIX password */
2912 if (lp_unix_password_sync()) {
2913 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2914 if (!passwd) {
2915 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2918 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2919 pdb_free_sam(&pwd);
2920 return False;
2925 ZERO_STRUCT(plaintext_buf);
2927 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2929 /* update the SAMBA password */
2930 if(!pdb_update_sam_account(pwd)) {
2931 pdb_free_sam(&pwd);
2932 return False;
2935 pdb_free_sam(&pwd);
2937 return True;
2940 /*******************************************************************
2941 samr_reply_set_userinfo
2942 ********************************************************************/
2944 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2946 DOM_SID sid;
2947 POLICY_HND *pol = &q_u->pol;
2948 uint16 switch_value = q_u->switch_value;
2949 SAM_USERINFO_CTR *ctr = q_u->ctr;
2950 uint32 acc_granted;
2951 uint32 acc_required;
2953 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2955 r_u->status = NT_STATUS_OK;
2957 /* find the policy handle. open a policy on it. */
2958 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2959 return NT_STATUS_INVALID_HANDLE;
2961 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2962 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2963 return r_u->status;
2966 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2968 if (ctr == NULL) {
2969 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2970 return NT_STATUS_INVALID_INFO_CLASS;
2973 /* ok! user info levels (lots: see MSDEV help), off we go... */
2974 switch (switch_value) {
2975 case 0x12:
2976 if (!set_user_info_12(ctr->info.id12, &sid))
2977 return NT_STATUS_ACCESS_DENIED;
2978 break;
2980 case 24:
2981 if (!p->session_key.length) {
2982 return NT_STATUS_NO_USER_SESSION_KEY;
2984 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
2986 dump_data(100, (char *)ctr->info.id24->pass, 516);
2988 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2989 return NT_STATUS_ACCESS_DENIED;
2990 break;
2992 case 25:
2993 #if 0
2995 * Currently we don't really know how to unmarshall
2996 * the level 25 struct, and the password encryption
2997 * is different. This is a placeholder for when we
2998 * do understand it. In the meantime just return INVALID
2999 * info level and W2K SP2 drops down to level 23... JRA.
3002 if (!p->session_key.length) {
3003 return NT_STATUS_NO_USER_SESSION_KEY;
3005 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3007 dump_data(100, (char *)ctr->info.id25->pass, 532);
3009 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3010 return NT_STATUS_ACCESS_DENIED;
3011 break;
3012 #endif
3013 return NT_STATUS_INVALID_INFO_CLASS;
3015 case 23:
3016 if (!p->session_key.length) {
3017 return NT_STATUS_NO_USER_SESSION_KEY;
3019 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3021 dump_data(100, (char *)ctr->info.id23->pass, 516);
3023 if (!set_user_info_23(ctr->info.id23, &sid))
3024 return NT_STATUS_ACCESS_DENIED;
3025 break;
3027 default:
3028 return NT_STATUS_INVALID_INFO_CLASS;
3031 return r_u->status;
3034 /*******************************************************************
3035 samr_reply_set_userinfo2
3036 ********************************************************************/
3038 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3040 DOM_SID sid;
3041 SAM_USERINFO_CTR *ctr = q_u->ctr;
3042 POLICY_HND *pol = &q_u->pol;
3043 uint16 switch_value = q_u->switch_value;
3044 uint32 acc_granted;
3045 uint32 acc_required;
3047 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3049 r_u->status = NT_STATUS_OK;
3051 /* find the policy handle. open a policy on it. */
3052 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3053 return NT_STATUS_INVALID_HANDLE;
3055 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3056 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3057 return r_u->status;
3060 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3062 if (ctr == NULL) {
3063 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3064 return NT_STATUS_INVALID_INFO_CLASS;
3067 switch_value=ctr->switch_value;
3069 /* ok! user info levels (lots: see MSDEV help), off we go... */
3070 switch (switch_value) {
3071 case 21:
3072 if (!set_user_info_21(ctr->info.id21, &sid))
3073 return NT_STATUS_ACCESS_DENIED;
3074 break;
3075 case 20:
3076 if (!set_user_info_20(ctr->info.id20, &sid))
3077 return NT_STATUS_ACCESS_DENIED;
3078 break;
3079 case 16:
3080 if (!set_user_info_10(ctr->info.id10, &sid))
3081 return NT_STATUS_ACCESS_DENIED;
3082 break;
3083 case 18:
3084 /* Used by AS/U JRA. */
3085 if (!set_user_info_12(ctr->info.id12, &sid))
3086 return NT_STATUS_ACCESS_DENIED;
3087 break;
3088 default:
3089 return NT_STATUS_INVALID_INFO_CLASS;
3092 return r_u->status;
3095 /*********************************************************************
3096 _samr_query_aliasmem
3097 *********************************************************************/
3099 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3101 int num_groups = 0, tmp_num_groups=0;
3102 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3103 struct samr_info *info = NULL;
3104 int i,j;
3106 NTSTATUS ntstatus1;
3107 NTSTATUS ntstatus2;
3109 /* until i see a real useraliases query, we fack one up */
3111 /* I have seen one, JFM 2/12/2001 */
3113 * Explanation of what this call does:
3114 * for all the SID given in the request:
3115 * return a list of alias (local groups)
3116 * that have those SID as members.
3118 * and that's the alias in the domain specified
3119 * in the policy_handle
3121 * if the policy handle is on an incorrect sid
3122 * for example a user's sid
3123 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3126 r_u->status = NT_STATUS_OK;
3128 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3130 /* find the policy handle. open a policy on it. */
3131 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3132 return NT_STATUS_INVALID_HANDLE;
3134 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3135 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3137 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3138 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3139 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3140 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3144 if (!sid_check_is_domain(&info->sid) &&
3145 !sid_check_is_builtin(&info->sid))
3146 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3149 for (i=0; i<q_u->num_sids1; i++) {
3151 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3154 * if there is an error, we just continue as
3155 * it can be an unfound user or group
3157 if (!NT_STATUS_IS_OK(r_u->status)) {
3158 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3159 continue;
3162 if (tmp_num_groups==0) {
3163 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3164 continue;
3167 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3168 if (new_rids==NULL) {
3169 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3170 return NT_STATUS_NO_MEMORY;
3172 rids=new_rids;
3174 for (j=0; j<tmp_num_groups; j++)
3175 rids[j+num_groups]=tmp_rids[j];
3177 safe_free(tmp_rids);
3179 num_groups+=tmp_num_groups;
3182 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3183 return NT_STATUS_OK;
3186 /*********************************************************************
3187 _samr_query_aliasmem
3188 *********************************************************************/
3190 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3192 int i;
3194 GROUP_MAP map;
3195 int num_sids = 0;
3196 DOM_SID2 *sid;
3197 DOM_SID *sids=NULL;
3199 DOM_SID alias_sid;
3200 DOM_SID als_sid;
3201 uint32 alias_rid;
3202 fstring alias_sid_str;
3204 uint32 acc_granted;
3206 /* find the policy handle. open a policy on it. */
3207 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3208 return NT_STATUS_INVALID_HANDLE;
3210 if (!NT_STATUS_IS_OK(r_u->status =
3211 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3212 return r_u->status;
3215 sid_copy(&als_sid, &alias_sid);
3216 sid_to_string(alias_sid_str, &alias_sid);
3217 sid_split_rid(&alias_sid, &alias_rid);
3219 DEBUG(10, ("sid is %s\n", alias_sid_str));
3221 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3222 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3223 if(!get_builtin_group_from_sid(&als_sid, &map))
3224 return NT_STATUS_NO_SUCH_ALIAS;
3225 } else {
3226 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3227 DEBUG(10, ("lookup on Server SID\n"));
3228 if(!get_local_group_from_sid(&als_sid, &map)) {
3229 fstring alias_sid_string;
3230 DEBUG(10, ("Alias %s not found\n", sid_to_string(alias_sid_string, &als_sid)));
3231 return NT_STATUS_NO_SUCH_ALIAS;
3236 if (!get_sid_list_of_group(map.gid, &sids, &num_sids)) {
3237 fstring alias_sid_string;
3238 DEBUG(10, ("Alias %s found, but member list unavailable\n", sid_to_string(alias_sid_string, &als_sid)));
3239 return NT_STATUS_NO_SUCH_ALIAS;
3242 DEBUG(10, ("sid is %s\n", alias_sid_str));
3243 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_sids);
3244 if (num_sids!=0 && sid == NULL) {
3245 SAFE_FREE(sids);
3246 return NT_STATUS_NO_MEMORY;
3249 for (i = 0; i < num_sids; i++) {
3250 init_dom_sid2(&sid[i], &sids[i]);
3253 DEBUG(10, ("sid is %s\n", alias_sid_str));
3254 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3256 SAFE_FREE(sids);
3258 return NT_STATUS_OK;
3261 /*********************************************************************
3262 _samr_query_groupmem
3263 *********************************************************************/
3265 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3267 int num_sids = 0;
3268 int final_num_sids = 0;
3269 int i;
3270 DOM_SID group_sid;
3271 fstring group_sid_str;
3272 DOM_SID *sids=NULL;
3274 GROUP_MAP map;
3276 uint32 *rid=NULL;
3277 uint32 *attr=NULL;
3279 uint32 acc_granted;
3281 /* find the policy handle. open a policy on it. */
3282 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3283 return NT_STATUS_INVALID_HANDLE;
3285 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3286 return r_u->status;
3289 sid_to_string(group_sid_str, &group_sid);
3290 DEBUG(10, ("sid is %s\n", group_sid_str));
3292 if (!sid_check_is_in_our_domain(&group_sid)) {
3293 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3294 return NT_STATUS_NO_SUCH_GROUP;
3297 DEBUG(10, ("lookup on Domain SID\n"));
3299 if(!get_domain_group_from_sid(group_sid, &map))
3300 return NT_STATUS_NO_SUCH_GROUP;
3302 if(!get_sid_list_of_group(map.gid, &sids, &num_sids))
3303 return NT_STATUS_NO_SUCH_GROUP;
3305 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_sids);
3306 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_sids);
3308 if (num_sids!=0 && (rid==NULL || attr==NULL))
3309 return NT_STATUS_NO_MEMORY;
3311 for (i=0; i<num_sids; i++) {
3312 uint32 urid;
3314 if (sid_peek_check_rid(get_global_sam_sid(), &sids[i], &urid)) {
3315 rid[final_num_sids] = urid;
3316 attr[final_num_sids] = SID_NAME_USER;
3317 final_num_sids++;
3318 } else {
3319 fstring user_sid_str, domain_sid_str;
3320 DEBUG(1, ("_samr_query_groupmem: SID %s in group %s is not in our domain %s\n",
3321 sid_to_string(user_sid_str, &sids[i]),
3322 sid_to_string(group_sid_str, &group_sid),
3323 sid_to_string(domain_sid_str, get_global_sam_sid())));
3327 init_samr_r_query_groupmem(r_u, final_num_sids, rid, attr, NT_STATUS_OK);
3329 return NT_STATUS_OK;
3332 /*********************************************************************
3333 _samr_add_aliasmem
3334 *********************************************************************/
3336 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3338 DOM_SID alias_sid;
3339 fstring alias_sid_str;
3340 uid_t uid;
3341 struct passwd *pwd;
3342 struct group *grp;
3343 fstring grp_name;
3344 GROUP_MAP map;
3345 NTSTATUS ret;
3346 SAM_ACCOUNT *sam_user = NULL;
3347 BOOL check;
3348 uint32 acc_granted;
3350 /* Find the policy handle. Open a policy on it. */
3351 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3352 return NT_STATUS_INVALID_HANDLE;
3354 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3355 return r_u->status;
3358 sid_to_string(alias_sid_str, &alias_sid);
3359 DEBUG(10, ("sid is %s\n", alias_sid_str));
3361 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3362 DEBUG(10, ("adding member on Server SID\n"));
3363 if(!get_local_group_from_sid(&alias_sid, &map))
3364 return NT_STATUS_NO_SUCH_ALIAS;
3366 } else {
3367 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3368 DEBUG(10, ("adding member on BUILTIN SID\n"));
3369 if( !get_builtin_group_from_sid(&alias_sid, &map))
3370 return NT_STATUS_NO_SUCH_ALIAS;
3372 } else
3373 return NT_STATUS_NO_SUCH_ALIAS;
3376 ret = pdb_init_sam(&sam_user);
3377 if (!NT_STATUS_IS_OK(ret))
3378 return ret;
3380 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3382 if (check != True) {
3383 pdb_free_sam(&sam_user);
3384 return NT_STATUS_NO_SUCH_USER;
3387 /* check a real user exist before we run the script to add a user to a group */
3388 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3389 pdb_free_sam(&sam_user);
3390 return NT_STATUS_NO_SUCH_USER;
3393 pdb_free_sam(&sam_user);
3395 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3396 return NT_STATUS_NO_SUCH_USER;
3399 if ((grp=getgrgid(map.gid)) == NULL) {
3400 passwd_free(&pwd);
3401 return NT_STATUS_NO_SUCH_ALIAS;
3404 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3405 fstrcpy(grp_name, grp->gr_name);
3407 /* if the user is already in the group */
3408 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3409 passwd_free(&pwd);
3410 return NT_STATUS_MEMBER_IN_ALIAS;
3414 * ok, the group exist, the user exist, the user is not in the group,
3415 * we can (finally) add it to the group !
3417 smb_add_user_group(grp_name, pwd->pw_name);
3419 /* check if the user has been added then ... */
3420 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3421 passwd_free(&pwd);
3422 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3425 passwd_free(&pwd);
3426 return NT_STATUS_OK;
3429 /*********************************************************************
3430 _samr_del_aliasmem
3431 *********************************************************************/
3433 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3435 DOM_SID alias_sid;
3436 fstring alias_sid_str;
3437 struct group *grp;
3438 fstring grp_name;
3439 GROUP_MAP map;
3440 SAM_ACCOUNT *sam_pass=NULL;
3441 uint32 acc_granted;
3443 /* Find the policy handle. Open a policy on it. */
3444 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3445 return NT_STATUS_INVALID_HANDLE;
3447 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3448 return r_u->status;
3451 sid_to_string(alias_sid_str, &alias_sid);
3452 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3454 if (!sid_check_is_in_our_domain(&alias_sid) &&
3455 !sid_check_is_in_builtin(&alias_sid)) {
3456 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3457 return NT_STATUS_NO_SUCH_ALIAS;
3460 if( !get_local_group_from_sid(&alias_sid, &map))
3461 return NT_STATUS_NO_SUCH_ALIAS;
3463 if ((grp=getgrgid(map.gid)) == NULL)
3464 return NT_STATUS_NO_SUCH_ALIAS;
3466 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3467 fstrcpy(grp_name, grp->gr_name);
3469 /* check if the user exists before trying to remove it from the group */
3470 pdb_init_sam(&sam_pass);
3471 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3472 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3473 pdb_free_sam(&sam_pass);
3474 return NT_STATUS_NO_SUCH_USER;
3477 /* if the user is not in the group */
3478 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3479 pdb_free_sam(&sam_pass);
3480 return NT_STATUS_MEMBER_IN_ALIAS;
3483 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3485 /* check if the user has been removed then ... */
3486 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3487 pdb_free_sam(&sam_pass);
3488 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3491 pdb_free_sam(&sam_pass);
3492 return NT_STATUS_OK;
3495 /*********************************************************************
3496 _samr_add_groupmem
3497 *********************************************************************/
3499 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3501 DOM_SID group_sid;
3502 DOM_SID user_sid;
3503 fstring group_sid_str;
3504 uid_t uid;
3505 struct passwd *pwd;
3506 struct group *grp;
3507 fstring grp_name;
3508 GROUP_MAP map;
3509 NTSTATUS ret;
3510 SAM_ACCOUNT *sam_user=NULL;
3511 BOOL check;
3512 uint32 acc_granted;
3514 /* Find the policy handle. Open a policy on it. */
3515 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3516 return NT_STATUS_INVALID_HANDLE;
3518 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3519 return r_u->status;
3522 sid_to_string(group_sid_str, &group_sid);
3523 DEBUG(10, ("sid is %s\n", group_sid_str));
3525 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3526 return NT_STATUS_NO_SUCH_GROUP;
3528 DEBUG(10, ("lookup on Domain SID\n"));
3530 if(!get_domain_group_from_sid(group_sid, &map))
3531 return NT_STATUS_NO_SUCH_GROUP;
3533 sid_copy(&user_sid, get_global_sam_sid());
3534 sid_append_rid(&user_sid, q_u->rid);
3536 ret = pdb_init_sam(&sam_user);
3537 if (!NT_STATUS_IS_OK(ret))
3538 return ret;
3540 check = pdb_getsampwsid(sam_user, &user_sid);
3542 if (check != True) {
3543 pdb_free_sam(&sam_user);
3544 return NT_STATUS_NO_SUCH_USER;
3547 /* check a real user exist before we run the script to add a user to a group */
3548 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3549 pdb_free_sam(&sam_user);
3550 return NT_STATUS_NO_SUCH_USER;
3553 pdb_free_sam(&sam_user);
3555 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3556 return NT_STATUS_NO_SUCH_USER;
3559 if ((grp=getgrgid(map.gid)) == NULL) {
3560 passwd_free(&pwd);
3561 return NT_STATUS_NO_SUCH_GROUP;
3564 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3565 fstrcpy(grp_name, grp->gr_name);
3567 /* if the user is already in the group */
3568 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3569 passwd_free(&pwd);
3570 return NT_STATUS_MEMBER_IN_GROUP;
3574 * ok, the group exist, the user exist, the user is not in the group,
3576 * we can (finally) add it to the group !
3579 smb_add_user_group(grp_name, pwd->pw_name);
3581 /* check if the user has been added then ... */
3582 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3583 passwd_free(&pwd);
3584 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3587 passwd_free(&pwd);
3588 return NT_STATUS_OK;
3591 /*********************************************************************
3592 _samr_del_groupmem
3593 *********************************************************************/
3595 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3597 DOM_SID group_sid;
3598 DOM_SID user_sid;
3599 SAM_ACCOUNT *sam_pass=NULL;
3600 GROUP_MAP map;
3601 fstring grp_name;
3602 struct group *grp;
3603 uint32 acc_granted;
3606 * delete the group member named q_u->rid
3607 * who is a member of the sid associated with the handle
3608 * the rid is a user's rid as the group is a domain group.
3611 /* Find the policy handle. Open a policy on it. */
3612 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3613 return NT_STATUS_INVALID_HANDLE;
3615 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3616 return r_u->status;
3619 if (!sid_check_is_in_our_domain(&group_sid))
3620 return NT_STATUS_NO_SUCH_GROUP;
3622 sid_copy(&user_sid, get_global_sam_sid());
3623 sid_append_rid(&user_sid, q_u->rid);
3625 if (!get_domain_group_from_sid(group_sid, &map))
3626 return NT_STATUS_NO_SUCH_GROUP;
3628 if ((grp=getgrgid(map.gid)) == NULL)
3629 return NT_STATUS_NO_SUCH_GROUP;
3631 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3632 fstrcpy(grp_name, grp->gr_name);
3634 /* check if the user exists before trying to remove it from the group */
3635 pdb_init_sam(&sam_pass);
3636 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3637 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3638 pdb_free_sam(&sam_pass);
3639 return NT_STATUS_NO_SUCH_USER;
3642 /* if the user is not in the group */
3643 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3644 pdb_free_sam(&sam_pass);
3645 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3648 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3650 /* check if the user has been removed then ... */
3651 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3652 pdb_free_sam(&sam_pass);
3653 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3656 pdb_free_sam(&sam_pass);
3657 return NT_STATUS_OK;
3661 /****************************************************************************
3662 Delete a UNIX user on demand.
3663 ****************************************************************************/
3665 static int smb_delete_user(const char *unix_user)
3667 pstring del_script;
3668 int ret;
3670 /* try winbindd first since it is impossible to determine where
3671 a user came from via NSS. Try the delete user script if this fails
3672 meaning the user did not exist in winbindd's list of accounts */
3674 if ( winbind_delete_user( unix_user ) ) {
3675 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3676 return 0;
3680 /* fall back to 'delete user script' */
3682 pstrcpy(del_script, lp_deluser_script());
3683 if (! *del_script)
3684 return -1;
3685 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3686 ret = smbrun(del_script,NULL);
3687 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3689 return ret;
3692 /*********************************************************************
3693 _samr_delete_dom_user
3694 *********************************************************************/
3696 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3698 DOM_SID user_sid;
3699 SAM_ACCOUNT *sam_pass=NULL;
3700 uint32 acc_granted;
3702 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3704 /* Find the policy handle. Open a policy on it. */
3705 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3706 return NT_STATUS_INVALID_HANDLE;
3708 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3709 return r_u->status;
3712 if (!sid_check_is_in_our_domain(&user_sid))
3713 return NT_STATUS_CANNOT_DELETE;
3715 /* check if the user exists before trying to delete */
3716 pdb_init_sam(&sam_pass);
3717 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3718 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3719 sid_string_static(&user_sid)));
3720 pdb_free_sam(&sam_pass);
3721 return NT_STATUS_NO_SUCH_USER;
3724 /* delete the unix side */
3726 * note: we don't check if the delete really happened
3727 * as the script is not necessary present
3728 * and maybe the sysadmin doesn't want to delete the unix side
3730 smb_delete_user(pdb_get_username(sam_pass));
3732 /* and delete the samba side */
3733 if (!pdb_delete_sam_account(sam_pass)) {
3734 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3735 pdb_free_sam(&sam_pass);
3736 return NT_STATUS_CANNOT_DELETE;
3739 pdb_free_sam(&sam_pass);
3741 if (!close_policy_hnd(p, &q_u->user_pol))
3742 return NT_STATUS_OBJECT_NAME_INVALID;
3744 return NT_STATUS_OK;
3747 /*********************************************************************
3748 _samr_delete_dom_group
3749 *********************************************************************/
3751 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3753 DOM_SID group_sid;
3754 DOM_SID dom_sid;
3755 uint32 group_rid;
3756 fstring group_sid_str;
3757 gid_t gid;
3758 struct group *grp;
3759 GROUP_MAP map;
3760 uint32 acc_granted;
3762 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3764 /* Find the policy handle. Open a policy on it. */
3765 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3766 return NT_STATUS_INVALID_HANDLE;
3768 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3769 return r_u->status;
3772 sid_copy(&dom_sid, &group_sid);
3773 sid_to_string(group_sid_str, &dom_sid);
3774 sid_split_rid(&dom_sid, &group_rid);
3776 DEBUG(10, ("sid is %s\n", group_sid_str));
3778 /* we check if it's our SID before deleting */
3779 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3780 return NT_STATUS_NO_SUCH_GROUP;
3782 DEBUG(10, ("lookup on Domain SID\n"));
3784 if(!get_domain_group_from_sid(group_sid, &map))
3785 return NT_STATUS_NO_SUCH_GROUP;
3787 gid=map.gid;
3789 /* check if group really exists */
3790 if ( (grp=getgrgid(gid)) == NULL)
3791 return NT_STATUS_NO_SUCH_GROUP;
3793 /* delete mapping first */
3794 if(!pdb_delete_group_mapping_entry(group_sid))
3795 return NT_STATUS_ACCESS_DENIED;
3797 /* we can delete the UNIX group */
3798 smb_delete_group(grp->gr_name);
3800 /* check if the group has been successfully deleted */
3801 if ( (grp=getgrgid(gid)) != NULL)
3802 return NT_STATUS_ACCESS_DENIED;
3805 if (!close_policy_hnd(p, &q_u->group_pol))
3806 return NT_STATUS_OBJECT_NAME_INVALID;
3808 return NT_STATUS_OK;
3811 /*********************************************************************
3812 _samr_delete_dom_alias
3813 *********************************************************************/
3815 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3817 DOM_SID alias_sid;
3818 DOM_SID dom_sid;
3819 uint32 alias_rid;
3820 fstring alias_sid_str;
3821 gid_t gid;
3822 struct group *grp;
3823 GROUP_MAP map;
3824 uint32 acc_granted;
3826 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3828 /* Find the policy handle. Open a policy on it. */
3829 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3830 return NT_STATUS_INVALID_HANDLE;
3832 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3833 return r_u->status;
3836 sid_copy(&dom_sid, &alias_sid);
3837 sid_to_string(alias_sid_str, &dom_sid);
3838 sid_split_rid(&dom_sid, &alias_rid);
3840 DEBUG(10, ("sid is %s\n", alias_sid_str));
3842 /* we check if it's our SID before deleting */
3843 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3844 return NT_STATUS_NO_SUCH_ALIAS;
3846 DEBUG(10, ("lookup on Local SID\n"));
3848 if(!get_local_group_from_sid(&alias_sid, &map))
3849 return NT_STATUS_NO_SUCH_ALIAS;
3851 gid=map.gid;
3853 /* check if group really exists */
3854 if ( (grp=getgrgid(gid)) == NULL)
3855 return NT_STATUS_NO_SUCH_ALIAS;
3857 /* we can delete the UNIX group */
3858 smb_delete_group(grp->gr_name);
3860 /* check if the group has been successfully deleted */
3861 if ( (grp=getgrgid(gid)) != NULL)
3862 return NT_STATUS_ACCESS_DENIED;
3864 /* don't check if we removed it as it could be an un-mapped group */
3865 pdb_delete_group_mapping_entry(alias_sid);
3867 if (!close_policy_hnd(p, &q_u->alias_pol))
3868 return NT_STATUS_OBJECT_NAME_INVALID;
3870 return NT_STATUS_OK;
3873 /*********************************************************************
3874 _samr_create_dom_group
3875 *********************************************************************/
3877 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3879 DOM_SID dom_sid;
3880 DOM_SID info_sid;
3881 fstring name;
3882 fstring sid_string;
3883 struct group *grp;
3884 struct samr_info *info;
3885 uint32 acc_granted;
3886 gid_t gid;
3888 /* Find the policy handle. Open a policy on it. */
3889 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3890 return NT_STATUS_INVALID_HANDLE;
3892 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3893 return r_u->status;
3896 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3897 return NT_STATUS_ACCESS_DENIED;
3899 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3901 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3903 /* check if group already exist */
3904 if ((grp=getgrnam(name)) != NULL)
3905 return NT_STATUS_GROUP_EXISTS;
3907 /* we can create the UNIX group */
3908 if (smb_create_group(name, &gid) != 0)
3909 return NT_STATUS_ACCESS_DENIED;
3911 /* check if the group has been successfully created */
3912 if ((grp=getgrgid(gid)) == NULL)
3913 return NT_STATUS_ACCESS_DENIED;
3915 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3917 /* add the group to the mapping table */
3918 sid_copy(&info_sid, get_global_sam_sid());
3919 sid_append_rid(&info_sid, r_u->rid);
3920 sid_to_string(sid_string, &info_sid);
3922 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3923 return NT_STATUS_ACCESS_DENIED;
3925 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3926 return NT_STATUS_NO_MEMORY;
3928 /* get a (unique) handle. open a policy on it. */
3929 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3930 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3932 return NT_STATUS_OK;
3935 /*********************************************************************
3936 _samr_create_dom_alias
3937 *********************************************************************/
3939 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3941 DOM_SID dom_sid;
3942 DOM_SID info_sid;
3943 fstring name;
3944 fstring sid_string;
3945 struct group *grp;
3946 struct samr_info *info;
3947 uint32 acc_granted;
3948 gid_t gid;
3950 /* Find the policy handle. Open a policy on it. */
3951 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3952 return NT_STATUS_INVALID_HANDLE;
3954 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3955 return r_u->status;
3958 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3959 return NT_STATUS_ACCESS_DENIED;
3961 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3963 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3965 /* check if group already exists */
3966 if ( (grp=getgrnam(name)) != NULL)
3967 return NT_STATUS_GROUP_EXISTS;
3969 /* we can create the UNIX group */
3970 if (smb_create_group(name, &gid) != 0)
3971 return NT_STATUS_ACCESS_DENIED;
3973 /* check if the group has been successfully created */
3974 if ((grp=getgrgid(gid)) == NULL)
3975 return NT_STATUS_ACCESS_DENIED;
3977 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3979 sid_copy(&info_sid, get_global_sam_sid());
3980 sid_append_rid(&info_sid, r_u->rid);
3981 sid_to_string(sid_string, &info_sid);
3983 /* add the group to the mapping table */
3984 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
3985 return NT_STATUS_ACCESS_DENIED;
3987 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3988 return NT_STATUS_NO_MEMORY;
3990 /* get a (unique) handle. open a policy on it. */
3991 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3992 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3994 return NT_STATUS_OK;
3997 /*********************************************************************
3998 _samr_query_groupinfo
4000 sends the name/comment pair of a domain group
4001 level 1 send also the number of users of that group
4002 *********************************************************************/
4004 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4006 DOM_SID group_sid;
4007 GROUP_MAP map;
4008 DOM_SID *sids=NULL;
4009 int num_sids=0;
4010 GROUP_INFO_CTR *ctr;
4011 uint32 acc_granted;
4012 BOOL ret;
4014 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4015 return NT_STATUS_INVALID_HANDLE;
4017 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4018 return r_u->status;
4021 become_root();
4022 ret = get_domain_group_from_sid(group_sid, &map);
4023 unbecome_root();
4024 if (!ret)
4025 return NT_STATUS_INVALID_HANDLE;
4027 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4028 if (ctr==NULL)
4029 return NT_STATUS_NO_MEMORY;
4031 switch (q_u->switch_level) {
4032 case 1:
4033 ctr->switch_value1 = 1;
4034 if(!get_sid_list_of_group(map.gid, &sids, &num_sids))
4035 return NT_STATUS_NO_SUCH_GROUP;
4036 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_sids);
4037 SAFE_FREE(sids);
4038 break;
4039 case 3:
4040 ctr->switch_value1 = 3;
4041 init_samr_group_info3(&ctr->group.info3);
4042 break;
4043 case 4:
4044 ctr->switch_value1 = 4;
4045 init_samr_group_info4(&ctr->group.info4, map.comment);
4046 break;
4047 default:
4048 return NT_STATUS_INVALID_INFO_CLASS;
4051 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4053 return NT_STATUS_OK;
4056 /*********************************************************************
4057 _samr_set_groupinfo
4059 update a domain group's comment.
4060 *********************************************************************/
4062 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4064 DOM_SID group_sid;
4065 GROUP_MAP map;
4066 GROUP_INFO_CTR *ctr;
4067 uint32 acc_granted;
4069 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4070 return NT_STATUS_INVALID_HANDLE;
4072 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4073 return r_u->status;
4076 if (!get_domain_group_from_sid(group_sid, &map))
4077 return NT_STATUS_NO_SUCH_GROUP;
4079 ctr=q_u->ctr;
4081 switch (ctr->switch_value1) {
4082 case 1:
4083 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4084 break;
4085 case 4:
4086 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4087 break;
4088 default:
4089 return NT_STATUS_INVALID_INFO_CLASS;
4092 if(!pdb_update_group_mapping_entry(&map)) {
4093 return NT_STATUS_NO_SUCH_GROUP;
4096 return NT_STATUS_OK;
4099 /*********************************************************************
4100 _samr_set_aliasinfo
4102 update an alias's comment.
4103 *********************************************************************/
4105 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4107 DOM_SID group_sid;
4108 GROUP_MAP map;
4109 ALIAS_INFO_CTR *ctr;
4110 uint32 acc_granted;
4112 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4113 return NT_STATUS_INVALID_HANDLE;
4115 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4116 return r_u->status;
4119 if (!get_local_group_from_sid(&group_sid, &map) &&
4120 !get_builtin_group_from_sid(&group_sid, &map))
4121 return NT_STATUS_NO_SUCH_GROUP;
4123 ctr=&q_u->ctr;
4125 switch (ctr->switch_value1) {
4126 case 3:
4127 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4128 break;
4129 default:
4130 return NT_STATUS_INVALID_INFO_CLASS;
4133 if(!pdb_update_group_mapping_entry(&map)) {
4134 return NT_STATUS_NO_SUCH_GROUP;
4137 return NT_STATUS_OK;
4140 /*********************************************************************
4141 _samr_get_dom_pwinfo
4142 *********************************************************************/
4144 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4146 /* Perform access check. Since this rpc does not require a
4147 policy handle it will not be caught by the access checks on
4148 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4150 if (!pipe_access_check(p)) {
4151 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4152 r_u->status = NT_STATUS_ACCESS_DENIED;
4153 return r_u->status;
4156 /* Actually, returning zeros here works quite well :-). */
4158 return NT_STATUS_OK;
4161 /*********************************************************************
4162 _samr_open_group
4163 *********************************************************************/
4165 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4167 DOM_SID sid;
4168 DOM_SID info_sid;
4169 GROUP_MAP map;
4170 struct samr_info *info;
4171 SEC_DESC *psd = NULL;
4172 uint32 acc_granted;
4173 uint32 des_access = q_u->access_mask;
4174 size_t sd_size;
4175 NTSTATUS status;
4176 fstring sid_string;
4177 BOOL ret;
4179 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4180 return NT_STATUS_INVALID_HANDLE;
4182 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4183 return status;
4186 /*check if access can be granted as requested by client. */
4187 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4188 se_map_generic(&des_access,&grp_generic_mapping);
4189 if (!NT_STATUS_IS_OK(status =
4190 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4191 des_access, &acc_granted, "_samr_open_group"))) {
4192 return status;
4196 /* this should not be hard-coded like this */
4197 if (!sid_equal(&sid, get_global_sam_sid()))
4198 return NT_STATUS_ACCESS_DENIED;
4200 sid_copy(&info_sid, get_global_sam_sid());
4201 sid_append_rid(&info_sid, q_u->rid_group);
4202 sid_to_string(sid_string, &info_sid);
4204 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4205 return NT_STATUS_NO_MEMORY;
4207 info->acc_granted = acc_granted;
4209 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4211 /* check if that group really exists */
4212 become_root();
4213 ret = get_domain_group_from_sid(info->sid, &map);
4214 unbecome_root();
4215 if (!ret)
4216 return NT_STATUS_NO_SUCH_GROUP;
4218 /* get a (unique) handle. open a policy on it. */
4219 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4220 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4222 return NT_STATUS_OK;
4225 /*********************************************************************
4226 _samr_remove_sid_foreign_domain
4227 *********************************************************************/
4229 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4230 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4231 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4233 DOM_SID delete_sid, alias_sid;
4234 SAM_ACCOUNT *sam_pass=NULL;
4235 uint32 acc_granted;
4236 GROUP_MAP map;
4237 BOOL is_user = False;
4238 NTSTATUS result;
4239 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4241 sid_copy( &delete_sid, &q_u->sid.sid );
4243 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4244 sid_string_static(&delete_sid)));
4246 /* Find the policy handle. Open a policy on it. */
4248 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4249 return NT_STATUS_INVALID_HANDLE;
4251 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4252 "_samr_remove_sid_foreign_domain");
4254 if (!NT_STATUS_IS_OK(result))
4255 return result;
4257 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4258 sid_string_static(&alias_sid)));
4260 /* make sure we can handle this */
4262 if ( sid_check_is_domain(&alias_sid) )
4263 type = SID_NAME_DOM_GRP;
4264 else if ( sid_check_is_builtin(&alias_sid) )
4265 type = SID_NAME_ALIAS;
4267 if ( type == SID_NAME_UNKNOWN ) {
4268 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4269 return NT_STATUS_OK;
4272 /* check if the user exists before trying to delete */
4274 pdb_init_sam(&sam_pass);
4276 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4277 is_user = True;
4278 } else {
4279 /* maybe it is a group */
4280 if( !pdb_getgrsid(&map, delete_sid) ) {
4281 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4282 sid_string_static(&delete_sid)));
4283 result = NT_STATUS_INVALID_SID;
4284 goto done;
4288 /* we can only delete a user from a group since we don't have
4289 nested groups anyways. So in the latter case, just say OK */
4291 if ( is_user ) {
4292 GROUP_MAP *mappings = NULL;
4293 int num_groups, i;
4294 struct group *grp2;
4296 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4298 /* interate over the groups */
4299 for ( i=0; i<num_groups; i++ ) {
4301 grp2 = getgrgid(mappings[i].gid);
4303 if ( !grp2 ) {
4304 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4305 continue;
4308 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4309 continue;
4311 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4313 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4314 /* should we fail here ? */
4315 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4316 pdb_get_username(sam_pass), grp2->gr_name ));
4317 continue;
4320 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4321 pdb_get_username(sam_pass), grp2->gr_name ));
4324 SAFE_FREE(mappings);
4328 result = NT_STATUS_OK;
4329 done:
4331 pdb_free_sam(&sam_pass);
4333 return result;
4336 /*******************************************************************
4337 _samr_unknown_2e
4338 ********************************************************************/
4340 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4342 struct samr_info *info = NULL;
4343 SAM_UNK_CTR *ctr;
4344 uint32 min_pass_len,pass_hist,flag;
4345 time_t u_expire, u_min_age;
4346 NTTIME nt_expire, nt_min_age;
4348 time_t u_lock_duration, u_reset_time;
4349 NTTIME nt_lock_duration, nt_reset_time;
4350 uint32 lockout;
4352 time_t u_logout;
4353 NTTIME nt_logout;
4355 uint32 num_users=0, num_groups=0, num_aliases=0;
4357 uint32 account_policy_temp;
4359 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4360 return NT_STATUS_NO_MEMORY;
4362 ZERO_STRUCTP(ctr);
4364 r_u->status = NT_STATUS_OK;
4366 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4368 /* find the policy handle. open a policy on it. */
4369 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4370 return NT_STATUS_INVALID_HANDLE;
4372 switch (q_u->switch_value) {
4373 case 0x01:
4374 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4375 min_pass_len = account_policy_temp;
4377 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4378 pass_hist = account_policy_temp;
4380 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4381 flag = account_policy_temp;
4383 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4384 u_expire = account_policy_temp;
4386 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4387 u_min_age = account_policy_temp;
4389 unix_to_nt_time_abs(&nt_expire, u_expire);
4390 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4392 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4393 flag, nt_expire, nt_min_age);
4394 break;
4395 case 0x02:
4396 become_root();
4397 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4398 unbecome_root();
4399 if (!NT_STATUS_IS_OK(r_u->status)) {
4400 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4401 return r_u->status;
4403 num_users=info->disp_info.num_user_account;
4404 free_samr_db(info);
4406 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4407 if (NT_STATUS_IS_ERR(r_u->status)) {
4408 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4409 return r_u->status;
4411 num_groups=info->disp_info.num_group_account;
4412 free_samr_db(info);
4414 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4415 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4416 num_users, num_groups, num_aliases);
4417 break;
4418 case 0x03:
4419 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4420 u_logout = account_policy_temp;
4422 unix_to_nt_time_abs(&nt_logout, u_logout);
4424 init_unk_info3(&ctr->info.inf3, nt_logout);
4425 break;
4426 case 0x05:
4427 init_unk_info5(&ctr->info.inf5, global_myname());
4428 break;
4429 case 0x06:
4430 init_unk_info6(&ctr->info.inf6);
4431 break;
4432 case 0x07:
4433 init_unk_info7(&ctr->info.inf7);
4434 break;
4435 case 0x0c:
4436 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4437 u_lock_duration = account_policy_temp;
4439 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4440 u_reset_time = account_policy_temp;
4442 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4443 lockout = account_policy_temp;
4445 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4446 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4448 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4449 break;
4450 default:
4451 return NT_STATUS_INVALID_INFO_CLASS;
4454 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4456 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4458 return r_u->status;
4461 /*******************************************************************
4462 _samr_
4463 ********************************************************************/
4465 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4467 time_t u_expire, u_min_age;
4468 time_t u_logout;
4469 time_t u_lock_duration, u_reset_time;
4471 r_u->status = NT_STATUS_OK;
4473 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4475 /* find the policy handle. open a policy on it. */
4476 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4477 return NT_STATUS_INVALID_HANDLE;
4479 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4481 switch (q_u->switch_value) {
4482 case 0x01:
4483 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4484 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4486 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4487 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4488 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4489 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4490 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4491 break;
4492 case 0x02:
4493 break;
4494 case 0x03:
4495 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4496 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4497 break;
4498 case 0x05:
4499 break;
4500 case 0x06:
4501 break;
4502 case 0x07:
4503 break;
4504 case 0x0c:
4505 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
4506 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4508 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4509 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4510 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4511 break;
4512 default:
4513 return NT_STATUS_INVALID_INFO_CLASS;
4516 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4518 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4520 return r_u->status;