First round of merging various UUID structures.
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_samr_nt.c
blob71e5bc7d70b372b1ee748aaea2579cc7262c2a4b
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;
296 DEBUG(10,("load_group_domain_entries\n"));
298 /* if the snapshoot is already loaded, return */
299 if (info->disp_info.group_dbloaded==True) {
300 DEBUG(10,("load_group_domain_entries: already in memory\n"));
301 return NT_STATUS_OK;
305 become_root();
307 if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED)) {
308 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
309 return NT_STATUS_NO_MEMORY;
312 unbecome_root();
314 info->disp_info.num_group_account=group_entries;
316 grp_array=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
317 if (group_entries!=0 && grp_array==NULL) {
318 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
319 SAFE_FREE(map);
320 return NT_STATUS_NO_MEMORY;
323 info->disp_info.disp_group_info=grp_array;
325 for (i=0; i<group_entries; i++) {
326 fstrcpy(grp_array[i].name, map[i].nt_name);
327 fstrcpy(grp_array[i].comment, map[i].comment);
328 sid_split_rid(&map[i].sid, &grp_array[i].rid);
329 grp_array[i].attr=SID_NAME_DOM_GRP;
332 SAFE_FREE(map);
334 /* the snapshoot is in memory, we're ready to enumerate fast */
336 info->disp_info.group_dbloaded=True;
338 DEBUG(10,("load_group_domain_entries: done\n"));
340 return NT_STATUS_OK;
344 /*******************************************************************
345 _samr_close_hnd
346 ********************************************************************/
348 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
350 r_u->status = NT_STATUS_OK;
352 /* close the policy handle */
353 if (!close_policy_hnd(p, &q_u->pol))
354 return NT_STATUS_OBJECT_NAME_INVALID;
356 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
358 return r_u->status;
361 /*******************************************************************
362 samr_reply_open_domain
363 ********************************************************************/
365 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
367 struct samr_info *info;
368 SEC_DESC *psd = NULL;
369 uint32 acc_granted;
370 uint32 des_access = q_u->flags;
371 size_t sd_size;
372 NTSTATUS status;
374 r_u->status = NT_STATUS_OK;
376 /* find the connection policy handle. */
377 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
378 return NT_STATUS_INVALID_HANDLE;
380 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
381 return status;
384 /*check if access can be granted as requested by client. */
385 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
386 se_map_generic(&des_access,&dom_generic_mapping);
388 if (!NT_STATUS_IS_OK(status =
389 access_check_samr_object(psd, p->pipe_user.nt_user_token,
390 des_access, &acc_granted, "_samr_open_domain"))) {
391 return status;
394 /* associate the domain SID with the (unique) handle. */
395 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
396 return NT_STATUS_NO_MEMORY;
397 info->acc_granted = acc_granted;
399 /* get a (unique) handle. open a policy on it. */
400 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
401 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
403 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
405 return r_u->status;
408 /*******************************************************************
409 _samr_get_usrdom_pwinfo
410 ********************************************************************/
412 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
414 struct samr_info *info = NULL;
416 r_u->status = NT_STATUS_OK;
418 /* find the policy handle. open a policy on it. */
419 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
420 return NT_STATUS_INVALID_HANDLE;
422 if (!sid_check_is_in_our_domain(&info->sid))
423 return NT_STATUS_OBJECT_TYPE_MISMATCH;
425 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
427 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
430 * NT sometimes return NT_STATUS_ACCESS_DENIED
431 * I don't know yet why.
434 return r_u->status;
437 /*******************************************************************
438 samr_make_dom_obj_sd
439 ********************************************************************/
441 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
443 extern DOM_SID global_sid_World;
444 DOM_SID adm_sid;
445 DOM_SID act_sid;
447 SEC_ACE ace[3];
448 SEC_ACCESS mask;
450 SEC_ACL *psa = NULL;
452 sid_copy(&adm_sid, &global_sid_Builtin);
453 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
455 sid_copy(&act_sid, &global_sid_Builtin);
456 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
458 /*basic access for every one*/
459 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
460 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
462 /*full access for builtin aliases Administrators and Account Operators*/
463 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
464 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
465 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
467 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
468 return NT_STATUS_NO_MEMORY;
470 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
471 return NT_STATUS_NO_MEMORY;
473 return NT_STATUS_OK;
476 /*******************************************************************
477 samr_make_usr_obj_sd
478 ********************************************************************/
480 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
482 extern DOM_SID global_sid_World;
483 DOM_SID adm_sid;
484 DOM_SID act_sid;
486 SEC_ACE ace[4];
487 SEC_ACCESS mask;
489 SEC_ACL *psa = NULL;
491 sid_copy(&adm_sid, &global_sid_Builtin);
492 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
494 sid_copy(&act_sid, &global_sid_Builtin);
495 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
497 /*basic access for every one*/
498 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
499 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
501 /*full access for builtin aliases Administrators and Account Operators*/
502 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
503 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
504 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
506 /*extended access for the user*/
507 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
508 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
511 return NT_STATUS_NO_MEMORY;
513 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
514 return NT_STATUS_NO_MEMORY;
516 return NT_STATUS_OK;
519 /*******************************************************************
520 samr_make_grp_obj_sd
521 ********************************************************************/
523 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
525 extern DOM_SID global_sid_World;
526 DOM_SID adm_sid;
527 DOM_SID act_sid;
529 SEC_ACE ace[3];
530 SEC_ACCESS mask;
532 SEC_ACL *psa = NULL;
534 sid_copy(&adm_sid, &global_sid_Builtin);
535 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
537 sid_copy(&act_sid, &global_sid_Builtin);
538 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
540 /*basic access for every one*/
541 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
542 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
544 /*full access for builtin aliases Administrators and Account Operators*/
545 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
546 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
547 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
549 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
550 return NT_STATUS_NO_MEMORY;
552 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
553 return NT_STATUS_NO_MEMORY;
555 return NT_STATUS_OK;
558 /*******************************************************************
559 samr_make_ali_obj_sd
560 ********************************************************************/
562 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
564 extern DOM_SID global_sid_World;
565 DOM_SID adm_sid;
566 DOM_SID act_sid;
568 SEC_ACE ace[3];
569 SEC_ACCESS mask;
571 SEC_ACL *psa = NULL;
573 sid_copy(&adm_sid, &global_sid_Builtin);
574 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
576 sid_copy(&act_sid, &global_sid_Builtin);
577 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
579 /*basic access for every one*/
580 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
581 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
583 /*full access for builtin aliases Administrators and Account Operators*/
584 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
585 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
588 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
589 return NT_STATUS_NO_MEMORY;
591 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
592 return NT_STATUS_NO_MEMORY;
594 return NT_STATUS_OK;
597 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
599 struct samr_info *info = NULL;
601 /* find the policy handle. open a policy on it. */
602 if (!find_policy_by_hnd(p, pol, (void **)&info))
603 return False;
605 if (!info)
606 return False;
608 *sid = info->sid;
609 *acc_granted = info->acc_granted;
610 return True;
613 /*******************************************************************
614 _samr_set_sec_obj
615 ********************************************************************/
617 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
619 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
620 return NT_STATUS_NOT_IMPLEMENTED;
624 /*******************************************************************
625 _samr_query_sec_obj
626 ********************************************************************/
628 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
630 DOM_SID pol_sid;
631 fstring str_sid;
632 SEC_DESC * psd = NULL;
633 size_t sd_size;
634 uint32 acc_granted;
636 r_u->status = NT_STATUS_OK;
638 /* Get the SID. */
639 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
640 return NT_STATUS_INVALID_HANDLE;
644 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
646 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
648 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
649 if (pol_sid.sid_rev_num == 0)
651 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
652 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
654 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
657 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
658 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
660 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
662 /* TODO: Builtin probably needs a different SD with restricted write access*/
663 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
664 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
666 else if (sid_check_is_in_our_domain(&pol_sid) ||
667 sid_check_is_in_builtin(&pol_sid))
669 /* TODO: different SDs have to be generated for aliases groups and users.
670 Currently all three get a default user SD */
671 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
672 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
674 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
676 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
677 return NT_STATUS_NO_MEMORY;
679 if (NT_STATUS_IS_OK(r_u->status))
680 r_u->ptr = 1;
682 return r_u->status;
685 /*******************************************************************
686 makes a SAM_ENTRY / UNISTR2* structure from a user list.
687 ********************************************************************/
689 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
690 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
691 DOM_SID *domain_sid)
693 uint32 i;
694 SAM_ENTRY *sam;
695 UNISTR2 *uni_name;
696 SAM_ACCOUNT *pwd = NULL;
697 UNISTR2 uni_temp_name;
698 const char *temp_name;
699 const DOM_SID *user_sid;
700 uint32 user_rid;
701 fstring user_sid_string;
702 fstring domain_sid_string;
704 *sam_pp = NULL;
705 *uni_name_pp = NULL;
707 if (num_entries == 0)
708 return NT_STATUS_OK;
710 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
712 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
714 if (sam == NULL || uni_name == NULL) {
715 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
716 return NT_STATUS_NO_MEMORY;
719 for (i = 0; i < num_entries; i++) {
720 pwd = &disp_user_info[i+start_idx];
721 temp_name = pdb_get_username(pwd);
722 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
723 user_sid = pdb_get_user_sid(pwd);
725 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
726 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
727 "the domain sid %s. Failing operation.\n",
728 temp_name,
729 sid_to_string(user_sid_string, user_sid),
730 sid_to_string(domain_sid_string, domain_sid)));
731 return NT_STATUS_UNSUCCESSFUL;
734 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
735 copy_unistr2(&uni_name[i], &uni_temp_name);
738 *sam_pp = sam;
739 *uni_name_pp = uni_name;
740 return NT_STATUS_OK;
743 /*******************************************************************
744 samr_reply_enum_dom_users
745 ********************************************************************/
747 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
748 SAMR_R_ENUM_DOM_USERS *r_u)
750 struct samr_info *info = NULL;
751 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
752 int num_account;
753 uint32 enum_context=q_u->start_idx;
754 uint32 max_size=q_u->max_size;
755 uint32 temp_size;
756 enum remote_arch_types ra_type = get_remote_arch();
757 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
758 uint32 max_entries = max_sam_entries;
759 DOM_SID domain_sid;
761 r_u->status = NT_STATUS_OK;
763 /* find the policy handle. open a policy on it. */
764 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
765 return NT_STATUS_INVALID_HANDLE;
767 domain_sid = info->sid;
769 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
770 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
771 "_samr_enum_dom_users"))) {
772 return r_u->status;
775 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
777 become_root();
778 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
779 unbecome_root();
781 if (!NT_STATUS_IS_OK(r_u->status))
782 return r_u->status;
784 num_account = info->disp_info.num_user_account;
786 if (enum_context > num_account) {
787 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
788 return NT_STATUS_OK;
791 /* verify we won't overflow */
792 if (max_entries > num_account-enum_context) {
793 max_entries = num_account-enum_context;
794 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
797 /* calculate the size and limit on the number of entries we will return */
798 temp_size=max_entries*struct_size;
800 if (temp_size>max_size) {
801 max_entries=MIN((max_size/struct_size),max_entries);;
802 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
806 * Note from JRA. total_entries is not being used here. Currently if there is a
807 * large user base then it looks like NT will enumerate until get_sampwd_entries
808 * returns False due to num_entries being zero. This will cause an access denied
809 * return. I don't think this is right and needs further investigation. Note that
810 * this is also the same in the TNG code (I don't think that has been tested with
811 * a very large user list as MAX_SAM_ENTRIES is set to 600).
813 * I also think that one of the 'num_entries' return parameters is probably
814 * the "max entries" parameter - but in the TNG code they're all currently set to the same
815 * value (again I think this is wrong).
818 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
819 max_entries, enum_context,
820 info->disp_info.disp_user_info,
821 &domain_sid);
823 if (!NT_STATUS_IS_OK(r_u->status))
824 return r_u->status;
826 if (enum_context+max_entries < num_account)
827 r_u->status = STATUS_MORE_ENTRIES;
829 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
831 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
833 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
835 return r_u->status;
838 /*******************************************************************
839 makes a SAM_ENTRY / UNISTR2* structure from a group list.
840 ********************************************************************/
842 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
843 uint32 num_sam_entries, DOMAIN_GRP *grp)
845 uint32 i;
846 SAM_ENTRY *sam;
847 UNISTR2 *uni_name;
849 *sam_pp = NULL;
850 *uni_name_pp = NULL;
852 if (num_sam_entries == 0)
853 return;
855 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
857 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
859 if (sam == NULL || uni_name == NULL) {
860 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
861 return;
864 for (i = 0; i < num_sam_entries; i++) {
866 * JRA. I think this should include the null. TNG does not.
868 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
869 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
872 *sam_pp = sam;
873 *uni_name_pp = uni_name;
876 /*******************************************************************
877 Get the group entries - similar to get_sampwd_entries().
878 ********************************************************************/
880 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
881 uint32 *p_num_entries, uint32 max_entries)
883 fstring sid_str;
884 uint32 num_entries = 0;
885 int i;
886 GROUP_MAP smap;
887 GROUP_MAP *map = NULL;
889 sid_to_string(sid_str, sid);
890 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
892 *p_num_entries = 0;
894 /* well-known aliases */
895 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
897 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED);
899 if (num_entries != 0) {
900 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
901 if (*d_grp==NULL)
902 return NT_STATUS_NO_MEMORY;
904 for(i=0; i<num_entries && i<max_entries; i++) {
905 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
906 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
910 SAFE_FREE(map);
912 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
913 struct sys_grent *glist;
914 struct sys_grent *grp;
915 gid_t winbind_gid_low, winbind_gid_high;
916 BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
918 /* local aliases */
919 /* we return the UNIX groups here. This seems to be the right */
920 /* thing to do, since NT member servers return their local */
921 /* groups in the same situation. */
923 /* use getgrent_list() to retrieve the list of groups to avoid
924 * problems with getgrent possible infinite loop by internal
925 * libc grent structures overwrites by called functions */
926 grp = glist = getgrent_list();
927 if (grp == NULL)
928 return NT_STATUS_NO_MEMORY;
930 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
931 uint32 trid;
933 if(!pdb_getgrgid(&smap, grp->gr_gid))
934 continue;
936 if (smap.sid_name_use!=SID_NAME_ALIAS) {
937 continue;
940 sid_split_rid(&smap.sid, &trid);
942 if (!sid_equal(sid, &smap.sid))
943 continue;
945 /* Don't return winbind groups as they are not local! */
946 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
947 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
948 continue;
951 /* Don't return user private groups... */
953 if (Get_Pwnam(smap.nt_name) != 0) {
954 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
955 continue;
958 for( i = 0; i < num_entries; i++)
959 if ( (*d_grp)[i].rid == trid )
960 break;
962 if ( i < num_entries ) {
963 continue; /* rid was there, dup! */
966 /* JRA - added this for large group db enumeration... */
968 if (start_idx > 0) {
969 /* skip the requested number of entries.
970 not very efficient, but hey...
972 start_idx--;
973 continue;
976 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
977 if (*d_grp==NULL) {
978 grent_free(glist);
979 return NT_STATUS_NO_MEMORY;
982 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
983 (*d_grp)[num_entries].rid = trid;
984 num_entries++;
985 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
988 grent_free(glist);
991 *p_num_entries = num_entries;
993 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
995 if (num_entries >= max_entries)
996 return STATUS_MORE_ENTRIES;
997 return NT_STATUS_OK;
1000 /*******************************************************************
1001 Get the group entries - similar to get_sampwd_entries().
1002 ********************************************************************/
1004 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1005 uint32 *p_num_entries, uint32 max_entries)
1007 GROUP_MAP *map=NULL;
1008 int i;
1009 uint32 group_entries = 0;
1010 uint32 num_entries = 0;
1012 *p_num_entries = 0;
1014 /* access checks for the users were performed higher up. become/unbecome_root()
1015 needed for some passdb backends to enumerate groups */
1017 become_root();
1018 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
1019 unbecome_root();
1021 num_entries=group_entries-start_idx;
1023 /* limit the number of entries */
1024 if (num_entries>max_entries) {
1025 DEBUG(5,("Limiting to %d entries\n", max_entries));
1026 num_entries=max_entries;
1029 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1030 if (num_entries!=0 && *d_grp==NULL){
1031 SAFE_FREE(map);
1032 return NT_STATUS_NO_MEMORY;
1035 for (i=0; i<num_entries; i++) {
1036 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1037 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1038 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1039 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1042 SAFE_FREE(map);
1044 *p_num_entries = num_entries;
1046 return NT_STATUS_OK;
1049 /*******************************************************************
1050 samr_reply_enum_dom_groups
1051 ********************************************************************/
1053 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1055 DOMAIN_GRP *grp=NULL;
1056 uint32 num_entries;
1057 DOM_SID sid;
1058 uint32 acc_granted;
1060 r_u->status = NT_STATUS_OK;
1062 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1063 return NT_STATUS_INVALID_HANDLE;
1065 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1066 return r_u->status;
1069 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1071 /* the domain group array is being allocated in the function below */
1072 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))) {
1073 return r_u->status;
1076 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1078 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1080 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1082 return r_u->status;
1086 /*******************************************************************
1087 samr_reply_enum_dom_aliases
1088 ********************************************************************/
1090 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1092 DOMAIN_GRP *grp=NULL;
1093 uint32 num_entries = 0;
1094 fstring sid_str;
1095 DOM_SID sid;
1096 NTSTATUS status;
1097 uint32 acc_granted;
1099 r_u->status = NT_STATUS_OK;
1101 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1102 return NT_STATUS_INVALID_HANDLE;
1104 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1105 return r_u->status;
1108 sid_to_string(sid_str, &sid);
1109 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1111 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1112 &num_entries, MAX_SAM_ENTRIES);
1113 if (NT_STATUS_IS_ERR(status)) return status;
1115 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1117 /*safe_free(grp);*/
1119 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1121 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1123 return r_u->status;
1126 /*******************************************************************
1127 samr_reply_query_dispinfo
1128 ********************************************************************/
1130 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1131 SAMR_R_QUERY_DISPINFO *r_u)
1133 struct samr_info *info = NULL;
1134 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1136 uint32 max_entries=q_u->max_entries;
1137 uint32 enum_context=q_u->start_idx;
1138 uint32 max_size=q_u->max_size;
1140 SAM_DISPINFO_CTR *ctr;
1141 uint32 temp_size=0, total_data_size=0;
1142 NTSTATUS disp_ret;
1143 uint32 num_account = 0;
1144 enum remote_arch_types ra_type = get_remote_arch();
1145 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1146 DOM_SID domain_sid;
1148 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1149 r_u->status = NT_STATUS_OK;
1151 /* find the policy handle. open a policy on it. */
1152 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1153 return NT_STATUS_INVALID_HANDLE;
1155 domain_sid = info->sid;
1158 * calculate how many entries we will return.
1159 * based on
1160 * - the number of entries the client asked
1161 * - our limit on that
1162 * - the starting point (enumeration context)
1163 * - the buffer size the client will accept
1167 * We are a lot more like W2K. Instead of reading the SAM
1168 * each time to find the records we need to send back,
1169 * we read it once and link that copy to the sam handle.
1170 * For large user list (over the MAX_SAM_ENTRIES)
1171 * it's a definitive win.
1172 * second point to notice: between enumerations
1173 * our sam is now the same as it's a snapshoot.
1174 * third point: got rid of the static SAM_USER_21 struct
1175 * no more intermediate.
1176 * con: it uses much more memory, as a full copy is stored
1177 * in memory.
1179 * If you want to change it, think twice and think
1180 * of the second point , that's really important.
1182 * JFM, 12/20/2001
1185 /* Get what we need from the password database */
1186 switch (q_u->switch_level) {
1187 case 0x1:
1188 /* When playing with usrmgr, this is necessary
1189 if you want immediate refresh after editing
1190 a user. I would like to do this after the
1191 setuserinfo2, but we do not have access to
1192 the domain handle in that call, only to the
1193 user handle. Where else does this hurt?
1194 -- Volker
1196 #if 0
1197 /* We cannot do this here - it kills performace. JRA. */
1198 free_samr_users(info);
1199 #endif
1200 case 0x2:
1201 case 0x4:
1202 become_root();
1203 /* Level 2 is for all machines, otherwise only 'normal' users */
1204 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1205 unbecome_root();
1206 if (!NT_STATUS_IS_OK(r_u->status)) {
1207 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1208 return r_u->status;
1210 num_account = info->disp_info.num_user_account;
1211 break;
1212 case 0x3:
1213 case 0x5:
1214 r_u->status = load_group_domain_entries(info, &info->sid);
1215 if (!NT_STATUS_IS_OK(r_u->status))
1216 return r_u->status;
1217 num_account = info->disp_info.num_group_account;
1218 break;
1219 default:
1220 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1221 return NT_STATUS_INVALID_INFO_CLASS;
1224 /* first limit the number of entries we will return */
1225 if(max_entries > max_sam_entries) {
1226 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1227 max_entries = max_sam_entries;
1230 if (enum_context > num_account) {
1231 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1232 return NT_STATUS_NO_MORE_ENTRIES;
1235 /* verify we won't overflow */
1236 if (max_entries > num_account-enum_context) {
1237 max_entries = num_account-enum_context;
1238 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1241 /* calculate the size and limit on the number of entries we will return */
1242 temp_size=max_entries*struct_size;
1244 if (temp_size>max_size) {
1245 max_entries=MIN((max_size/struct_size),max_entries);;
1246 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1249 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1250 return NT_STATUS_NO_MEMORY;
1252 ZERO_STRUCTP(ctr);
1254 /* Now create reply structure */
1255 switch (q_u->switch_level) {
1256 case 0x1:
1257 if (max_entries) {
1258 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1259 return NT_STATUS_NO_MEMORY;
1261 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1262 info->disp_info.disp_user_info, &domain_sid);
1263 if (!NT_STATUS_IS_OK(disp_ret))
1264 return disp_ret;
1265 break;
1266 case 0x2:
1267 if (max_entries) {
1268 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1269 return NT_STATUS_NO_MEMORY;
1271 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1272 info->disp_info.disp_user_info, &domain_sid);
1273 if (!NT_STATUS_IS_OK(disp_ret))
1274 return disp_ret;
1275 break;
1276 case 0x3:
1277 if (max_entries) {
1278 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1279 return NT_STATUS_NO_MEMORY;
1281 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1282 if (!NT_STATUS_IS_OK(disp_ret))
1283 return disp_ret;
1284 break;
1285 case 0x4:
1286 if (max_entries) {
1287 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1288 return NT_STATUS_NO_MEMORY;
1290 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1291 if (!NT_STATUS_IS_OK(disp_ret))
1292 return disp_ret;
1293 break;
1294 case 0x5:
1295 if (max_entries) {
1296 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1297 return NT_STATUS_NO_MEMORY;
1299 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1300 if (!NT_STATUS_IS_OK(disp_ret))
1301 return disp_ret;
1302 break;
1304 default:
1305 ctr->sam.info = NULL;
1306 return NT_STATUS_INVALID_INFO_CLASS;
1309 /* calculate the total size */
1310 total_data_size=num_account*struct_size;
1312 if (enum_context+max_entries < num_account)
1313 r_u->status = STATUS_MORE_ENTRIES;
1315 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1317 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1319 return r_u->status;
1323 /*******************************************************************
1324 samr_reply_query_aliasinfo
1325 ********************************************************************/
1327 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1329 DOM_SID sid;
1330 GROUP_MAP map;
1331 uint32 acc_granted;
1333 r_u->status = NT_STATUS_OK;
1335 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1337 /* find the policy handle. open a policy on it. */
1338 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1339 return NT_STATUS_INVALID_HANDLE;
1340 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1341 return r_u->status;
1344 if (!sid_check_is_in_our_domain(&sid) &&
1345 !sid_check_is_in_builtin(&sid))
1346 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1348 if (!pdb_getgrsid(&map, sid))
1349 return NT_STATUS_NO_SUCH_ALIAS;
1351 switch (q_u->switch_level) {
1352 case 1:
1353 r_u->ptr = 1;
1354 r_u->ctr.switch_value1 = 1;
1355 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1356 break;
1357 case 3:
1358 r_u->ptr = 1;
1359 r_u->ctr.switch_value1 = 3;
1360 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1361 break;
1362 default:
1363 return NT_STATUS_INVALID_INFO_CLASS;
1366 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1368 return r_u->status;
1371 #if 0
1372 /*******************************************************************
1373 samr_reply_lookup_ids
1374 ********************************************************************/
1376 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1378 uint32 rid[MAX_SAM_ENTRIES];
1379 int num_rids = q_u->num_sids1;
1381 r_u->status = NT_STATUS_OK;
1383 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1385 if (num_rids > MAX_SAM_ENTRIES) {
1386 num_rids = MAX_SAM_ENTRIES;
1387 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1390 #if 0
1391 int i;
1392 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1394 for (i = 0; i < num_rids && status == 0; i++)
1396 struct sam_passwd *sam_pass;
1397 fstring user_name;
1400 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1401 q_u->uni_user_name[i].uni_str_len));
1403 /* find the user account */
1404 become_root();
1405 sam_pass = get_smb21pwd_entry(user_name, 0);
1406 unbecome_root();
1408 if (sam_pass == NULL)
1410 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1411 rid[i] = 0;
1413 else
1415 rid[i] = sam_pass->user_rid;
1418 #endif
1420 num_rids = 1;
1421 rid[0] = BUILTIN_ALIAS_RID_USERS;
1423 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1425 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1427 return r_u->status;
1429 #endif
1431 /*******************************************************************
1432 _samr_lookup_names
1433 ********************************************************************/
1435 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1437 uint32 rid[MAX_SAM_ENTRIES];
1438 uint32 local_rid;
1439 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1440 enum SID_NAME_USE local_type;
1441 int i;
1442 int num_rids = q_u->num_names2;
1443 DOM_SID pol_sid;
1444 fstring sid_str;
1445 uint32 acc_granted;
1447 r_u->status = NT_STATUS_OK;
1449 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1451 ZERO_ARRAY(rid);
1452 ZERO_ARRAY(type);
1454 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1455 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1456 return r_u->status;
1459 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 */
1460 return r_u->status;
1463 if (num_rids > MAX_SAM_ENTRIES) {
1464 num_rids = MAX_SAM_ENTRIES;
1465 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1468 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1470 become_root(); /* local_lookup_name can require root privs */
1472 for (i = 0; i < num_rids; i++) {
1473 fstring name;
1474 DOM_SID sid;
1475 int ret;
1477 r_u->status = NT_STATUS_NONE_MAPPED;
1479 rid [i] = 0xffffffff;
1480 type[i] = SID_NAME_UNKNOWN;
1482 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1485 * we are only looking for a name
1486 * the SID we get back can be outside
1487 * the scope of the pol_sid
1489 * in clear: it prevents to reply to domain\group: yes
1490 * when only builtin\group exists.
1492 * a cleaner code is to add the sid of the domain we're looking in
1493 * to the local_lookup_name function.
1496 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1497 sid_split_rid(&sid, &local_rid);
1499 if (sid_equal(&sid, &pol_sid)) {
1500 rid[i]=local_rid;
1501 type[i]=local_type;
1502 r_u->status = NT_STATUS_OK;
1507 unbecome_root();
1509 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1511 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1513 return r_u->status;
1516 /*******************************************************************
1517 _samr_chgpasswd_user
1518 ********************************************************************/
1520 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1522 fstring user_name;
1523 fstring wks;
1525 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1527 r_u->status = NT_STATUS_OK;
1529 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1530 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1532 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1535 * Pass the user through the NT -> unix user mapping
1536 * function.
1539 (void)map_username(user_name);
1542 * UNIX username case mangling not required, pass_oem_change
1543 * is case insensitive.
1546 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1547 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1549 init_samr_r_chgpasswd_user(r_u, r_u->status);
1551 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1553 return r_u->status;
1556 /*******************************************************************
1557 makes a SAMR_R_LOOKUP_RIDS structure.
1558 ********************************************************************/
1560 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1561 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1563 uint32 i;
1564 UNIHDR *hdr_name=NULL;
1565 UNISTR2 *uni_name=NULL;
1567 *pp_uni_name = NULL;
1568 *pp_hdr_name = NULL;
1570 if (num_names != 0) {
1571 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1572 if (hdr_name == NULL)
1573 return False;
1575 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1576 if (uni_name == NULL)
1577 return False;
1580 for (i = 0; i < num_names; i++) {
1581 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1582 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1583 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1586 *pp_uni_name = uni_name;
1587 *pp_hdr_name = hdr_name;
1589 return True;
1592 /*******************************************************************
1593 _samr_lookup_rids
1594 ********************************************************************/
1596 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1598 fstring group_names[MAX_SAM_ENTRIES];
1599 uint32 *group_attrs = NULL;
1600 UNIHDR *hdr_name = NULL;
1601 UNISTR2 *uni_name = NULL;
1602 DOM_SID pol_sid;
1603 int num_rids = q_u->num_rids1;
1604 int i;
1605 uint32 acc_granted;
1607 r_u->status = NT_STATUS_OK;
1609 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1611 /* find the policy handle. open a policy on it. */
1612 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1613 return NT_STATUS_INVALID_HANDLE;
1615 if (num_rids > MAX_SAM_ENTRIES) {
1616 num_rids = MAX_SAM_ENTRIES;
1617 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1620 if (num_rids) {
1621 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1622 return NT_STATUS_NO_MEMORY;
1625 r_u->status = NT_STATUS_NONE_MAPPED;
1627 become_root(); /* lookup_sid can require root privs */
1629 for (i = 0; i < num_rids; i++) {
1630 fstring tmpname;
1631 fstring domname;
1632 DOM_SID sid;
1633 enum SID_NAME_USE type;
1635 group_attrs[i] = SID_NAME_UNKNOWN;
1636 *group_names[i] = '\0';
1638 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1639 sid_copy(&sid, &pol_sid);
1640 sid_append_rid(&sid, q_u->rid[i]);
1642 if (lookup_sid(&sid, domname, tmpname, &type)) {
1643 r_u->status = NT_STATUS_OK;
1644 group_attrs[i] = (uint32)type;
1645 fstrcpy(group_names[i],tmpname);
1646 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1651 unbecome_root();
1653 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1654 return NT_STATUS_NO_MEMORY;
1656 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1658 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1660 return r_u->status;
1663 /*******************************************************************
1664 _samr_open_user. Safe - gives out no passwd info.
1665 ********************************************************************/
1667 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1669 SAM_ACCOUNT *sampass=NULL;
1670 DOM_SID sid;
1671 POLICY_HND domain_pol = q_u->domain_pol;
1672 POLICY_HND *user_pol = &r_u->user_pol;
1673 struct samr_info *info = NULL;
1674 SEC_DESC *psd = NULL;
1675 uint32 acc_granted;
1676 uint32 des_access = q_u->access_mask;
1677 size_t sd_size;
1678 BOOL ret;
1679 NTSTATUS nt_status;
1681 r_u->status = NT_STATUS_OK;
1683 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1684 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1685 return NT_STATUS_INVALID_HANDLE;
1687 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1688 return nt_status;
1691 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1692 if (!NT_STATUS_IS_OK(nt_status)) {
1693 return nt_status;
1696 /* append the user's RID to it */
1697 if (!sid_append_rid(&sid, q_u->user_rid))
1698 return NT_STATUS_NO_SUCH_USER;
1700 /* check if access can be granted as requested by client. */
1701 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1702 se_map_generic(&des_access, &usr_generic_mapping);
1703 if (!NT_STATUS_IS_OK(nt_status =
1704 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1705 des_access, &acc_granted, "_samr_open_user"))) {
1706 return nt_status;
1709 become_root();
1710 ret=pdb_getsampwsid(sampass, &sid);
1711 unbecome_root();
1713 /* check that the SID exists in our domain. */
1714 if (ret == False) {
1715 return NT_STATUS_NO_SUCH_USER;
1718 pdb_free_sam(&sampass);
1720 /* associate the user's SID and access bits with the new handle. */
1721 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1722 return NT_STATUS_NO_MEMORY;
1723 info->acc_granted = acc_granted;
1725 /* get a (unique) handle. open a policy on it. */
1726 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1727 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1729 return r_u->status;
1732 /*************************************************************************
1733 get_user_info_10. Safe. Only gives out acb bits.
1734 *************************************************************************/
1736 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1738 SAM_ACCOUNT *smbpass=NULL;
1739 BOOL ret;
1740 NTSTATUS nt_status;
1742 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1744 if (!NT_STATUS_IS_OK(nt_status)) {
1745 return nt_status;
1748 become_root();
1749 ret = pdb_getsampwsid(smbpass, user_sid);
1750 unbecome_root();
1752 if (ret==False) {
1753 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1754 return NT_STATUS_NO_SUCH_USER;
1757 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1759 ZERO_STRUCTP(id10);
1760 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1762 pdb_free_sam(&smbpass);
1764 return NT_STATUS_OK;
1767 /*************************************************************************
1768 get_user_info_12. OK - this is the killer as it gives out password info.
1769 Ensure that this is only allowed on an encrypted connection with a root
1770 user. JRA.
1771 *************************************************************************/
1773 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1775 SAM_ACCOUNT *smbpass=NULL;
1776 BOOL ret;
1777 NTSTATUS nt_status;
1779 if (!p->ntlmssp_auth_validated)
1780 return NT_STATUS_ACCESS_DENIED;
1782 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1783 return NT_STATUS_ACCESS_DENIED;
1786 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1789 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1791 if (!NT_STATUS_IS_OK(nt_status)) {
1792 return nt_status;
1795 ret = pdb_getsampwsid(smbpass, user_sid);
1797 if (ret == False) {
1798 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1799 pdb_free_sam(&smbpass);
1800 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1803 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1805 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1806 pdb_free_sam(&smbpass);
1807 return NT_STATUS_ACCOUNT_DISABLED;
1810 ZERO_STRUCTP(id12);
1811 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1813 pdb_free_sam(&smbpass);
1815 return NT_STATUS_OK;
1818 /*************************************************************************
1819 get_user_info_20
1820 *************************************************************************/
1822 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1824 SAM_ACCOUNT *sampass=NULL;
1825 BOOL ret;
1827 pdb_init_sam_talloc(mem_ctx, &sampass);
1829 become_root();
1830 ret = pdb_getsampwsid(sampass, user_sid);
1831 unbecome_root();
1833 if (ret == False) {
1834 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1835 return NT_STATUS_NO_SUCH_USER;
1838 samr_clear_sam_passwd(sampass);
1840 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1842 ZERO_STRUCTP(id20);
1843 init_sam_user_info20A(id20, sampass);
1845 pdb_free_sam(&sampass);
1847 return NT_STATUS_OK;
1850 /*************************************************************************
1851 get_user_info_21
1852 *************************************************************************/
1854 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1855 DOM_SID *user_sid, DOM_SID *domain_sid)
1857 SAM_ACCOUNT *sampass=NULL;
1858 BOOL ret;
1859 NTSTATUS nt_status;
1861 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1862 if (!NT_STATUS_IS_OK(nt_status)) {
1863 return nt_status;
1866 become_root();
1867 ret = pdb_getsampwsid(sampass, user_sid);
1868 unbecome_root();
1870 if (ret == False) {
1871 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1872 return NT_STATUS_NO_SUCH_USER;
1875 samr_clear_sam_passwd(sampass);
1877 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1879 ZERO_STRUCTP(id21);
1880 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1882 pdb_free_sam(&sampass);
1884 return NT_STATUS_OK;
1887 /*******************************************************************
1888 _samr_query_userinfo
1889 ********************************************************************/
1891 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1893 SAM_USERINFO_CTR *ctr;
1894 struct samr_info *info = NULL;
1895 DOM_SID domain_sid;
1896 uint32 rid;
1898 r_u->status=NT_STATUS_OK;
1900 /* search for the handle */
1901 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1902 return NT_STATUS_INVALID_HANDLE;
1904 domain_sid = info->sid;
1906 sid_split_rid(&domain_sid, &rid);
1908 if (!sid_check_is_in_our_domain(&info->sid))
1909 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1911 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1913 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1914 if (!ctr)
1915 return NT_STATUS_NO_MEMORY;
1917 ZERO_STRUCTP(ctr);
1919 /* ok! user info levels (lots: see MSDEV help), off we go... */
1920 ctr->switch_value = q_u->switch_value;
1922 switch (q_u->switch_value) {
1923 case 0x10:
1924 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1925 if (ctr->info.id10 == NULL)
1926 return NT_STATUS_NO_MEMORY;
1928 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1929 return r_u->status;
1930 break;
1932 #if 0
1933 /* whoops - got this wrong. i think. or don't understand what's happening. */
1934 case 0x11:
1936 NTTIME expire;
1937 info = (void *)&id11;
1939 expire.low = 0xffffffff;
1940 expire.high = 0x7fffffff;
1942 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1943 sizeof
1944 (*ctr->
1945 info.
1946 id11));
1947 ZERO_STRUCTP(ctr->info.id11);
1948 init_sam_user_info11(ctr->info.id11, &expire,
1949 "BROOKFIELDS$", /* name */
1950 0x03ef, /* user rid */
1951 0x201, /* group rid */
1952 0x0080); /* acb info */
1954 break;
1956 #endif
1958 case 0x12:
1959 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1960 if (ctr->info.id12 == NULL)
1961 return NT_STATUS_NO_MEMORY;
1963 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1964 return r_u->status;
1965 break;
1967 case 20:
1968 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1969 if (ctr->info.id20 == NULL)
1970 return NT_STATUS_NO_MEMORY;
1971 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1972 return r_u->status;
1973 break;
1975 case 21:
1976 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1977 if (ctr->info.id21 == NULL)
1978 return NT_STATUS_NO_MEMORY;
1979 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1980 &info->sid, &domain_sid)))
1981 return r_u->status;
1982 break;
1984 default:
1985 return NT_STATUS_INVALID_INFO_CLASS;
1988 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1990 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1992 return r_u->status;
1995 /*******************************************************************
1996 samr_reply_query_usergroups
1997 ********************************************************************/
1999 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
2001 SAM_ACCOUNT *sam_pass=NULL;
2002 DOM_SID sid;
2003 DOM_GID *gids = NULL;
2004 int num_groups = 0;
2005 uint32 acc_granted;
2006 BOOL ret;
2009 * from the SID in the request:
2010 * we should send back the list of DOMAIN GROUPS
2011 * the user is a member of
2013 * and only the DOMAIN GROUPS
2014 * no ALIASES !!! neither aliases of the domain
2015 * nor aliases of the builtin SID
2017 * JFM, 12/2/2001
2020 r_u->status = NT_STATUS_OK;
2022 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2024 /* find the policy handle. open a policy on it. */
2025 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2026 return NT_STATUS_INVALID_HANDLE;
2028 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2029 return r_u->status;
2032 if (!sid_check_is_in_our_domain(&sid))
2033 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2035 pdb_init_sam(&sam_pass);
2037 become_root();
2038 ret = pdb_getsampwsid(sam_pass, &sid);
2039 unbecome_root();
2041 if (ret == False) {
2042 pdb_free_sam(&sam_pass);
2043 return NT_STATUS_NO_SUCH_USER;
2046 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2047 pdb_free_sam(&sam_pass);
2048 return NT_STATUS_NO_SUCH_GROUP;
2051 /* construct the response. lkclXXXX: gids are not copied! */
2052 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2054 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2056 pdb_free_sam(&sam_pass);
2058 return r_u->status;
2061 /*******************************************************************
2062 _samr_query_dom_info
2063 ********************************************************************/
2065 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2067 struct samr_info *info = NULL;
2068 SAM_UNK_CTR *ctr;
2069 uint32 min_pass_len,pass_hist,flag;
2070 time_t u_expire, u_min_age;
2071 NTTIME nt_expire, nt_min_age;
2073 time_t u_lock_duration, u_reset_time;
2074 NTTIME nt_lock_duration, nt_reset_time;
2075 uint32 lockout;
2077 time_t u_logout;
2078 NTTIME nt_logout;
2080 uint32 account_policy_temp;
2082 uint32 num_users=0, num_groups=0, num_aliases=0;
2084 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2085 return NT_STATUS_NO_MEMORY;
2087 ZERO_STRUCTP(ctr);
2089 r_u->status = NT_STATUS_OK;
2091 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2093 /* find the policy handle. open a policy on it. */
2094 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2095 return NT_STATUS_INVALID_HANDLE;
2097 switch (q_u->switch_value) {
2098 case 0x01:
2100 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2101 min_pass_len = account_policy_temp;
2103 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2104 pass_hist = account_policy_temp;
2106 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2107 flag = account_policy_temp;
2109 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2110 u_expire = account_policy_temp;
2112 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2113 u_min_age = account_policy_temp;
2115 unix_to_nt_time_abs(&nt_expire, u_expire);
2116 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2118 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2119 flag, nt_expire, nt_min_age);
2120 break;
2121 case 0x02:
2122 become_root();
2123 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2124 unbecome_root();
2125 if (!NT_STATUS_IS_OK(r_u->status)) {
2126 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2127 return r_u->status;
2129 num_users=info->disp_info.num_user_account;
2130 free_samr_db(info);
2132 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2133 if (!NT_STATUS_IS_OK(r_u->status)) {
2134 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2135 return r_u->status;
2137 num_groups=info->disp_info.num_group_account;
2138 free_samr_db(info);
2140 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2141 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2142 num_users, num_groups, num_aliases);
2143 break;
2144 case 0x03:
2145 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2146 unix_to_nt_time_abs(&nt_logout, u_logout);
2148 init_unk_info3(&ctr->info.inf3, nt_logout);
2149 break;
2150 case 0x05:
2151 init_unk_info5(&ctr->info.inf5, global_myname());
2152 break;
2153 case 0x06:
2154 init_unk_info6(&ctr->info.inf6);
2155 break;
2156 case 0x07:
2157 init_unk_info7(&ctr->info.inf7);
2158 break;
2159 case 0x0c:
2160 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2161 u_lock_duration = account_policy_temp;
2163 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2164 u_reset_time = account_policy_temp;
2166 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2167 lockout = account_policy_temp;
2169 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2170 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2172 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2173 break;
2174 default:
2175 return NT_STATUS_INVALID_INFO_CLASS;
2178 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2180 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2182 return r_u->status;
2185 /*******************************************************************
2186 _samr_create_user
2187 Create an account, can be either a normal user or a machine.
2188 This funcion will need to be updated for bdc/domain trusts.
2189 ********************************************************************/
2191 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2193 SAM_ACCOUNT *sam_pass=NULL;
2194 fstring account;
2195 DOM_SID sid;
2196 pstring add_script;
2197 POLICY_HND dom_pol = q_u->domain_pol;
2198 UNISTR2 user_account = q_u->uni_name;
2199 uint16 acb_info = q_u->acb_info;
2200 POLICY_HND *user_pol = &r_u->user_pol;
2201 struct samr_info *info = NULL;
2202 BOOL ret;
2203 NTSTATUS nt_status;
2204 struct passwd *pw;
2205 uint32 acc_granted;
2206 SEC_DESC *psd;
2207 size_t sd_size;
2208 uint32 new_rid = 0;
2209 /* check this, when giving away 'add computer to domain' privs */
2210 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2212 /* Get the domain SID stored in the domain policy */
2213 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2214 return NT_STATUS_INVALID_HANDLE;
2216 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2217 return nt_status;
2220 /* find the account: tell the caller if it exists.
2221 lkclXXXX i have *no* idea if this is a problem or not
2222 or even if you are supposed to construct a different
2223 reply if the account already exists...
2226 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2227 strlower_m(account);
2229 pdb_init_sam(&sam_pass);
2231 become_root();
2232 ret = pdb_getsampwnam(sam_pass, account);
2233 unbecome_root();
2234 if (ret == True) {
2235 /* this account exists: say so */
2236 pdb_free_sam(&sam_pass);
2237 return NT_STATUS_USER_EXISTS;
2240 pdb_free_sam(&sam_pass);
2243 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2244 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2245 * that only people with write access to the smbpasswd file will be able
2246 * to create a user. JRA.
2250 * add the user in the /etc/passwd file or the unix authority system.
2251 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2252 * a) local_password_change() checks for us if the /etc/passwd account really exists
2253 * b) smb_create_user() would return an error if the account already exists
2254 * and as it could return an error also if it can't create the account, it would be tricky.
2256 * So we go the easy way, only check after if the account exists.
2257 * JFM (2/3/2001), to clear any possible bad understanding (-:
2259 * We now have seperate script paramaters for adding users/machines so we
2260 * now have some sainity-checking to match.
2263 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2266 * we used to have code here that made sure the acb_info flags
2267 * matched with the users named (e.g. an account flags as a machine
2268 * trust account ended in '$'). It has been ifdef'd out for a long
2269 * time, so I replaced it with this comment. --jerry
2272 /* the passdb lookup has failed; check to see if we need to run the
2273 add user/machine script */
2275 pw = Get_Pwnam(account);
2277 /*********************************************************************
2278 * HEADS UP! If we have to create a new user account, we have to get
2279 * a new RID from somewhere. This used to be done by the passdb
2280 * backend. It has been moved into idmap now. Since idmap is now
2281 * wrapped up behind winbind, this means you have to run winbindd if you
2282 * want new accounts to get a new RID when "enable rid algorithm = no".
2283 * Tough. We now have a uniform way of allocating RIDs regardless
2284 * of what ever passdb backend people may use.
2285 * --jerry (2003-07-10)
2286 *********************************************************************/
2288 if ( !pw ) {
2290 * we can't check both the ending $ and the acb_info.
2292 * UserManager creates trust accounts (ending in $,
2293 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2294 * JFM, 11/29/2001
2296 if (account[strlen(account)-1] == '$')
2297 pstrcpy(add_script, lp_addmachine_script());
2298 else
2299 pstrcpy(add_script, lp_adduser_script());
2301 if (*add_script) {
2302 int add_ret;
2303 all_string_sub(add_script, "%u", account, sizeof(account));
2304 add_ret = smbrun(add_script,NULL);
2305 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2307 else /* no add user script -- ask winbindd to do it */
2309 if ( !winbind_create_user( account, &new_rid ) ) {
2310 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2311 account));
2317 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2319 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2320 return nt_status;
2322 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2324 if (!pdb_add_sam_account(sam_pass)) {
2325 pdb_free_sam(&sam_pass);
2326 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2327 account));
2328 return NT_STATUS_ACCESS_DENIED;
2331 /* Get the user's SID */
2332 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2334 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2335 se_map_generic(&des_access, &usr_generic_mapping);
2336 if (!NT_STATUS_IS_OK(nt_status =
2337 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2338 des_access, &acc_granted, "_samr_create_user"))) {
2339 return nt_status;
2342 /* associate the user's SID with the new handle. */
2343 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2344 pdb_free_sam(&sam_pass);
2345 return NT_STATUS_NO_MEMORY;
2348 ZERO_STRUCTP(info);
2349 info->sid = sid;
2350 info->acc_granted = acc_granted;
2352 /* get a (unique) handle. open a policy on it. */
2353 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2354 pdb_free_sam(&sam_pass);
2355 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2358 r_u->user_rid=pdb_get_user_rid(sam_pass);
2360 r_u->access_granted = acc_granted;
2362 pdb_free_sam(&sam_pass);
2364 return NT_STATUS_OK;
2367 /*******************************************************************
2368 samr_reply_connect_anon
2369 ********************************************************************/
2371 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2373 struct samr_info *info = NULL;
2374 uint32 des_access = q_u->access_mask;
2376 /* Access check */
2378 if (!pipe_access_check(p)) {
2379 DEBUG(3, ("access denied to samr_connect_anon\n"));
2380 r_u->status = NT_STATUS_ACCESS_DENIED;
2381 return r_u->status;
2384 /* set up the SAMR connect_anon response */
2386 r_u->status = NT_STATUS_OK;
2388 /* associate the user's SID with the new handle. */
2389 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2390 return NT_STATUS_NO_MEMORY;
2392 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2393 was observed from a win98 client trying to enumerate users (when configured
2394 user level access control on shares) --jerry */
2396 se_map_generic( &des_access, &sam_generic_mapping );
2397 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2399 info->status = q_u->unknown_0;
2401 /* get a (unique) handle. open a policy on it. */
2402 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2403 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2405 return r_u->status;
2408 /*******************************************************************
2409 samr_reply_connect
2410 ********************************************************************/
2412 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2414 struct samr_info *info = NULL;
2415 SEC_DESC *psd = NULL;
2416 uint32 acc_granted;
2417 uint32 des_access = q_u->access_mask;
2418 size_t sd_size;
2419 NTSTATUS nt_status;
2422 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2424 /* Access check */
2426 if (!pipe_access_check(p)) {
2427 DEBUG(3, ("access denied to samr_connect\n"));
2428 r_u->status = NT_STATUS_ACCESS_DENIED;
2429 return r_u->status;
2432 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2433 se_map_generic(&des_access, &sam_generic_mapping);
2434 if (!NT_STATUS_IS_OK(nt_status =
2435 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2436 des_access, &acc_granted, "_samr_connect"))) {
2437 return nt_status;
2440 r_u->status = NT_STATUS_OK;
2442 /* associate the user's SID and access granted with the new handle. */
2443 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2444 return NT_STATUS_NO_MEMORY;
2446 info->acc_granted = acc_granted;
2447 info->status = q_u->access_mask;
2449 /* get a (unique) handle. open a policy on it. */
2450 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2451 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2453 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2455 return r_u->status;
2458 /*******************************************************************
2459 samr_connect4
2460 ********************************************************************/
2462 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2464 struct samr_info *info = NULL;
2465 SEC_DESC *psd = NULL;
2466 uint32 acc_granted;
2467 uint32 des_access = q_u->access_mask;
2468 size_t sd_size;
2469 NTSTATUS nt_status;
2472 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2474 /* Access check */
2476 if (!pipe_access_check(p)) {
2477 DEBUG(3, ("access denied to samr_connect4\n"));
2478 r_u->status = NT_STATUS_ACCESS_DENIED;
2479 return r_u->status;
2482 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2483 se_map_generic(&des_access, &sam_generic_mapping);
2484 if (!NT_STATUS_IS_OK(nt_status =
2485 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2486 des_access, &acc_granted, "_samr_connect"))) {
2487 return nt_status;
2490 r_u->status = NT_STATUS_OK;
2492 /* associate the user's SID and access granted with the new handle. */
2493 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2494 return NT_STATUS_NO_MEMORY;
2496 info->acc_granted = acc_granted;
2497 info->status = q_u->access_mask;
2499 /* get a (unique) handle. open a policy on it. */
2500 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2501 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2503 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2505 return r_u->status;
2508 /**********************************************************************
2509 api_samr_lookup_domain
2510 **********************************************************************/
2512 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2514 struct samr_info *info;
2515 fstring domain_name;
2516 DOM_SID sid;
2518 r_u->status = NT_STATUS_OK;
2520 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2521 return NT_STATUS_INVALID_HANDLE;
2523 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2524 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2526 return r_u->status;
2529 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2531 ZERO_STRUCT(sid);
2533 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2534 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2537 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2539 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2541 return r_u->status;
2544 /******************************************************************
2545 makes a SAMR_R_ENUM_DOMAINS structure.
2546 ********************************************************************/
2548 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2549 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2551 uint32 i;
2552 SAM_ENTRY *sam;
2553 UNISTR2 *uni_name;
2555 DEBUG(5, ("make_enum_domains\n"));
2557 *pp_sam = NULL;
2558 *pp_uni_name = NULL;
2560 if (num_sam_entries == 0)
2561 return True;
2563 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2564 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2566 if (sam == NULL || uni_name == NULL)
2567 return False;
2569 for (i = 0; i < num_sam_entries; i++) {
2570 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2571 init_sam_entry(&sam[i], &uni_name[i], 0);
2574 *pp_sam = sam;
2575 *pp_uni_name = uni_name;
2577 return True;
2580 /**********************************************************************
2581 api_samr_enum_domains
2582 **********************************************************************/
2584 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2586 struct samr_info *info;
2587 uint32 num_entries = 2;
2588 fstring dom[2];
2589 const char *name;
2591 r_u->status = NT_STATUS_OK;
2593 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2594 return NT_STATUS_INVALID_HANDLE;
2596 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2597 return r_u->status;
2600 name = get_global_sam_name();
2602 fstrcpy(dom[0],name);
2603 strupper_m(dom[0]);
2604 fstrcpy(dom[1],"Builtin");
2606 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2607 return NT_STATUS_NO_MEMORY;
2609 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2611 return r_u->status;
2614 /*******************************************************************
2615 api_samr_open_alias
2616 ********************************************************************/
2618 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2620 DOM_SID sid;
2621 POLICY_HND domain_pol = q_u->dom_pol;
2622 uint32 alias_rid = q_u->rid_alias;
2623 POLICY_HND *alias_pol = &r_u->pol;
2624 struct samr_info *info = NULL;
2625 SEC_DESC *psd = NULL;
2626 uint32 acc_granted;
2627 uint32 des_access = q_u->access_mask;
2628 size_t sd_size;
2629 NTSTATUS status;
2631 r_u->status = NT_STATUS_OK;
2633 /* find the domain policy and get the SID / access bits stored in the domain policy */
2634 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2635 return NT_STATUS_INVALID_HANDLE;
2637 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2638 return status;
2641 /* append the alias' RID to it */
2642 if (!sid_append_rid(&sid, alias_rid))
2643 return NT_STATUS_NO_SUCH_USER;
2645 /*check if access can be granted as requested by client. */
2646 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2647 se_map_generic(&des_access,&ali_generic_mapping);
2648 if (!NT_STATUS_IS_OK(status =
2649 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2650 des_access, &acc_granted, "_samr_open_alias"))) {
2651 return status;
2655 * we should check if the rid really exist !!!
2656 * JFM.
2659 /* associate the user's SID with the new handle. */
2660 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2661 return NT_STATUS_NO_MEMORY;
2663 info->acc_granted = acc_granted;
2665 /* get a (unique) handle. open a policy on it. */
2666 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2667 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2669 return r_u->status;
2672 /*******************************************************************
2673 set_user_info_10
2674 ********************************************************************/
2676 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2678 SAM_ACCOUNT *pwd =NULL;
2679 BOOL ret;
2681 pdb_init_sam(&pwd);
2683 ret = pdb_getsampwsid(pwd, sid);
2685 if(ret==False) {
2686 pdb_free_sam(&pwd);
2687 return False;
2690 if (id10 == NULL) {
2691 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2692 pdb_free_sam(&pwd);
2693 return False;
2696 /* FIX ME: check if the value is really changed --metze */
2697 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2698 pdb_free_sam(&pwd);
2699 return False;
2702 if(!pdb_update_sam_account(pwd)) {
2703 pdb_free_sam(&pwd);
2704 return False;
2707 pdb_free_sam(&pwd);
2709 return True;
2712 /*******************************************************************
2713 set_user_info_12
2714 ********************************************************************/
2716 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2718 SAM_ACCOUNT *pwd = NULL;
2720 pdb_init_sam(&pwd);
2722 if(!pdb_getsampwsid(pwd, sid)) {
2723 pdb_free_sam(&pwd);
2724 return False;
2727 if (id12 == NULL) {
2728 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2729 pdb_free_sam(&pwd);
2730 return False;
2733 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2734 pdb_free_sam(&pwd);
2735 return False;
2737 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2738 pdb_free_sam(&pwd);
2739 return False;
2741 if (!pdb_set_pass_changed_now (pwd)) {
2742 pdb_free_sam(&pwd);
2743 return False;
2746 if(!pdb_update_sam_account(pwd)) {
2747 pdb_free_sam(&pwd);
2748 return False;
2751 pdb_free_sam(&pwd);
2752 return True;
2755 /*******************************************************************
2756 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2757 ********************************************************************/
2758 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2760 struct group *grp;
2761 gid_t gid;
2763 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2764 &gid))) {
2765 DEBUG(2,("Could not get gid for primary group of "
2766 "user %s\n", pdb_get_username(sampass)));
2767 return False;
2770 grp = getgrgid(gid);
2772 if (grp == NULL) {
2773 DEBUG(2,("Could not find primary group %lu for "
2774 "user %s\n", (unsigned long)gid,
2775 pdb_get_username(sampass)));
2776 return False;
2779 if (smb_set_primary_group(grp->gr_name,
2780 pdb_get_username(sampass)) != 0) {
2781 DEBUG(2,("Could not set primary group for user %s to "
2782 "%s\n",
2783 pdb_get_username(sampass), grp->gr_name));
2784 return False;
2787 return True;
2791 /*******************************************************************
2792 set_user_info_21
2793 ********************************************************************/
2795 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2797 SAM_ACCOUNT *pwd = NULL;
2799 if (id21 == NULL) {
2800 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2801 return False;
2804 pdb_init_sam(&pwd);
2806 if (!pdb_getsampwsid(pwd, sid)) {
2807 pdb_free_sam(&pwd);
2808 return False;
2811 copy_id21_to_sam_passwd(pwd, id21);
2814 * The funny part about the previous two calls is
2815 * that pwd still has the password hashes from the
2816 * passdb entry. These have not been updated from
2817 * id21. I don't know if they need to be set. --jerry
2820 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2821 set_unix_primary_group(pwd);
2823 /* write the change out */
2824 if(!pdb_update_sam_account(pwd)) {
2825 pdb_free_sam(&pwd);
2826 return False;
2829 pdb_free_sam(&pwd);
2831 return True;
2834 /*******************************************************************
2835 set_user_info_23
2836 ********************************************************************/
2838 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2840 SAM_ACCOUNT *pwd = NULL;
2841 pstring plaintext_buf;
2842 uint32 len;
2843 uint16 acct_ctrl;
2845 if (id23 == NULL) {
2846 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2847 return False;
2850 pdb_init_sam(&pwd);
2852 if (!pdb_getsampwsid(pwd, sid)) {
2853 pdb_free_sam(&pwd);
2854 return False;
2857 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2858 pdb_get_username(pwd)));
2860 acct_ctrl = pdb_get_acct_ctrl(pwd);
2862 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2863 pdb_free_sam(&pwd);
2864 return False;
2867 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2868 pdb_free_sam(&pwd);
2869 return False;
2872 copy_id23_to_sam_passwd(pwd, id23);
2874 /* if it's a trust account, don't update /etc/passwd */
2875 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2876 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2877 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2878 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2879 } else {
2880 /* update the UNIX password */
2881 if (lp_unix_password_sync() )
2882 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2883 pdb_free_sam(&pwd);
2884 return False;
2888 ZERO_STRUCT(plaintext_buf);
2890 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2891 set_unix_primary_group(pwd);
2893 if(!pdb_update_sam_account(pwd)) {
2894 pdb_free_sam(&pwd);
2895 return False;
2898 pdb_free_sam(&pwd);
2900 return True;
2903 /*******************************************************************
2904 set_user_info_pw
2905 ********************************************************************/
2907 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2909 SAM_ACCOUNT *pwd = NULL;
2910 uint32 len;
2911 pstring plaintext_buf;
2912 uint16 acct_ctrl;
2914 pdb_init_sam(&pwd);
2916 if (!pdb_getsampwsid(pwd, sid)) {
2917 pdb_free_sam(&pwd);
2918 return False;
2921 DEBUG(5, ("Attempting administrator password change for user %s\n",
2922 pdb_get_username(pwd)));
2924 acct_ctrl = pdb_get_acct_ctrl(pwd);
2926 ZERO_STRUCT(plaintext_buf);
2928 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2929 pdb_free_sam(&pwd);
2930 return False;
2933 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2934 pdb_free_sam(&pwd);
2935 return False;
2938 /* if it's a trust account, don't update /etc/passwd */
2939 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2940 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2941 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2942 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2943 } else {
2944 /* update the UNIX password */
2945 if (lp_unix_password_sync()) {
2946 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2947 pdb_free_sam(&pwd);
2948 return False;
2953 ZERO_STRUCT(plaintext_buf);
2955 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2957 /* update the SAMBA password */
2958 if(!pdb_update_sam_account(pwd)) {
2959 pdb_free_sam(&pwd);
2960 return False;
2963 pdb_free_sam(&pwd);
2965 return True;
2968 /*******************************************************************
2969 samr_reply_set_userinfo
2970 ********************************************************************/
2972 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2974 DOM_SID sid;
2975 POLICY_HND *pol = &q_u->pol;
2976 uint16 switch_value = q_u->switch_value;
2977 SAM_USERINFO_CTR *ctr = q_u->ctr;
2978 uint32 acc_granted;
2979 uint32 acc_required;
2981 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2983 r_u->status = NT_STATUS_OK;
2985 /* find the policy handle. open a policy on it. */
2986 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2987 return NT_STATUS_INVALID_HANDLE;
2989 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2990 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2991 return r_u->status;
2994 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2996 if (ctr == NULL) {
2997 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2998 return NT_STATUS_INVALID_INFO_CLASS;
3001 /* ok! user info levels (lots: see MSDEV help), off we go... */
3002 switch (switch_value) {
3003 case 0x12:
3004 if (!set_user_info_12(ctr->info.id12, &sid))
3005 return NT_STATUS_ACCESS_DENIED;
3006 break;
3008 case 24:
3009 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
3011 dump_data(100, (char *)ctr->info.id24->pass, 516);
3013 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3014 return NT_STATUS_ACCESS_DENIED;
3015 break;
3017 case 25:
3018 #if 0
3020 * Currently we don't really know how to unmarshall
3021 * the level 25 struct, and the password encryption
3022 * is different. This is a placeholder for when we
3023 * do understand it. In the meantime just return INVALID
3024 * info level and W2K SP2 drops down to level 23... JRA.
3027 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3029 dump_data(100, (char *)ctr->info.id25->pass, 532);
3031 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3032 return NT_STATUS_ACCESS_DENIED;
3033 break;
3034 #endif
3035 return NT_STATUS_INVALID_INFO_CLASS;
3037 case 23:
3038 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3040 dump_data(100, (char *)ctr->info.id23->pass, 516);
3042 if (!set_user_info_23(ctr->info.id23, &sid))
3043 return NT_STATUS_ACCESS_DENIED;
3044 break;
3046 default:
3047 return NT_STATUS_INVALID_INFO_CLASS;
3050 return r_u->status;
3053 /*******************************************************************
3054 samr_reply_set_userinfo2
3055 ********************************************************************/
3057 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3059 DOM_SID sid;
3060 SAM_USERINFO_CTR *ctr = q_u->ctr;
3061 POLICY_HND *pol = &q_u->pol;
3062 uint16 switch_value = q_u->switch_value;
3063 uint32 acc_granted;
3064 uint32 acc_required;
3066 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3068 r_u->status = NT_STATUS_OK;
3070 /* find the policy handle. open a policy on it. */
3071 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3072 return NT_STATUS_INVALID_HANDLE;
3074 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3075 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3076 return r_u->status;
3079 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3081 if (ctr == NULL) {
3082 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3083 return NT_STATUS_INVALID_INFO_CLASS;
3086 switch_value=ctr->switch_value;
3088 /* ok! user info levels (lots: see MSDEV help), off we go... */
3089 switch (switch_value) {
3090 case 21:
3091 if (!set_user_info_21(ctr->info.id21, &sid))
3092 return NT_STATUS_ACCESS_DENIED;
3093 break;
3094 case 16:
3095 if (!set_user_info_10(ctr->info.id10, &sid))
3096 return NT_STATUS_ACCESS_DENIED;
3097 break;
3098 case 18:
3099 /* Used by AS/U JRA. */
3100 if (!set_user_info_12(ctr->info.id12, &sid))
3101 return NT_STATUS_ACCESS_DENIED;
3102 break;
3103 default:
3104 return NT_STATUS_INVALID_INFO_CLASS;
3107 return r_u->status;
3110 /*********************************************************************
3111 _samr_query_aliasmem
3112 *********************************************************************/
3114 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3116 int num_groups = 0, tmp_num_groups=0;
3117 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3118 struct samr_info *info = NULL;
3119 int i,j;
3121 NTSTATUS ntstatus1;
3122 NTSTATUS ntstatus2;
3124 /* until i see a real useraliases query, we fack one up */
3126 /* I have seen one, JFM 2/12/2001 */
3128 * Explanation of what this call does:
3129 * for all the SID given in the request:
3130 * return a list of alias (local groups)
3131 * that have those SID as members.
3133 * and that's the alias in the domain specified
3134 * in the policy_handle
3136 * if the policy handle is on an incorrect sid
3137 * for example a user's sid
3138 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3141 r_u->status = NT_STATUS_OK;
3143 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3145 /* find the policy handle. open a policy on it. */
3146 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3147 return NT_STATUS_INVALID_HANDLE;
3149 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3150 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3152 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3153 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3154 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3155 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3159 if (!sid_check_is_domain(&info->sid) &&
3160 !sid_check_is_builtin(&info->sid))
3161 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3164 for (i=0; i<q_u->num_sids1; i++) {
3166 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3169 * if there is an error, we just continue as
3170 * it can be an unfound user or group
3172 if (!NT_STATUS_IS_OK(r_u->status)) {
3173 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3174 continue;
3177 if (tmp_num_groups==0) {
3178 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3179 continue;
3182 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3183 if (new_rids==NULL) {
3184 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3185 return NT_STATUS_NO_MEMORY;
3187 rids=new_rids;
3189 for (j=0; j<tmp_num_groups; j++)
3190 rids[j+num_groups]=tmp_rids[j];
3192 safe_free(tmp_rids);
3194 num_groups+=tmp_num_groups;
3197 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3198 return NT_STATUS_OK;
3201 /*********************************************************************
3202 _samr_query_aliasmem
3203 *********************************************************************/
3205 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3207 int i;
3209 GROUP_MAP map;
3210 int num_uids = 0;
3211 DOM_SID2 *sid;
3212 uid_t *uid=NULL;
3214 DOM_SID alias_sid;
3215 DOM_SID als_sid;
3216 uint32 alias_rid;
3217 fstring alias_sid_str;
3218 DOM_SID temp_sid;
3220 SAM_ACCOUNT *sam_user = NULL;
3221 BOOL check;
3222 uint32 acc_granted;
3224 /* find the policy handle. open a policy on it. */
3225 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3226 return NT_STATUS_INVALID_HANDLE;
3228 if (!NT_STATUS_IS_OK(r_u->status =
3229 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3230 return r_u->status;
3233 sid_copy(&als_sid, &alias_sid);
3234 sid_to_string(alias_sid_str, &alias_sid);
3235 sid_split_rid(&alias_sid, &alias_rid);
3237 DEBUG(10, ("sid is %s\n", alias_sid_str));
3239 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3240 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3241 if(!get_builtin_group_from_sid(als_sid, &map))
3242 return NT_STATUS_NO_SUCH_ALIAS;
3243 } else {
3244 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3245 DEBUG(10, ("lookup on Server SID\n"));
3246 if(!get_local_group_from_sid(als_sid, &map))
3247 return NT_STATUS_NO_SUCH_ALIAS;
3251 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3252 return NT_STATUS_NO_SUCH_ALIAS;
3254 DEBUG(10, ("sid is %s\n", alias_sid_str));
3255 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3256 if (num_uids!=0 && sid == NULL)
3257 return NT_STATUS_NO_MEMORY;
3259 for (i = 0; i < num_uids; i++) {
3260 struct passwd *pass;
3261 uint32 rid;
3263 sid_copy(&temp_sid, get_global_sam_sid());
3265 pass = getpwuid_alloc(uid[i]);
3266 if (!pass) continue;
3268 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3269 passwd_free(&pass);
3270 continue;
3273 become_root();
3274 check = pdb_getsampwnam(sam_user, pass->pw_name);
3275 unbecome_root();
3277 if (check != True) {
3278 pdb_free_sam(&sam_user);
3279 passwd_free(&pass);
3280 continue;
3283 rid = pdb_get_user_rid(sam_user);
3284 if (rid == 0) {
3285 pdb_free_sam(&sam_user);
3286 passwd_free(&pass);
3287 continue;
3290 pdb_free_sam(&sam_user);
3291 passwd_free(&pass);
3293 sid_append_rid(&temp_sid, rid);
3295 init_dom_sid2(&sid[i], &temp_sid);
3298 DEBUG(10, ("sid is %s\n", alias_sid_str));
3299 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3301 return NT_STATUS_OK;
3304 /*********************************************************************
3305 _samr_query_groupmem
3306 *********************************************************************/
3308 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3310 int num_uids = 0;
3311 int i;
3312 DOM_SID group_sid;
3313 uint32 group_rid;
3314 fstring group_sid_str;
3315 uid_t *uid=NULL;
3317 GROUP_MAP map;
3319 uint32 *rid=NULL;
3320 uint32 *attr=NULL;
3322 SAM_ACCOUNT *sam_user = NULL;
3323 BOOL check;
3324 uint32 acc_granted;
3326 /* find the policy handle. open a policy on it. */
3327 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3328 return NT_STATUS_INVALID_HANDLE;
3330 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3331 return r_u->status;
3334 /* todo: change to use sid_compare_front */
3336 sid_split_rid(&group_sid, &group_rid);
3337 sid_to_string(group_sid_str, &group_sid);
3338 DEBUG(10, ("sid is %s\n", group_sid_str));
3340 /* can we get a query for an SID outside our domain ? */
3341 if (!sid_equal(&group_sid, get_global_sam_sid()))
3342 return NT_STATUS_NO_SUCH_GROUP;
3344 sid_append_rid(&group_sid, group_rid);
3345 DEBUG(10, ("lookup on Domain SID\n"));
3347 if(!get_domain_group_from_sid(group_sid, &map))
3348 return NT_STATUS_NO_SUCH_GROUP;
3350 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3351 return NT_STATUS_NO_SUCH_GROUP;
3353 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3354 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3356 if (num_uids!=0 && (rid==NULL || attr==NULL))
3357 return NT_STATUS_NO_MEMORY;
3359 for (i=0; i<num_uids; i++) {
3360 struct passwd *pass;
3361 uint32 urid;
3363 pass = getpwuid_alloc(uid[i]);
3364 if (!pass) continue;
3366 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3367 passwd_free(&pass);
3368 continue;
3371 become_root();
3372 check = pdb_getsampwnam(sam_user, pass->pw_name);
3373 unbecome_root();
3375 if (check != True) {
3376 pdb_free_sam(&sam_user);
3377 passwd_free(&pass);
3378 continue;
3381 urid = pdb_get_user_rid(sam_user);
3382 if (urid == 0) {
3383 pdb_free_sam(&sam_user);
3384 passwd_free(&pass);
3385 continue;
3388 pdb_free_sam(&sam_user);
3389 passwd_free(&pass);
3391 rid[i] = urid;
3392 attr[i] = SID_NAME_USER;
3395 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3397 return NT_STATUS_OK;
3400 /*********************************************************************
3401 _samr_add_aliasmem
3402 *********************************************************************/
3404 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3406 DOM_SID alias_sid;
3407 fstring alias_sid_str;
3408 uid_t uid;
3409 struct passwd *pwd;
3410 struct group *grp;
3411 fstring grp_name;
3412 GROUP_MAP map;
3413 NTSTATUS ret;
3414 SAM_ACCOUNT *sam_user = NULL;
3415 BOOL check;
3416 uint32 acc_granted;
3418 /* Find the policy handle. Open a policy on it. */
3419 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3420 return NT_STATUS_INVALID_HANDLE;
3422 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3423 return r_u->status;
3426 sid_to_string(alias_sid_str, &alias_sid);
3427 DEBUG(10, ("sid is %s\n", alias_sid_str));
3429 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3430 DEBUG(10, ("adding member on Server SID\n"));
3431 if(!get_local_group_from_sid(alias_sid, &map))
3432 return NT_STATUS_NO_SUCH_ALIAS;
3434 } else {
3435 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3436 DEBUG(10, ("adding member on BUILTIN SID\n"));
3437 if( !get_local_group_from_sid(alias_sid, &map))
3438 return NT_STATUS_NO_SUCH_ALIAS;
3440 } else
3441 return NT_STATUS_NO_SUCH_ALIAS;
3444 ret = pdb_init_sam(&sam_user);
3445 if (!NT_STATUS_IS_OK(ret))
3446 return ret;
3448 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3450 if (check != True) {
3451 pdb_free_sam(&sam_user);
3452 return NT_STATUS_NO_SUCH_USER;
3455 /* check a real user exist before we run the script to add a user to a group */
3456 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3457 pdb_free_sam(&sam_user);
3458 return NT_STATUS_NO_SUCH_USER;
3461 pdb_free_sam(&sam_user);
3463 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3464 return NT_STATUS_NO_SUCH_USER;
3467 if ((grp=getgrgid(map.gid)) == NULL) {
3468 passwd_free(&pwd);
3469 return NT_STATUS_NO_SUCH_ALIAS;
3472 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3473 fstrcpy(grp_name, grp->gr_name);
3475 /* if the user is already in the group */
3476 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3477 passwd_free(&pwd);
3478 return NT_STATUS_MEMBER_IN_ALIAS;
3482 * ok, the group exist, the user exist, the user is not in the group,
3483 * we can (finally) add it to the group !
3485 smb_add_user_group(grp_name, pwd->pw_name);
3487 /* check if the user has been added then ... */
3488 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3489 passwd_free(&pwd);
3490 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3493 passwd_free(&pwd);
3494 return NT_STATUS_OK;
3497 /*********************************************************************
3498 _samr_del_aliasmem
3499 *********************************************************************/
3501 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3503 DOM_SID alias_sid;
3504 fstring alias_sid_str;
3505 struct group *grp;
3506 fstring grp_name;
3507 GROUP_MAP map;
3508 SAM_ACCOUNT *sam_pass=NULL;
3509 uint32 acc_granted;
3511 /* Find the policy handle. Open a policy on it. */
3512 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3513 return NT_STATUS_INVALID_HANDLE;
3515 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3516 return r_u->status;
3519 sid_to_string(alias_sid_str, &alias_sid);
3520 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3522 if (!sid_check_is_in_our_domain(&alias_sid) &&
3523 !sid_check_is_in_builtin(&alias_sid)) {
3524 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3525 return NT_STATUS_NO_SUCH_ALIAS;
3528 if( !get_local_group_from_sid(alias_sid, &map))
3529 return NT_STATUS_NO_SUCH_ALIAS;
3531 if ((grp=getgrgid(map.gid)) == NULL)
3532 return NT_STATUS_NO_SUCH_ALIAS;
3534 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3535 fstrcpy(grp_name, grp->gr_name);
3537 /* check if the user exists before trying to remove it from the group */
3538 pdb_init_sam(&sam_pass);
3539 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3540 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3541 pdb_free_sam(&sam_pass);
3542 return NT_STATUS_NO_SUCH_USER;
3545 /* if the user is not in the group */
3546 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3547 pdb_free_sam(&sam_pass);
3548 return NT_STATUS_MEMBER_IN_ALIAS;
3551 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3553 /* check if the user has been removed then ... */
3554 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3555 pdb_free_sam(&sam_pass);
3556 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3559 pdb_free_sam(&sam_pass);
3560 return NT_STATUS_OK;
3563 /*********************************************************************
3564 _samr_add_groupmem
3565 *********************************************************************/
3567 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3569 DOM_SID group_sid;
3570 DOM_SID user_sid;
3571 fstring group_sid_str;
3572 uid_t uid;
3573 struct passwd *pwd;
3574 struct group *grp;
3575 fstring grp_name;
3576 GROUP_MAP map;
3577 NTSTATUS ret;
3578 SAM_ACCOUNT *sam_user=NULL;
3579 BOOL check;
3580 uint32 acc_granted;
3582 /* Find the policy handle. Open a policy on it. */
3583 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3584 return NT_STATUS_INVALID_HANDLE;
3586 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3587 return r_u->status;
3590 sid_to_string(group_sid_str, &group_sid);
3591 DEBUG(10, ("sid is %s\n", group_sid_str));
3593 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3594 return NT_STATUS_NO_SUCH_GROUP;
3596 DEBUG(10, ("lookup on Domain SID\n"));
3598 if(!get_domain_group_from_sid(group_sid, &map))
3599 return NT_STATUS_NO_SUCH_GROUP;
3601 sid_copy(&user_sid, get_global_sam_sid());
3602 sid_append_rid(&user_sid, q_u->rid);
3604 ret = pdb_init_sam(&sam_user);
3605 if (!NT_STATUS_IS_OK(ret))
3606 return ret;
3608 check = pdb_getsampwsid(sam_user, &user_sid);
3610 if (check != True) {
3611 pdb_free_sam(&sam_user);
3612 return NT_STATUS_NO_SUCH_USER;
3615 /* check a real user exist before we run the script to add a user to a group */
3616 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3617 pdb_free_sam(&sam_user);
3618 return NT_STATUS_NO_SUCH_USER;
3621 pdb_free_sam(&sam_user);
3623 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3624 return NT_STATUS_NO_SUCH_USER;
3627 if ((grp=getgrgid(map.gid)) == NULL) {
3628 passwd_free(&pwd);
3629 return NT_STATUS_NO_SUCH_GROUP;
3632 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3633 fstrcpy(grp_name, grp->gr_name);
3635 /* if the user is already in the group */
3636 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3637 passwd_free(&pwd);
3638 return NT_STATUS_MEMBER_IN_GROUP;
3642 * ok, the group exist, the user exist, the user is not in the group,
3644 * we can (finally) add it to the group !
3647 smb_add_user_group(grp_name, pwd->pw_name);
3649 /* check if the user has been added then ... */
3650 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3651 passwd_free(&pwd);
3652 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3655 passwd_free(&pwd);
3656 return NT_STATUS_OK;
3659 /*********************************************************************
3660 _samr_del_groupmem
3661 *********************************************************************/
3663 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3665 DOM_SID group_sid;
3666 DOM_SID user_sid;
3667 SAM_ACCOUNT *sam_pass=NULL;
3668 GROUP_MAP map;
3669 fstring grp_name;
3670 struct group *grp;
3671 uint32 acc_granted;
3674 * delete the group member named q_u->rid
3675 * who is a member of the sid associated with the handle
3676 * the rid is a user's rid as the group is a domain group.
3679 /* Find the policy handle. Open a policy on it. */
3680 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3681 return NT_STATUS_INVALID_HANDLE;
3683 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3684 return r_u->status;
3687 if (!sid_check_is_in_our_domain(&group_sid))
3688 return NT_STATUS_NO_SUCH_GROUP;
3690 sid_copy(&user_sid, get_global_sam_sid());
3691 sid_append_rid(&user_sid, q_u->rid);
3693 if (!get_domain_group_from_sid(group_sid, &map))
3694 return NT_STATUS_NO_SUCH_GROUP;
3696 if ((grp=getgrgid(map.gid)) == NULL)
3697 return NT_STATUS_NO_SUCH_GROUP;
3699 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3700 fstrcpy(grp_name, grp->gr_name);
3702 /* check if the user exists before trying to remove it from the group */
3703 pdb_init_sam(&sam_pass);
3704 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3705 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3706 pdb_free_sam(&sam_pass);
3707 return NT_STATUS_NO_SUCH_USER;
3710 /* if the user is not in the group */
3711 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3712 pdb_free_sam(&sam_pass);
3713 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3716 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3718 /* check if the user has been removed then ... */
3719 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3720 pdb_free_sam(&sam_pass);
3721 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3724 pdb_free_sam(&sam_pass);
3725 return NT_STATUS_OK;
3729 /****************************************************************************
3730 Delete a UNIX user on demand.
3731 ****************************************************************************/
3733 static int smb_delete_user(const char *unix_user)
3735 pstring del_script;
3736 int ret;
3738 /* try winbindd first since it is impossible to determine where
3739 a user came from via NSS. Try the delete user script if this fails
3740 meaning the user did not exist in winbindd's list of accounts */
3742 if ( winbind_delete_user( unix_user ) ) {
3743 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3744 return 0;
3748 /* fall back to 'delete user script' */
3750 pstrcpy(del_script, lp_deluser_script());
3751 if (! *del_script)
3752 return -1;
3753 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3754 ret = smbrun(del_script,NULL);
3755 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3757 return ret;
3760 /*********************************************************************
3761 _samr_delete_dom_user
3762 *********************************************************************/
3764 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3766 DOM_SID user_sid;
3767 SAM_ACCOUNT *sam_pass=NULL;
3768 uint32 acc_granted;
3770 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3772 /* Find the policy handle. Open a policy on it. */
3773 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3774 return NT_STATUS_INVALID_HANDLE;
3776 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3777 return r_u->status;
3780 if (!sid_check_is_in_our_domain(&user_sid))
3781 return NT_STATUS_CANNOT_DELETE;
3783 /* check if the user exists before trying to delete */
3784 pdb_init_sam(&sam_pass);
3785 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3786 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3787 sid_string_static(&user_sid)));
3788 pdb_free_sam(&sam_pass);
3789 return NT_STATUS_NO_SUCH_USER;
3792 /* delete the unix side */
3794 * note: we don't check if the delete really happened
3795 * as the script is not necessary present
3796 * and maybe the sysadmin doesn't want to delete the unix side
3798 smb_delete_user(pdb_get_username(sam_pass));
3800 /* and delete the samba side */
3801 if (!pdb_delete_sam_account(sam_pass)) {
3802 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3803 pdb_free_sam(&sam_pass);
3804 return NT_STATUS_CANNOT_DELETE;
3807 pdb_free_sam(&sam_pass);
3809 if (!close_policy_hnd(p, &q_u->user_pol))
3810 return NT_STATUS_OBJECT_NAME_INVALID;
3812 return NT_STATUS_OK;
3815 /*********************************************************************
3816 _samr_delete_dom_group
3817 *********************************************************************/
3819 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3821 DOM_SID group_sid;
3822 DOM_SID dom_sid;
3823 uint32 group_rid;
3824 fstring group_sid_str;
3825 gid_t gid;
3826 struct group *grp;
3827 GROUP_MAP map;
3828 uint32 acc_granted;
3830 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3832 /* Find the policy handle. Open a policy on it. */
3833 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3834 return NT_STATUS_INVALID_HANDLE;
3836 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3837 return r_u->status;
3840 sid_copy(&dom_sid, &group_sid);
3841 sid_to_string(group_sid_str, &dom_sid);
3842 sid_split_rid(&dom_sid, &group_rid);
3844 DEBUG(10, ("sid is %s\n", group_sid_str));
3846 /* we check if it's our SID before deleting */
3847 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3848 return NT_STATUS_NO_SUCH_GROUP;
3850 DEBUG(10, ("lookup on Domain SID\n"));
3852 if(!get_domain_group_from_sid(group_sid, &map))
3853 return NT_STATUS_NO_SUCH_GROUP;
3855 gid=map.gid;
3857 /* check if group really exists */
3858 if ( (grp=getgrgid(gid)) == NULL)
3859 return NT_STATUS_NO_SUCH_GROUP;
3861 /* we can delete the UNIX group */
3862 smb_delete_group(grp->gr_name);
3864 /* check if the group has been successfully deleted */
3865 if ( (grp=getgrgid(gid)) != NULL)
3866 return NT_STATUS_ACCESS_DENIED;
3868 if(!pdb_delete_group_mapping_entry(group_sid))
3869 return NT_STATUS_ACCESS_DENIED;
3871 if (!close_policy_hnd(p, &q_u->group_pol))
3872 return NT_STATUS_OBJECT_NAME_INVALID;
3874 return NT_STATUS_OK;
3877 /*********************************************************************
3878 _samr_delete_dom_alias
3879 *********************************************************************/
3881 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3883 DOM_SID alias_sid;
3884 DOM_SID dom_sid;
3885 uint32 alias_rid;
3886 fstring alias_sid_str;
3887 gid_t gid;
3888 struct group *grp;
3889 GROUP_MAP map;
3890 uint32 acc_granted;
3892 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3894 /* Find the policy handle. Open a policy on it. */
3895 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3896 return NT_STATUS_INVALID_HANDLE;
3898 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3899 return r_u->status;
3902 sid_copy(&dom_sid, &alias_sid);
3903 sid_to_string(alias_sid_str, &dom_sid);
3904 sid_split_rid(&dom_sid, &alias_rid);
3906 DEBUG(10, ("sid is %s\n", alias_sid_str));
3908 /* we check if it's our SID before deleting */
3909 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3910 return NT_STATUS_NO_SUCH_ALIAS;
3912 DEBUG(10, ("lookup on Local SID\n"));
3914 if(!get_local_group_from_sid(alias_sid, &map))
3915 return NT_STATUS_NO_SUCH_ALIAS;
3917 gid=map.gid;
3919 /* check if group really exists */
3920 if ( (grp=getgrgid(gid)) == NULL)
3921 return NT_STATUS_NO_SUCH_ALIAS;
3923 /* we can delete the UNIX group */
3924 smb_delete_group(grp->gr_name);
3926 /* check if the group has been successfully deleted */
3927 if ( (grp=getgrgid(gid)) != NULL)
3928 return NT_STATUS_ACCESS_DENIED;
3930 /* don't check if we removed it as it could be an un-mapped group */
3931 pdb_delete_group_mapping_entry(alias_sid);
3933 if (!close_policy_hnd(p, &q_u->alias_pol))
3934 return NT_STATUS_OBJECT_NAME_INVALID;
3936 return NT_STATUS_OK;
3939 /*********************************************************************
3940 _samr_create_dom_group
3941 *********************************************************************/
3943 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3945 DOM_SID dom_sid;
3946 DOM_SID info_sid;
3947 fstring name;
3948 fstring sid_string;
3949 struct group *grp;
3950 struct samr_info *info;
3951 uint32 acc_granted;
3952 gid_t gid;
3954 /* Find the policy handle. Open a policy on it. */
3955 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3956 return NT_STATUS_INVALID_HANDLE;
3958 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3959 return r_u->status;
3962 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3963 return NT_STATUS_ACCESS_DENIED;
3965 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3967 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3969 /* check if group already exist */
3970 if ((grp=getgrnam(name)) != NULL)
3971 return NT_STATUS_GROUP_EXISTS;
3973 /* we can create the UNIX group */
3974 if (smb_create_group(name, &gid) != 0)
3975 return NT_STATUS_ACCESS_DENIED;
3977 /* check if the group has been successfully created */
3978 if ((grp=getgrgid(gid)) == NULL)
3979 return NT_STATUS_ACCESS_DENIED;
3981 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3983 /* add the group to the mapping table */
3984 sid_copy(&info_sid, get_global_sam_sid());
3985 sid_append_rid(&info_sid, r_u->rid);
3986 sid_to_string(sid_string, &info_sid);
3988 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3989 return NT_STATUS_ACCESS_DENIED;
3991 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3992 return NT_STATUS_NO_MEMORY;
3994 /* get a (unique) handle. open a policy on it. */
3995 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3996 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3998 return NT_STATUS_OK;
4001 /*********************************************************************
4002 _samr_create_dom_alias
4003 *********************************************************************/
4005 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4007 DOM_SID dom_sid;
4008 DOM_SID info_sid;
4009 fstring name;
4010 fstring sid_string;
4011 struct group *grp;
4012 struct samr_info *info;
4013 uint32 acc_granted;
4014 gid_t gid;
4016 /* Find the policy handle. Open a policy on it. */
4017 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4018 return NT_STATUS_INVALID_HANDLE;
4020 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4021 return r_u->status;
4024 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4025 return NT_STATUS_ACCESS_DENIED;
4027 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4029 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4031 /* check if group already exists */
4032 if ( (grp=getgrnam(name)) != NULL)
4033 return NT_STATUS_GROUP_EXISTS;
4035 /* we can create the UNIX group */
4036 if (smb_create_group(name, &gid) != 0)
4037 return NT_STATUS_ACCESS_DENIED;
4039 /* check if the group has been successfully created */
4040 if ((grp=getgrgid(gid)) == NULL)
4041 return NT_STATUS_ACCESS_DENIED;
4043 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4045 sid_copy(&info_sid, get_global_sam_sid());
4046 sid_append_rid(&info_sid, r_u->rid);
4047 sid_to_string(sid_string, &info_sid);
4049 /* add the group to the mapping table */
4050 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
4051 return NT_STATUS_ACCESS_DENIED;
4053 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4054 return NT_STATUS_NO_MEMORY;
4056 /* get a (unique) handle. open a policy on it. */
4057 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4058 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4060 return NT_STATUS_OK;
4063 /*********************************************************************
4064 _samr_query_groupinfo
4066 sends the name/comment pair of a domain group
4067 level 1 send also the number of users of that group
4068 *********************************************************************/
4070 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4072 DOM_SID group_sid;
4073 GROUP_MAP map;
4074 uid_t *uid=NULL;
4075 int num_uids=0;
4076 GROUP_INFO_CTR *ctr;
4077 uint32 acc_granted;
4079 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4080 return NT_STATUS_INVALID_HANDLE;
4082 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4083 return r_u->status;
4086 if (!get_domain_group_from_sid(group_sid, &map))
4087 return NT_STATUS_INVALID_HANDLE;
4089 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4090 if (ctr==NULL)
4091 return NT_STATUS_NO_MEMORY;
4093 switch (q_u->switch_level) {
4094 case 1:
4095 ctr->switch_value1 = 1;
4096 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4097 return NT_STATUS_NO_SUCH_GROUP;
4098 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4099 SAFE_FREE(uid);
4100 break;
4101 case 3:
4102 ctr->switch_value1 = 3;
4103 init_samr_group_info3(&ctr->group.info3);
4104 break;
4105 case 4:
4106 ctr->switch_value1 = 4;
4107 init_samr_group_info4(&ctr->group.info4, map.comment);
4108 break;
4109 default:
4110 return NT_STATUS_INVALID_INFO_CLASS;
4113 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4115 return NT_STATUS_OK;
4118 /*********************************************************************
4119 _samr_set_groupinfo
4121 update a domain group's comment.
4122 *********************************************************************/
4124 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4126 DOM_SID group_sid;
4127 GROUP_MAP map;
4128 GROUP_INFO_CTR *ctr;
4129 uint32 acc_granted;
4131 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4132 return NT_STATUS_INVALID_HANDLE;
4134 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4135 return r_u->status;
4138 if (!get_domain_group_from_sid(group_sid, &map))
4139 return NT_STATUS_NO_SUCH_GROUP;
4141 ctr=q_u->ctr;
4143 switch (ctr->switch_value1) {
4144 case 1:
4145 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4146 break;
4147 case 4:
4148 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4149 break;
4150 default:
4151 return NT_STATUS_INVALID_INFO_CLASS;
4154 if(!pdb_update_group_mapping_entry(&map)) {
4155 return NT_STATUS_NO_SUCH_GROUP;
4158 return NT_STATUS_OK;
4161 /*********************************************************************
4162 _samr_set_aliasinfo
4164 update an alias's comment.
4165 *********************************************************************/
4167 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4169 DOM_SID group_sid;
4170 GROUP_MAP map;
4171 ALIAS_INFO_CTR *ctr;
4172 uint32 acc_granted;
4174 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4175 return NT_STATUS_INVALID_HANDLE;
4177 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4178 return r_u->status;
4181 if (!get_local_group_from_sid(group_sid, &map))
4182 return NT_STATUS_NO_SUCH_GROUP;
4184 ctr=&q_u->ctr;
4186 switch (ctr->switch_value1) {
4187 case 3:
4188 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4189 break;
4190 default:
4191 return NT_STATUS_INVALID_INFO_CLASS;
4194 if(!pdb_update_group_mapping_entry(&map)) {
4195 return NT_STATUS_NO_SUCH_GROUP;
4198 return NT_STATUS_OK;
4201 /*********************************************************************
4202 _samr_get_dom_pwinfo
4203 *********************************************************************/
4205 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4207 /* Perform access check. Since this rpc does not require a
4208 policy handle it will not be caught by the access checks on
4209 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4211 if (!pipe_access_check(p)) {
4212 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4213 r_u->status = NT_STATUS_ACCESS_DENIED;
4214 return r_u->status;
4217 /* Actually, returning zeros here works quite well :-). */
4219 return NT_STATUS_OK;
4222 /*********************************************************************
4223 _samr_open_group
4224 *********************************************************************/
4226 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4228 DOM_SID sid;
4229 DOM_SID info_sid;
4230 GROUP_MAP map;
4231 struct samr_info *info;
4232 SEC_DESC *psd = NULL;
4233 uint32 acc_granted;
4234 uint32 des_access = q_u->access_mask;
4235 size_t sd_size;
4236 NTSTATUS status;
4237 fstring sid_string;
4239 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4240 return NT_STATUS_INVALID_HANDLE;
4242 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4243 return status;
4246 /*check if access can be granted as requested by client. */
4247 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4248 se_map_generic(&des_access,&grp_generic_mapping);
4249 if (!NT_STATUS_IS_OK(status =
4250 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4251 des_access, &acc_granted, "_samr_open_group"))) {
4252 return status;
4256 /* this should not be hard-coded like this */
4257 if (!sid_equal(&sid, get_global_sam_sid()))
4258 return NT_STATUS_ACCESS_DENIED;
4260 sid_copy(&info_sid, get_global_sam_sid());
4261 sid_append_rid(&info_sid, q_u->rid_group);
4262 sid_to_string(sid_string, &info_sid);
4264 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4265 return NT_STATUS_NO_MEMORY;
4267 info->acc_granted = acc_granted;
4269 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4271 /* check if that group really exists */
4272 if (!get_domain_group_from_sid(info->sid, &map))
4273 return NT_STATUS_NO_SUCH_GROUP;
4275 /* get a (unique) handle. open a policy on it. */
4276 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4277 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4279 return NT_STATUS_OK;
4282 /*********************************************************************
4283 _samr_remove_user_foreign_domain
4284 *********************************************************************/
4286 NTSTATUS _samr_remove_user_foreign_domain(pipes_struct *p,
4287 SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN *q_u,
4288 SAMR_R_REMOVE_USER_FOREIGN_DOMAIN *r_u)
4290 DOM_SID user_sid, dom_sid;
4291 SAM_ACCOUNT *sam_pass=NULL;
4292 uint32 acc_granted;
4294 sid_copy( &user_sid, &q_u->sid.sid );
4296 DEBUG(5,("_samr_remove_user_foreign_domain: removing user [%s]\n",
4297 sid_string_static(&user_sid)));
4299 /* Find the policy handle. Open a policy on it. */
4301 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4302 return NT_STATUS_INVALID_HANDLE;
4304 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted,
4305 STD_RIGHT_DELETE_ACCESS, "_samr_remove_user_foreign_domain")))
4307 return r_u->status;
4310 if ( !sid_check_is_in_our_domain(&user_sid) ) {
4311 DEBUG(5,("_samr_remove_user_foreign_domain: user not is our domain!\n"));
4312 return NT_STATUS_NO_SUCH_USER;
4315 /* check if the user exists before trying to delete */
4317 pdb_init_sam(&sam_pass);
4319 if ( !pdb_getsampwsid(sam_pass, &user_sid) ) {
4321 DEBUG(5,("_samr_remove_user_foreign_domain:User %s doesn't exist.\n",
4322 sid_string_static(&user_sid)));
4324 pdb_free_sam(&sam_pass);
4326 return NT_STATUS_NO_SUCH_USER;
4330 * delete the unix side
4332 * note: we don't check if the delete really happened
4333 * as the script is not necessary present
4334 * and maybe the sysadmin doesn't want to delete the unix side
4337 smb_delete_user(pdb_get_username(sam_pass));
4339 /* and delete the samba side */
4341 if ( !pdb_delete_sam_account(sam_pass) ) {
4343 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
4344 pdb_free_sam(&sam_pass);
4346 return NT_STATUS_CANNOT_DELETE;
4349 pdb_free_sam(&sam_pass);
4351 return NT_STATUS_OK;
4354 /*******************************************************************
4355 _samr_unknown_2e
4356 ********************************************************************/
4358 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4360 struct samr_info *info = NULL;
4361 SAM_UNK_CTR *ctr;
4362 uint32 min_pass_len,pass_hist,flag;
4363 time_t u_expire, u_min_age;
4364 NTTIME nt_expire, nt_min_age;
4366 time_t u_lock_duration, u_reset_time;
4367 NTTIME nt_lock_duration, nt_reset_time;
4368 uint32 lockout;
4370 time_t u_logout;
4371 NTTIME nt_logout;
4373 uint32 num_users=0, num_groups=0, num_aliases=0;
4375 uint32 account_policy_temp;
4377 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4378 return NT_STATUS_NO_MEMORY;
4380 ZERO_STRUCTP(ctr);
4382 r_u->status = NT_STATUS_OK;
4384 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4386 /* find the policy handle. open a policy on it. */
4387 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4388 return NT_STATUS_INVALID_HANDLE;
4390 switch (q_u->switch_value) {
4391 case 0x01:
4392 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4393 min_pass_len = account_policy_temp;
4395 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4396 pass_hist = account_policy_temp;
4398 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4399 flag = account_policy_temp;
4401 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4402 u_expire = account_policy_temp;
4404 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4405 u_min_age = account_policy_temp;
4407 unix_to_nt_time_abs(&nt_expire, u_expire);
4408 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4410 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4411 flag, nt_expire, nt_min_age);
4412 break;
4413 case 0x02:
4414 become_root();
4415 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4416 unbecome_root();
4417 if (!NT_STATUS_IS_OK(r_u->status)) {
4418 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4419 return r_u->status;
4421 num_users=info->disp_info.num_user_account;
4422 free_samr_db(info);
4424 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4425 if (NT_STATUS_IS_ERR(r_u->status)) {
4426 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4427 return r_u->status;
4429 num_groups=info->disp_info.num_group_account;
4430 free_samr_db(info);
4432 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4433 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4434 num_users, num_groups, num_aliases);
4435 break;
4436 case 0x03:
4437 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4438 u_logout = account_policy_temp;
4440 unix_to_nt_time_abs(&nt_logout, u_logout);
4442 init_unk_info3(&ctr->info.inf3, nt_logout);
4443 break;
4444 case 0x05:
4445 init_unk_info5(&ctr->info.inf5, global_myname());
4446 break;
4447 case 0x06:
4448 init_unk_info6(&ctr->info.inf6);
4449 break;
4450 case 0x07:
4451 init_unk_info7(&ctr->info.inf7);
4452 break;
4453 case 0x0c:
4454 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4455 u_lock_duration = account_policy_temp;
4457 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4458 u_reset_time = account_policy_temp;
4460 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4461 lockout = account_policy_temp;
4463 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4464 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4466 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4467 break;
4468 default:
4469 return NT_STATUS_INVALID_INFO_CLASS;
4472 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4474 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4476 return r_u->status;
4479 /*******************************************************************
4480 _samr_
4481 ********************************************************************/
4483 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4485 time_t u_expire, u_min_age;
4486 time_t u_logout;
4487 time_t u_lock_duration, u_reset_time;
4489 r_u->status = NT_STATUS_OK;
4491 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4493 /* find the policy handle. open a policy on it. */
4494 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4495 return NT_STATUS_INVALID_HANDLE;
4497 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4499 switch (q_u->switch_value) {
4500 case 0x01:
4501 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4502 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4504 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4505 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4506 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4507 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4508 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4509 break;
4510 case 0x02:
4511 break;
4512 case 0x03:
4513 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4514 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4515 break;
4516 case 0x05:
4517 break;
4518 case 0x06:
4519 break;
4520 case 0x07:
4521 break;
4522 case 0x0c:
4523 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4524 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4526 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4527 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4528 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4529 break;
4530 default:
4531 return NT_STATUS_INVALID_INFO_CLASS;
4534 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4536 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4538 return r_u->status;