Removed some misleading comment.
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_samr_nt.c
blobee4335cb0ab414b5125008cc3180f58e01544e4a
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) Anthony Liguori 2002,
11 * Copyright (C) Jim McDonough 2002.
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 fstring global_myworkgroup;
38 extern pstring global_myname;
39 extern DOM_SID global_sid_Builtin;
41 extern rid_name domain_group_rids[];
42 extern rid_name domain_alias_rids[];
43 extern rid_name builtin_alias_rids[];
46 typedef struct _disp_info {
47 BOOL user_dbloaded;
48 uint32 num_user_account;
49 DISP_USER_INFO *disp_user_info;
50 BOOL group_dbloaded;
51 uint32 num_group_account;
52 DISP_GROUP_INFO *disp_group_info;
53 } DISP_INFO;
55 struct samr_info {
56 /* for use by the \PIPE\samr policy */
57 DOM_SID sid;
58 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
59 uint32 acc_granted;
60 DISP_INFO disp_info;
62 TALLOC_CTX *mem_ctx;
65 struct generic_mapping sam_generic_mapping = {SAMR_READ, SAMR_WRITE, SAMR_EXECUTE, SAMR_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {DOMAIN_READ, DOMAIN_WRITE, DOMAIN_EXECUTE, DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {USER_READ, USER_WRITE, USER_EXECUTE, USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {ALIAS_READ, ALIAS_WRITE, ALIAS_EXECUTE, 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 if (geteuid() == sec_initial_uid()) {
85 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
86 debug, des_access));
87 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
88 status = NT_STATUS_OK;
90 else {
91 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
92 debug, des_access));
95 return status;
98 /*******************************************************************
99 Checks if access to a function can be granted
100 ********************************************************************/
102 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
104 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
105 debug, acc_granted, acc_required));
106 if ((acc_granted & acc_required) != acc_required) {
107 if (geteuid() == sec_initial_uid()) {
108 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
109 debug, acc_granted, acc_required));
110 DEBUGADD(4,("but overwritten by euid == 0\n"));
111 return NT_STATUS_OK;
113 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
114 debug, acc_granted, acc_required));
115 return NT_STATUS_ACCESS_DENIED;
117 return NT_STATUS_OK;
121 /*******************************************************************
122 Create a samr_info struct.
123 ********************************************************************/
125 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
127 struct samr_info *info;
128 fstring sid_str;
129 TALLOC_CTX *mem_ctx;
131 if (psid) {
132 sid_to_string(sid_str, psid);
133 } else {
134 fstrcpy(sid_str,"(NULL)");
137 mem_ctx = talloc_init_named("samr_info for domain sid %s", sid_str);
139 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
140 return NULL;
142 ZERO_STRUCTP(info);
143 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
144 if (psid) {
145 sid_copy( &info->sid, psid);
146 } else {
147 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
149 info->mem_ctx = mem_ctx;
150 return info;
153 /*******************************************************************
154 Function to free the per handle data.
155 ********************************************************************/
156 static void free_samr_db(struct samr_info *info)
158 int i;
160 /* Groups are talloced */
162 if (info->disp_info.user_dbloaded){
163 for (i=0; i<info->disp_info.num_user_account; i++) {
164 /* Not really a free, actually a 'clear' */
165 pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.group_dbloaded=False;
171 info->disp_info.num_group_account=0;
172 info->disp_info.num_user_account=0;
176 static void free_samr_info(void *ptr)
178 struct samr_info *info=(struct samr_info *) ptr;
180 free_samr_db(info);
181 talloc_destroy(info->mem_ctx);
184 /*******************************************************************
185 Ensure password info is never given out. Paranioa... JRA.
186 ********************************************************************/
188 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
191 if (!sam_pass)
192 return;
194 /* These now zero out the old password */
196 pdb_set_lanman_passwd(sam_pass, NULL);
197 pdb_set_nt_passwd(sam_pass, NULL);
201 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask)
203 SAM_ACCOUNT *pwd = NULL;
204 DISP_USER_INFO *pwd_array = NULL;
205 NTSTATUS nt_status = NT_STATUS_OK;
206 TALLOC_CTX *mem_ctx = info->mem_ctx;
208 DEBUG(10,("load_sampwd_entries\n"));
210 /* if the snapshoot is already loaded, return */
211 if (info->disp_info.user_dbloaded==True) {
212 DEBUG(10,("load_sampwd_entries: already in memory\n"));
213 return NT_STATUS_OK;
216 if (!pdb_setsampwent(False)) {
217 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
218 return NT_STATUS_ACCESS_DENIED;
221 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
222 && pdb_getsampwent(pwd) == True; pwd=NULL) {
224 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
225 pdb_free_sam(&pwd);
226 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
227 continue;
230 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
231 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
233 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
234 pwd_array=(DISP_USER_INFO *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
235 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
237 if (pwd_array==NULL)
238 return NT_STATUS_NO_MEMORY;
240 info->disp_info.disp_user_info=pwd_array;
243 /* link the SAM_ACCOUNT to the array */
244 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
246 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
248 info->disp_info.num_user_account++;
251 pdb_endsampwent();
253 /* the snapshoot is in memory, we're ready to enumerate fast */
255 info->disp_info.user_dbloaded=True;
257 DEBUG(12,("load_sampwd_entries: done\n"));
259 return nt_status;
262 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
264 GROUP_MAP *map=NULL;
265 DISP_GROUP_INFO *grp_array = NULL;
266 uint32 group_entries = 0;
267 uint32 i;
268 TALLOC_CTX *mem_ctx = info->mem_ctx;
270 DEBUG(10,("load_group_domain_entries\n"));
272 /* if the snapshoot is already loaded, return */
273 if (info->disp_info.group_dbloaded==True) {
274 DEBUG(10,("load_group_domain_entries: already in memory\n"));
275 return NT_STATUS_OK;
278 if (!enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) {
279 return NT_STATUS_NO_MEMORY;
282 info->disp_info.num_group_account=group_entries;
284 grp_array=(DISP_GROUP_INFO *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
286 if (group_entries!=0 && grp_array==NULL) {
287 SAFE_FREE(map);
288 return NT_STATUS_NO_MEMORY;
291 info->disp_info.disp_group_info=grp_array;
293 for (i=0; i<group_entries; i++) {
295 grp_array[i].grp=(DOMAIN_GRP *)talloc(mem_ctx, sizeof(DOMAIN_GRP));
297 fstrcpy(grp_array[i].grp->name, map[i].nt_name);
298 fstrcpy(grp_array[i].grp->comment, map[i].comment);
299 sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
300 grp_array[i].grp->attr=SID_NAME_DOM_GRP;
303 SAFE_FREE(map);
305 /* the snapshoot is in memory, we're ready to enumerate fast */
307 info->disp_info.group_dbloaded=True;
309 DEBUG(12,("load_group_domain_entries: done\n"));
311 return NT_STATUS_OK;
315 /*******************************************************************
316 _samr_close_hnd
317 ********************************************************************/
319 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
321 r_u->status = NT_STATUS_OK;
323 /* close the policy handle */
324 if (!close_policy_hnd(p, &q_u->pol))
325 return NT_STATUS_OBJECT_NAME_INVALID;
327 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
329 return r_u->status;
332 /*******************************************************************
333 samr_reply_open_domain
334 ********************************************************************/
336 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
338 struct samr_info *info;
339 SEC_DESC *psd = NULL;
340 uint32 acc_granted;
341 uint32 des_access = q_u->flags;
342 size_t sd_size;
343 NTSTATUS status;
345 r_u->status = NT_STATUS_OK;
347 /* find the connection policy handle. */
348 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
349 return NT_STATUS_INVALID_HANDLE;
351 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SAMR_ACCESS_OPEN_DOMAIN,"_samr_open_domain"))) {
352 return status;
355 /*check if access can be granted as requested by client. */
356 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
357 se_map_generic(&des_access,&dom_generic_mapping);
359 if (!NT_STATUS_IS_OK(status =
360 access_check_samr_object(psd, p->pipe_user.nt_user_token,
361 des_access, &acc_granted, "_samr_open_domain"))) {
362 return status;
365 /* associate the domain SID with the (unique) handle. */
366 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
367 return NT_STATUS_NO_MEMORY;
368 info->acc_granted = acc_granted;
370 /* get a (unique) handle. open a policy on it. */
371 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
372 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
374 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
376 return r_u->status;
379 /*******************************************************************
380 _samr_get_usrdom_pwinfo
381 ********************************************************************/
383 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
385 struct samr_info *info = NULL;
387 r_u->status = NT_STATUS_OK;
389 /* find the policy handle. open a policy on it. */
390 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
391 return NT_STATUS_INVALID_HANDLE;
393 if (!sid_check_is_in_our_domain(&info->sid))
394 return NT_STATUS_OBJECT_TYPE_MISMATCH;
396 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
398 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
401 * NT sometimes return NT_STATUS_ACCESS_DENIED
402 * I don't know yet why.
405 return r_u->status;
408 /*******************************************************************
409 samr_make_dom_obj_sd
410 ********************************************************************/
412 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
414 extern DOM_SID global_sid_World;
415 DOM_SID adm_sid;
416 DOM_SID act_sid;
418 SEC_ACE ace[3];
419 SEC_ACCESS mask;
421 SEC_ACL *psa = NULL;
423 sid_copy(&adm_sid, &global_sid_Builtin);
424 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
426 sid_copy(&act_sid, &global_sid_Builtin);
427 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
429 /*basic access for every one*/
430 init_sec_access(&mask, DOMAIN_EXECUTE | DOMAIN_READ);
431 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
433 /*full access for builtin aliases Administrators and Account Operators*/
434 init_sec_access(&mask, DOMAIN_ALL_ACCESS);
435 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
436 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
438 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
439 return NT_STATUS_NO_MEMORY;
441 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
442 return NT_STATUS_NO_MEMORY;
444 return NT_STATUS_OK;
447 /*******************************************************************
448 samr_make_usr_obj_sd
449 ********************************************************************/
451 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
453 extern DOM_SID global_sid_World;
454 DOM_SID adm_sid;
455 DOM_SID act_sid;
457 SEC_ACE ace[4];
458 SEC_ACCESS mask;
460 SEC_ACL *psa = NULL;
462 sid_copy(&adm_sid, &global_sid_Builtin);
463 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
465 sid_copy(&act_sid, &global_sid_Builtin);
466 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
468 /*basic access for every one*/
469 init_sec_access(&mask, USER_EXECUTE | USER_READ);
470 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
472 /*full access for builtin aliases Administrators and Account Operators*/
473 init_sec_access(&mask, USER_ALL_ACCESS);
474 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
475 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
477 /*extended access for the user*/
478 init_sec_access(&mask,READ_CONTROL_ACCESS | USER_ACCESS_CHANGE_PASSWORD | USER_ACCESS_SET_LOC_COM);
479 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
481 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
482 return NT_STATUS_NO_MEMORY;
484 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
485 return NT_STATUS_NO_MEMORY;
487 return NT_STATUS_OK;
490 /*******************************************************************
491 samr_make_grp_obj_sd
492 ********************************************************************/
494 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
496 extern DOM_SID global_sid_World;
497 DOM_SID adm_sid;
498 DOM_SID act_sid;
500 SEC_ACE ace[3];
501 SEC_ACCESS mask;
503 SEC_ACL *psa = NULL;
505 sid_copy(&adm_sid, &global_sid_Builtin);
506 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
508 sid_copy(&act_sid, &global_sid_Builtin);
509 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
511 /*basic access for every one*/
512 init_sec_access(&mask, GROUP_EXECUTE | GROUP_READ);
513 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
515 /*full access for builtin aliases Administrators and Account Operators*/
516 init_sec_access(&mask, GROUP_ALL_ACCESS);
517 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
518 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
520 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
521 return NT_STATUS_NO_MEMORY;
523 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
524 return NT_STATUS_NO_MEMORY;
526 return NT_STATUS_OK;
529 /*******************************************************************
530 samr_make_ali_obj_sd
531 ********************************************************************/
533 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
535 extern DOM_SID global_sid_World;
536 DOM_SID adm_sid;
537 DOM_SID act_sid;
539 SEC_ACE ace[3];
540 SEC_ACCESS mask;
542 SEC_ACL *psa = NULL;
544 sid_copy(&adm_sid, &global_sid_Builtin);
545 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
547 sid_copy(&act_sid, &global_sid_Builtin);
548 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
550 /*basic access for every one*/
551 init_sec_access(&mask, ALIAS_EXECUTE | ALIAS_READ);
552 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
554 /*full access for builtin aliases Administrators and Account Operators*/
555 init_sec_access(&mask, ALIAS_ALL_ACCESS);
556 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
557 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
559 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
560 return NT_STATUS_NO_MEMORY;
562 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
563 return NT_STATUS_NO_MEMORY;
565 return NT_STATUS_OK;
568 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
570 struct samr_info *info = NULL;
572 /* find the policy handle. open a policy on it. */
573 if (!find_policy_by_hnd(p, pol, (void **)&info))
574 return False;
576 if (!info)
577 return False;
579 *sid = info->sid;
580 *acc_granted = info->acc_granted;
581 return True;
584 /*******************************************************************
585 _samr_set_sec_obj
586 ********************************************************************/
588 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
590 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
591 return NT_STATUS_NOT_IMPLEMENTED;
595 /*******************************************************************
596 _samr_query_sec_obj
597 ********************************************************************/
599 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
601 DOM_SID pol_sid;
602 fstring str_sid;
603 SEC_DESC * psd = NULL;
604 size_t sd_size;
605 uint32 acc_granted;
607 r_u->status = NT_STATUS_OK;
609 /* Get the SID. */
610 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
611 return NT_STATUS_INVALID_HANDLE;
615 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
617 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
619 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
620 if (pol_sid.sid_rev_num == 0)
622 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
623 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
625 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
628 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
629 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
631 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
633 /* TODO: Builtin probably needs a different SD with restricted write access*/
634 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
635 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
637 else if (sid_check_is_in_our_domain(&pol_sid) ||
638 sid_check_is_in_builtin(&pol_sid))
640 /* TODO: different SDs have to be generated for aliases groups and users.
641 Currently all three get a default user SD */
642 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
643 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
645 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
647 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
648 return NT_STATUS_NO_MEMORY;
650 if (NT_STATUS_IS_OK(r_u->status))
651 r_u->ptr = 1;
653 return r_u->status;
656 /*******************************************************************
657 makes a SAM_ENTRY / UNISTR2* structure from a user list.
658 ********************************************************************/
660 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
661 uint32 num_entries, uint32 start_idx, DISP_USER_INFO *disp_user_info,
662 DOM_SID *domain_sid)
664 uint32 i;
665 SAM_ENTRY *sam;
666 UNISTR2 *uni_name;
667 SAM_ACCOUNT *pwd = NULL;
668 UNISTR2 uni_temp_name;
669 const char *temp_name;
670 const DOM_SID *user_sid;
671 uint32 user_rid;
672 fstring user_sid_string;
673 fstring domain_sid_string;
675 *sam_pp = NULL;
676 *uni_name_pp = NULL;
678 if (num_entries == 0)
679 return NT_STATUS_OK;
681 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
683 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
685 if (sam == NULL || uni_name == NULL) {
686 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
687 return NT_STATUS_NO_MEMORY;
690 for (i = 0; i < num_entries; i++) {
691 pwd = disp_user_info[i+start_idx].sam;
692 temp_name = pdb_get_username(pwd);
693 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
694 user_sid = pdb_get_user_sid(pwd);
696 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
697 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
698 "the domain sid %s. Failing operation.\n",
699 temp_name,
700 sid_to_string(user_sid_string, user_sid),
701 sid_to_string(domain_sid_string, domain_sid)));
702 return NT_STATUS_UNSUCCESSFUL;
705 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
706 copy_unistr2(&uni_name[i], &uni_temp_name);
709 *sam_pp = sam;
710 *uni_name_pp = uni_name;
711 return NT_STATUS_OK;
714 /*******************************************************************
715 samr_reply_enum_dom_users
716 ********************************************************************/
718 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
719 SAMR_R_ENUM_DOM_USERS *r_u)
721 struct samr_info *info = NULL;
722 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
723 int num_account;
724 uint32 enum_context=q_u->start_idx;
725 uint32 max_size=q_u->max_size;
726 uint32 temp_size;
727 enum remote_arch_types ra_type = get_remote_arch();
728 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
729 uint32 max_entries = max_sam_entries;
730 DOM_SID domain_sid;
732 r_u->status = NT_STATUS_OK;
734 /* find the policy handle. open a policy on it. */
735 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
736 return NT_STATUS_INVALID_HANDLE;
738 domain_sid = info->sid;
740 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
741 DOMAIN_ACCESS_ENUM_ACCOUNTS,
742 "_samr_enum_dom_users"))) {
743 return r_u->status;
746 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
748 become_root();
749 r_u->status=load_sampwd_entries(info, q_u->acb_mask);
750 unbecome_root();
752 if (!NT_STATUS_IS_OK(r_u->status))
753 return r_u->status;
755 num_account = info->disp_info.num_user_account;
757 if (enum_context > num_account) {
758 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
759 return NT_STATUS_OK;
762 /* verify we won't overflow */
763 if (max_entries > num_account-enum_context) {
764 max_entries = num_account-enum_context;
765 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
768 /* calculate the size and limit on the number of entries we will return */
769 temp_size=max_entries*struct_size;
771 if (temp_size>max_size) {
772 max_entries=MIN((max_size/struct_size),max_entries);;
773 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
777 * Note from JRA. total_entries is not being used here. Currently if there is a
778 * large user base then it looks like NT will enumerate until get_sampwd_entries
779 * returns False due to num_entries being zero. This will cause an access denied
780 * return. I don't think this is right and needs further investigation. Note that
781 * this is also the same in the TNG code (I don't think that has been tested with
782 * a very large user list as MAX_SAM_ENTRIES is set to 600).
784 * I also think that one of the 'num_entries' return parameters is probably
785 * the "max entries" parameter - but in the TNG code they're all currently set to the same
786 * value (again I think this is wrong).
789 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
790 max_entries, enum_context,
791 info->disp_info.disp_user_info,
792 &domain_sid);
794 if (!NT_STATUS_IS_OK(r_u->status))
795 return r_u->status;
797 if (enum_context+max_entries < num_account)
798 r_u->status = STATUS_MORE_ENTRIES;
800 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
802 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
804 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
806 return r_u->status;
809 /*******************************************************************
810 makes a SAM_ENTRY / UNISTR2* structure from a group list.
811 ********************************************************************/
813 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
814 uint32 num_sam_entries, DOMAIN_GRP *grp)
816 uint32 i;
817 SAM_ENTRY *sam;
818 UNISTR2 *uni_name;
820 *sam_pp = NULL;
821 *uni_name_pp = NULL;
823 if (num_sam_entries == 0)
824 return;
826 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
828 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
830 if (sam == NULL || uni_name == NULL) {
831 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
832 return;
835 for (i = 0; i < num_sam_entries; i++) {
837 * JRA. I think this should include the null. TNG does not.
839 int len = strlen(grp[i].name)+1;
841 init_sam_entry(&sam[i], len, grp[i].rid);
842 init_unistr2(&uni_name[i], grp[i].name, len);
845 *sam_pp = sam;
846 *uni_name_pp = uni_name;
849 /*******************************************************************
850 Get the group entries - similar to get_sampwd_entries().
851 ********************************************************************/
853 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
854 uint32 *p_num_entries, uint32 max_entries)
856 fstring sid_str;
857 uint32 num_entries = 0;
858 int i;
859 GROUP_MAP smap;
860 GROUP_MAP *map;
862 sid_to_string(sid_str, sid);
863 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
865 *p_num_entries = 0;
867 /* well-known aliases */
868 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
870 enum_group_mapping(SID_NAME_ALIAS, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
872 if (num_entries != 0) {
873 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
874 if (*d_grp==NULL)
875 return NT_STATUS_NO_MEMORY;
877 for(i=0; i<num_entries && i<max_entries; i++) {
878 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
879 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
883 SAFE_FREE(map);
885 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
886 struct sys_grent *glist;
887 struct sys_grent *grp;
888 struct passwd *pw;
889 gid_t winbind_gid_low, winbind_gid_high;
890 BOOL winbind_groups_exist = lp_winbind_gid(&winbind_gid_low, &winbind_gid_high);
892 /* local aliases */
893 /* we return the UNIX groups here. This seems to be the right */
894 /* thing to do, since NT member servers return their local */
895 /* groups in the same situation. */
897 /* use getgrent_list() to retrieve the list of groups to avoid
898 * problems with getgrent possible infinite loop by internal
899 * libc grent structures overwrites by called functions */
900 grp = glist = getgrent_list();
901 if (grp == NULL)
902 return NT_STATUS_NO_MEMORY;
904 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
905 uint32 trid;
907 if(!get_group_from_gid(grp->gr_gid, &smap, MAPPING_WITHOUT_PRIV))
908 continue;
910 if (smap.sid_name_use!=SID_NAME_ALIAS) {
911 continue;
914 sid_split_rid(&smap.sid, &trid);
916 if (!sid_equal(sid, &smap.sid))
917 continue;
919 /* Don't return winbind groups as they are not local! */
920 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
921 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
922 continue;
925 /* Don't return user private groups... */
927 if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
928 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
929 continue;
932 for( i = 0; i < num_entries; i++)
933 if ( (*d_grp)[i].rid == trid )
934 break;
936 if ( i < num_entries ) {
937 continue; /* rid was there, dup! */
940 /* JRA - added this for large group db enumeration... */
942 if (start_idx > 0) {
943 /* skip the requested number of entries.
944 not very efficient, but hey...
946 start_idx--;
947 continue;
950 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
951 if (*d_grp==NULL) {
952 grent_free(glist);
953 return NT_STATUS_NO_MEMORY;
956 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
957 (*d_grp)[num_entries].rid = trid;
958 num_entries++;
959 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
962 grent_free(glist);
965 *p_num_entries = num_entries;
967 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
969 if (num_entries >= max_entries)
970 return STATUS_MORE_ENTRIES;
971 return NT_STATUS_OK;
974 /*******************************************************************
975 Get the group entries - similar to get_sampwd_entries().
976 ********************************************************************/
978 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
979 uint32 *p_num_entries, uint32 max_entries)
981 GROUP_MAP *map=NULL;
982 int i;
983 uint32 group_entries = 0;
984 uint32 num_entries = 0;
986 *p_num_entries = 0;
988 enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
990 num_entries=group_entries-start_idx;
992 /* limit the number of entries */
993 if (num_entries>max_entries) {
994 DEBUG(5,("Limiting to %d entries\n", max_entries));
995 num_entries=max_entries;
998 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
999 if (num_entries!=0 && *d_grp==NULL){
1000 SAFE_FREE(map);
1001 return NT_STATUS_NO_MEMORY;
1004 for (i=0; i<num_entries; i++) {
1005 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1006 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1007 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1008 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1011 SAFE_FREE(map);
1013 *p_num_entries = num_entries;
1015 return NT_STATUS_OK;
1018 /*******************************************************************
1019 samr_reply_enum_dom_groups
1020 ********************************************************************/
1022 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1024 DOMAIN_GRP *grp=NULL;
1025 uint32 num_entries;
1026 DOM_SID sid;
1027 uint32 acc_granted;
1029 r_u->status = NT_STATUS_OK;
1031 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1032 return NT_STATUS_INVALID_HANDLE;
1034 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1035 return r_u->status;
1038 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1040 /* the domain group array is being allocated in the function below */
1041 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))) {
1042 return r_u->status;
1045 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1047 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1049 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1051 return r_u->status;
1055 /*******************************************************************
1056 samr_reply_enum_dom_aliases
1057 ********************************************************************/
1059 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1061 DOMAIN_GRP *grp=NULL;
1062 uint32 num_entries = 0;
1063 fstring sid_str;
1064 DOM_SID sid;
1065 NTSTATUS status;
1066 uint32 acc_granted;
1068 r_u->status = NT_STATUS_OK;
1070 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1071 return NT_STATUS_INVALID_HANDLE;
1073 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1074 return r_u->status;
1077 sid_to_string(sid_str, &sid);
1078 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1080 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1081 &num_entries, MAX_SAM_ENTRIES);
1082 if (NT_STATUS_IS_ERR(status)) return status;
1084 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1086 /*safe_free(grp);*/
1088 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1090 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1092 return r_u->status;
1095 /*******************************************************************
1096 samr_reply_query_dispinfo
1097 ********************************************************************/
1098 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1099 SAMR_R_QUERY_DISPINFO *r_u)
1101 struct samr_info *info = NULL;
1102 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1103 uint16 acb_mask;
1105 uint32 max_entries=q_u->max_entries;
1106 uint32 enum_context=q_u->start_idx;
1107 uint32 max_size=q_u->max_size;
1109 SAM_DISPINFO_CTR *ctr;
1110 uint32 temp_size=0, total_data_size=0;
1111 NTSTATUS disp_ret;
1112 uint32 num_account = 0;
1113 enum remote_arch_types ra_type = get_remote_arch();
1114 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1115 DOM_SID domain_sid;
1117 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1118 r_u->status = NT_STATUS_OK;
1120 /* find the policy handle. open a policy on it. */
1121 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1122 return NT_STATUS_INVALID_HANDLE;
1124 domain_sid = info->sid;
1127 * calculate how many entries we will return.
1128 * based on
1129 * - the number of entries the client asked
1130 * - our limit on that
1131 * - the starting point (enumeration context)
1132 * - the buffer size the client will accept
1136 * We are a lot more like W2K. Instead of reading the SAM
1137 * each time to find the records we need to send back,
1138 * we read it once and link that copy to the sam handle.
1139 * For large user list (over the MAX_SAM_ENTRIES)
1140 * it's a definitive win.
1141 * second point to notice: between enumerations
1142 * our sam is now the same as it's a snapshoot.
1143 * third point: got rid of the static SAM_USER_21 struct
1144 * no more intermediate.
1145 * con: it uses much more memory, as a full copy is stored
1146 * in memory.
1148 * If you want to change it, think twice and think
1149 * of the second point , that's really important.
1151 * JFM, 12/20/2001
1154 /* Get what we need from the password database */
1156 if (q_u->switch_level==2)
1157 acb_mask = ACB_WSTRUST;
1158 else
1159 acb_mask = ACB_NORMAL;
1161 /* Get what we need from the password database */
1162 switch (q_u->switch_level) {
1163 case 0x1:
1164 case 0x2:
1165 case 0x4:
1166 become_root();
1167 r_u->status=load_sampwd_entries(info, acb_mask);
1168 unbecome_root();
1169 if (!NT_STATUS_IS_OK(r_u->status)) {
1170 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1171 return r_u->status;
1173 num_account = info->disp_info.num_user_account;
1174 break;
1175 case 0x3:
1176 case 0x5:
1177 r_u->status = load_group_domain_entries(info, &info->sid);
1178 if (!NT_STATUS_IS_OK(r_u->status))
1179 return r_u->status;
1180 num_account = info->disp_info.num_group_account;
1181 break;
1182 default:
1183 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1184 return NT_STATUS_INVALID_INFO_CLASS;
1187 /* first limit the number of entries we will return */
1188 if(max_entries > max_sam_entries) {
1189 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1190 max_entries = max_sam_entries;
1193 if (enum_context > num_account) {
1194 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1195 return NT_STATUS_NO_MORE_ENTRIES;
1198 /* verify we won't overflow */
1199 if (max_entries > num_account-enum_context) {
1200 max_entries = num_account-enum_context;
1201 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1204 /* calculate the size and limit on the number of entries we will return */
1205 temp_size=max_entries*struct_size;
1207 if (temp_size>max_size) {
1208 max_entries=MIN((max_size/struct_size),max_entries);;
1209 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1212 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1213 return NT_STATUS_NO_MEMORY;
1215 ZERO_STRUCTP(ctr);
1217 /* Now create reply structure */
1218 switch (q_u->switch_level) {
1219 case 0x1:
1220 if (max_entries) {
1221 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1222 return NT_STATUS_NO_MEMORY;
1224 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1225 info->disp_info.disp_user_info, &domain_sid);
1226 if (!NT_STATUS_IS_OK(disp_ret))
1227 return disp_ret;
1228 break;
1229 case 0x2:
1230 if (max_entries) {
1231 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1232 return NT_STATUS_NO_MEMORY;
1234 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1235 info->disp_info.disp_user_info, &domain_sid);
1236 if (!NT_STATUS_IS_OK(disp_ret))
1237 return disp_ret;
1238 break;
1239 case 0x3:
1240 if (max_entries) {
1241 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1242 return NT_STATUS_NO_MEMORY;
1244 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1245 if (!NT_STATUS_IS_OK(disp_ret))
1246 return disp_ret;
1247 break;
1248 case 0x4:
1249 if (max_entries) {
1250 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1251 return NT_STATUS_NO_MEMORY;
1253 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1254 if (!NT_STATUS_IS_OK(disp_ret))
1255 return disp_ret;
1256 break;
1257 case 0x5:
1258 if (max_entries) {
1259 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1260 return NT_STATUS_NO_MEMORY;
1262 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1263 if (!NT_STATUS_IS_OK(disp_ret))
1264 return disp_ret;
1265 break;
1267 default:
1268 ctr->sam.info = NULL;
1269 return NT_STATUS_INVALID_INFO_CLASS;
1272 /* calculate the total size */
1273 total_data_size=num_account*struct_size;
1275 if (enum_context+max_entries < num_account)
1276 r_u->status = STATUS_MORE_ENTRIES;
1278 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1280 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1282 return r_u->status;
1286 /*******************************************************************
1287 samr_reply_query_aliasinfo
1288 ********************************************************************/
1290 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1292 DOM_SID sid;
1293 GROUP_MAP map;
1294 uint32 acc_granted;
1296 r_u->status = NT_STATUS_OK;
1298 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1300 /* find the policy handle. open a policy on it. */
1301 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1302 return NT_STATUS_INVALID_HANDLE;
1303 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, ALIAS_ACCESS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1304 return r_u->status;
1307 if (!sid_check_is_in_our_domain(&sid) &&
1308 !sid_check_is_in_builtin(&sid))
1309 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1311 if (!get_local_group_from_sid(sid, &map, MAPPING_WITHOUT_PRIV))
1312 return NT_STATUS_NO_SUCH_ALIAS;
1314 switch (q_u->switch_level) {
1315 case 1:
1316 r_u->ptr = 1;
1317 r_u->ctr.switch_value1 = 1;
1318 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1319 break;
1320 case 3:
1321 r_u->ptr = 1;
1322 r_u->ctr.switch_value1 = 3;
1323 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1324 break;
1325 default:
1326 return NT_STATUS_INVALID_INFO_CLASS;
1329 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1331 return r_u->status;
1334 #if 0
1335 /*******************************************************************
1336 samr_reply_lookup_ids
1337 ********************************************************************/
1339 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1341 uint32 rid[MAX_SAM_ENTRIES];
1342 int num_rids = q_u->num_sids1;
1344 r_u->status = NT_STATUS_OK;
1346 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1348 if (num_rids > MAX_SAM_ENTRIES) {
1349 num_rids = MAX_SAM_ENTRIES;
1350 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1353 #if 0
1354 int i;
1355 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1357 for (i = 0; i < num_rids && status == 0; i++)
1359 struct sam_passwd *sam_pass;
1360 fstring user_name;
1363 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1364 q_u->uni_user_name[i].uni_str_len));
1366 /* find the user account */
1367 become_root();
1368 sam_pass = get_smb21pwd_entry(user_name, 0);
1369 unbecome_root();
1371 if (sam_pass == NULL)
1373 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1374 rid[i] = 0;
1376 else
1378 rid[i] = sam_pass->user_rid;
1381 #endif
1383 num_rids = 1;
1384 rid[0] = BUILTIN_ALIAS_RID_USERS;
1386 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1388 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1390 return r_u->status;
1392 #endif
1394 /*******************************************************************
1395 _samr_lookup_names
1396 ********************************************************************/
1398 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1400 uint32 rid[MAX_SAM_ENTRIES];
1401 uint32 local_rid;
1402 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1403 enum SID_NAME_USE local_type;
1404 int i;
1405 int num_rids = q_u->num_names2;
1406 DOM_SID pol_sid;
1407 fstring sid_str;
1408 uint32 acc_granted;
1410 r_u->status = NT_STATUS_OK;
1412 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1414 ZERO_ARRAY(rid);
1415 ZERO_ARRAY(type);
1417 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1418 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1419 return r_u->status;
1422 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 */
1423 return r_u->status;
1426 if (num_rids > MAX_SAM_ENTRIES) {
1427 num_rids = MAX_SAM_ENTRIES;
1428 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1431 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1433 become_root(); /* local_lookup_name can require root privs */
1435 for (i = 0; i < num_rids; i++) {
1436 fstring name;
1437 DOM_SID sid;
1439 r_u->status = NT_STATUS_NONE_MAPPED;
1441 rid [i] = 0xffffffff;
1442 type[i] = SID_NAME_UNKNOWN;
1444 rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1447 * we are only looking for a name
1448 * the SID we get back can be outside
1449 * the scope of the pol_sid
1451 * in clear: it prevents to reply to domain\group: yes
1452 * when only builtin\group exists.
1454 * a cleaner code is to add the sid of the domain we're looking in
1455 * to the local_lookup_name function.
1457 if(local_lookup_name(name, &sid, &local_type)) {
1458 sid_split_rid(&sid, &local_rid);
1460 if (sid_equal(&sid, &pol_sid)) {
1461 rid[i]=local_rid;
1462 type[i]=local_type;
1463 r_u->status = NT_STATUS_OK;
1468 unbecome_root();
1470 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1472 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1474 return r_u->status;
1477 /*******************************************************************
1478 _samr_chgpasswd_user
1479 ********************************************************************/
1481 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1483 fstring user_name;
1484 fstring wks;
1486 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1488 r_u->status = NT_STATUS_OK;
1490 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1491 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1493 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1496 * Pass the user through the NT -> unix user mapping
1497 * function.
1500 (void)map_username(user_name);
1503 * UNIX username case mangling not required, pass_oem_change
1504 * is case insensitive.
1507 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1508 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1509 r_u->status = NT_STATUS_WRONG_PASSWORD;
1511 init_samr_r_chgpasswd_user(r_u, r_u->status);
1513 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1515 return r_u->status;
1518 /*******************************************************************
1519 makes a SAMR_R_LOOKUP_RIDS structure.
1520 ********************************************************************/
1522 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1523 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1525 uint32 i;
1526 UNIHDR *hdr_name=NULL;
1527 UNISTR2 *uni_name=NULL;
1529 *pp_uni_name = NULL;
1530 *pp_hdr_name = NULL;
1532 if (num_names != 0) {
1533 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1534 if (hdr_name == NULL)
1535 return False;
1537 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1538 if (uni_name == NULL)
1539 return False;
1542 for (i = 0; i < num_names; i++) {
1543 int len = names[i] != NULL ? strlen(names[i]) : 0;
1544 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1545 init_uni_hdr(&hdr_name[i], len);
1546 init_unistr2(&uni_name[i], names[i], len);
1549 *pp_uni_name = uni_name;
1550 *pp_hdr_name = hdr_name;
1552 return True;
1555 /*******************************************************************
1556 _samr_lookup_rids
1557 ********************************************************************/
1559 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1561 fstring group_names[MAX_SAM_ENTRIES];
1562 uint32 *group_attrs = NULL;
1563 UNIHDR *hdr_name = NULL;
1564 UNISTR2 *uni_name = NULL;
1565 DOM_SID pol_sid;
1566 int num_rids = q_u->num_rids1;
1567 int i;
1568 uint32 acc_granted;
1570 r_u->status = NT_STATUS_OK;
1572 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1574 /* find the policy handle. open a policy on it. */
1575 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1576 return NT_STATUS_INVALID_HANDLE;
1578 if (num_rids > MAX_SAM_ENTRIES) {
1579 num_rids = MAX_SAM_ENTRIES;
1580 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1583 if (num_rids) {
1584 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1585 return NT_STATUS_NO_MEMORY;
1588 r_u->status = NT_STATUS_NONE_MAPPED;
1590 become_root(); /* lookup_sid can require root privs */
1592 for (i = 0; i < num_rids; i++) {
1593 fstring tmpname;
1594 fstring domname;
1595 DOM_SID sid;
1596 enum SID_NAME_USE type;
1598 group_attrs[i] = SID_NAME_UNKNOWN;
1599 *group_names[i] = '\0';
1601 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1602 sid_copy(&sid, &pol_sid);
1603 sid_append_rid(&sid, q_u->rid[i]);
1605 if (lookup_sid(&sid, domname, tmpname, &type)) {
1606 r_u->status = NT_STATUS_OK;
1607 group_attrs[i] = (uint32)type;
1608 fstrcpy(group_names[i],tmpname);
1609 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1614 unbecome_root();
1616 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1617 return NT_STATUS_NO_MEMORY;
1619 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1621 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1623 return r_u->status;
1626 /*******************************************************************
1627 _api_samr_open_user. Safe - gives out no passwd info.
1628 ********************************************************************/
1630 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1632 SAM_ACCOUNT *sampass=NULL;
1633 DOM_SID sid;
1634 POLICY_HND domain_pol = q_u->domain_pol;
1635 POLICY_HND *user_pol = &r_u->user_pol;
1636 struct samr_info *info = NULL;
1637 SEC_DESC *psd = NULL;
1638 uint32 acc_granted;
1639 uint32 des_access = q_u->access_mask;
1640 size_t sd_size;
1641 BOOL ret;
1642 NTSTATUS nt_status;
1644 r_u->status = NT_STATUS_OK;
1646 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1647 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1648 return NT_STATUS_INVALID_HANDLE;
1650 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_open_user"))) {
1651 return nt_status;
1654 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1655 if (!NT_STATUS_IS_OK(nt_status)) {
1656 return nt_status;
1659 /* append the user's RID to it */
1660 if (!sid_append_rid(&sid, q_u->user_rid))
1661 return NT_STATUS_NO_SUCH_USER;
1663 /* check if access can be granted as requested by client. */
1664 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1665 se_map_generic(&des_access, &usr_generic_mapping);
1666 if (!NT_STATUS_IS_OK(nt_status =
1667 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1668 des_access, &acc_granted, "_samr_open_user"))) {
1669 return nt_status;
1672 become_root();
1673 ret=pdb_getsampwsid(sampass, &sid);
1674 unbecome_root();
1676 /* check that the SID exists in our domain. */
1677 if (ret == False) {
1678 return NT_STATUS_NO_SUCH_USER;
1681 pdb_free_sam(&sampass);
1683 /* associate the user's SID and access bits with the new handle. */
1684 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1685 return NT_STATUS_NO_MEMORY;
1686 info->acc_granted = acc_granted;
1688 /* get a (unique) handle. open a policy on it. */
1689 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1690 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1692 return r_u->status;
1695 /*************************************************************************
1696 get_user_info_10. Safe. Only gives out acb bits.
1697 *************************************************************************/
1699 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1701 SAM_ACCOUNT *smbpass=NULL;
1702 BOOL ret;
1703 NTSTATUS nt_status;
1705 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1707 if (!NT_STATUS_IS_OK(nt_status)) {
1708 return nt_status;
1711 become_root();
1712 ret = pdb_getsampwsid(smbpass, user_sid);
1713 unbecome_root();
1715 if (ret==False) {
1716 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1717 return NT_STATUS_NO_SUCH_USER;
1720 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1722 ZERO_STRUCTP(id10);
1723 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1725 pdb_free_sam(&smbpass);
1727 return NT_STATUS_OK;
1730 /*************************************************************************
1731 get_user_info_12. OK - this is the killer as it gives out password info.
1732 Ensure that this is only allowed on an encrypted connection with a root
1733 user. JRA.
1734 *************************************************************************/
1736 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1738 SAM_ACCOUNT *smbpass=NULL;
1739 BOOL ret;
1740 NTSTATUS nt_status;
1742 if (!p->ntlmssp_auth_validated)
1743 return NT_STATUS_ACCESS_DENIED;
1745 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1746 return NT_STATUS_ACCESS_DENIED;
1749 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1752 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1754 if (!NT_STATUS_IS_OK(nt_status)) {
1755 return nt_status;
1758 ret = pdb_getsampwsid(smbpass, user_sid);
1760 if (ret == False) {
1761 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1762 pdb_free_sam(&smbpass);
1763 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1766 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1768 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1769 pdb_free_sam(&smbpass);
1770 return NT_STATUS_ACCOUNT_DISABLED;
1773 ZERO_STRUCTP(id12);
1774 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1776 pdb_free_sam(&smbpass);
1778 return NT_STATUS_OK;
1781 /*************************************************************************
1782 get_user_info_20
1783 *************************************************************************/
1785 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1787 SAM_ACCOUNT *sampass=NULL;
1788 BOOL ret;
1790 pdb_init_sam_talloc(mem_ctx, &sampass);
1792 become_root();
1793 ret = pdb_getsampwsid(sampass, user_sid);
1794 unbecome_root();
1796 if (ret == False) {
1797 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1798 return NT_STATUS_NO_SUCH_USER;
1801 samr_clear_sam_passwd(sampass);
1803 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1805 ZERO_STRUCTP(id20);
1806 init_sam_user_info20A(id20, sampass);
1808 pdb_free_sam(&sampass);
1810 return NT_STATUS_OK;
1813 /*************************************************************************
1814 get_user_info_21
1815 *************************************************************************/
1817 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1818 DOM_SID *user_sid, DOM_SID *domain_sid)
1820 SAM_ACCOUNT *sampass=NULL;
1821 BOOL ret;
1822 NTSTATUS nt_status;
1824 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1825 if (!NT_STATUS_IS_OK(nt_status)) {
1826 return nt_status;
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(id21);
1843 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1845 pdb_free_sam(&sampass);
1847 return NT_STATUS_OK;
1850 /*******************************************************************
1851 _samr_query_userinfo
1852 ********************************************************************/
1854 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1856 SAM_USERINFO_CTR *ctr;
1857 struct samr_info *info = NULL;
1858 DOM_SID domain_sid;
1859 uint32 rid;
1861 r_u->status=NT_STATUS_OK;
1863 /* search for the handle */
1864 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1865 return NT_STATUS_INVALID_HANDLE;
1867 domain_sid = info->sid;
1869 sid_split_rid(&domain_sid, &rid);
1871 if (!sid_check_is_in_our_domain(&info->sid))
1872 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1874 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1876 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1877 if (!ctr)
1878 return NT_STATUS_NO_MEMORY;
1880 ZERO_STRUCTP(ctr);
1882 /* ok! user info levels (lots: see MSDEV help), off we go... */
1883 ctr->switch_value = q_u->switch_value;
1885 switch (q_u->switch_value) {
1886 case 0x10:
1887 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1888 if (ctr->info.id10 == NULL)
1889 return NT_STATUS_NO_MEMORY;
1891 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1892 return r_u->status;
1893 break;
1895 #if 0
1896 /* whoops - got this wrong. i think. or don't understand what's happening. */
1897 case 0x11:
1899 NTTIME expire;
1900 info = (void *)&id11;
1902 expire.low = 0xffffffff;
1903 expire.high = 0x7fffffff;
1905 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1906 sizeof
1907 (*ctr->
1908 info.
1909 id11));
1910 ZERO_STRUCTP(ctr->info.id11);
1911 init_sam_user_info11(ctr->info.id11, &expire,
1912 "BROOKFIELDS$", /* name */
1913 0x03ef, /* user rid */
1914 0x201, /* group rid */
1915 0x0080); /* acb info */
1917 break;
1919 #endif
1921 case 0x12:
1922 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1923 if (ctr->info.id12 == NULL)
1924 return NT_STATUS_NO_MEMORY;
1926 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1927 return r_u->status;
1928 break;
1930 case 20:
1931 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1932 if (ctr->info.id20 == NULL)
1933 return NT_STATUS_NO_MEMORY;
1934 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1935 return r_u->status;
1936 break;
1938 case 21:
1939 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1940 if (ctr->info.id21 == NULL)
1941 return NT_STATUS_NO_MEMORY;
1942 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1943 &info->sid, &domain_sid)))
1944 return r_u->status;
1945 break;
1947 default:
1948 return NT_STATUS_INVALID_INFO_CLASS;
1951 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1953 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1955 return r_u->status;
1958 /*******************************************************************
1959 samr_reply_query_usergroups
1960 ********************************************************************/
1962 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1964 SAM_ACCOUNT *sam_pass=NULL;
1965 DOM_SID sid;
1966 DOM_GID *gids = NULL;
1967 int num_groups = 0;
1968 uint32 acc_granted;
1969 BOOL ret;
1972 * from the SID in the request:
1973 * we should send back the list of DOMAIN GROUPS
1974 * the user is a member of
1976 * and only the DOMAIN GROUPS
1977 * no ALIASES !!! neither aliases of the domain
1978 * nor aliases of the builtin SID
1980 * JFM, 12/2/2001
1983 r_u->status = NT_STATUS_OK;
1985 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1987 /* find the policy handle. open a policy on it. */
1988 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1989 return NT_STATUS_INVALID_HANDLE;
1991 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, USER_ACCESS_GET_GROUPS, "_samr_query_usergroups"))) {
1992 return r_u->status;
1995 if (!sid_check_is_in_our_domain(&sid))
1996 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1998 pdb_init_sam(&sam_pass);
2000 become_root();
2001 ret = pdb_getsampwsid(sam_pass, &sid);
2002 unbecome_root();
2004 if (ret == False) {
2005 pdb_free_sam(&sam_pass);
2006 return NT_STATUS_NO_SUCH_USER;
2009 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2010 pdb_free_sam(&sam_pass);
2011 return NT_STATUS_NO_SUCH_GROUP;
2014 /* construct the response. lkclXXXX: gids are not copied! */
2015 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2017 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2019 pdb_free_sam(&sam_pass);
2021 return r_u->status;
2024 /*******************************************************************
2025 _samr_query_dom_info
2026 ********************************************************************/
2028 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2030 struct samr_info *info = NULL;
2031 SAM_UNK_CTR *ctr;
2032 uint32 min_pass_len,pass_hist,flag;
2033 time_t u_expire, u_min_age;
2034 NTTIME nt_expire, nt_min_age;
2036 time_t u_lock_duration, u_reset_time;
2037 NTTIME nt_lock_duration, nt_reset_time;
2038 uint32 lockout;
2040 time_t u_logout;
2041 NTTIME nt_logout;
2043 uint32 account_policy_temp;
2045 uint32 num_users=0, num_groups=0, num_aliases=0;
2047 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2048 return NT_STATUS_NO_MEMORY;
2050 ZERO_STRUCTP(ctr);
2052 r_u->status = NT_STATUS_OK;
2054 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2056 /* find the policy handle. open a policy on it. */
2057 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2058 return NT_STATUS_INVALID_HANDLE;
2060 switch (q_u->switch_value) {
2061 case 0x01:
2063 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2064 min_pass_len = account_policy_temp;
2066 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2067 pass_hist = account_policy_temp;
2069 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2070 flag = account_policy_temp;
2072 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2073 u_expire = account_policy_temp;
2075 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2076 u_min_age = account_policy_temp;
2078 unix_to_nt_time_abs(&nt_expire, u_expire);
2079 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2081 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2082 flag, nt_expire, nt_min_age);
2083 break;
2084 case 0x02:
2085 become_root();
2086 r_u->status=load_sampwd_entries(info, ACB_NORMAL);
2087 unbecome_root();
2088 if (!NT_STATUS_IS_OK(r_u->status)) {
2089 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2090 return r_u->status;
2092 num_users=info->disp_info.num_user_account;
2093 free_samr_db(info);
2095 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2096 if (!NT_STATUS_IS_OK(r_u->status)) {
2097 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2098 return r_u->status;
2100 num_groups=info->disp_info.num_group_account;
2101 free_samr_db(info);
2103 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2104 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL),
2105 num_users, num_groups, num_aliases);
2106 break;
2107 case 0x03:
2108 account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
2109 unix_to_nt_time_abs(&nt_logout, u_logout);
2111 init_unk_info3(&ctr->info.inf3, nt_logout);
2112 break;
2113 case 0x05:
2114 init_unk_info5(&ctr->info.inf5, global_myname);
2115 break;
2116 case 0x06:
2117 init_unk_info6(&ctr->info.inf6);
2118 break;
2119 case 0x07:
2120 init_unk_info7(&ctr->info.inf7);
2121 break;
2122 case 0x0c:
2123 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2124 u_lock_duration = account_policy_temp;
2126 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2127 u_reset_time = account_policy_temp;
2129 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2130 lockout = account_policy_temp;
2132 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2133 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2135 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2136 break;
2137 default:
2138 return NT_STATUS_INVALID_INFO_CLASS;
2141 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2143 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2145 return r_u->status;
2148 /*******************************************************************
2149 _api_samr_create_user
2150 Create an account, can be either a normal user or a machine.
2151 This funcion will need to be updated for bdc/domain trusts.
2152 ********************************************************************/
2154 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2156 SAM_ACCOUNT *sam_pass=NULL;
2157 fstring account;
2158 DOM_SID sid;
2159 pstring add_script;
2160 POLICY_HND dom_pol = q_u->domain_pol;
2161 UNISTR2 user_account = q_u->uni_name;
2162 uint16 acb_info = q_u->acb_info;
2163 POLICY_HND *user_pol = &r_u->user_pol;
2164 struct samr_info *info = NULL;
2165 BOOL ret;
2166 NTSTATUS nt_status;
2167 struct passwd *pw;
2168 uint32 acc_granted;
2169 SEC_DESC *psd;
2170 size_t sd_size;
2171 uint32 des_access;
2173 /* Get the domain SID stored in the domain policy */
2174 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2175 return NT_STATUS_INVALID_HANDLE;
2177 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_CREATE_USER, "_samr_create_user"))) {
2178 return nt_status;
2181 /* find the account: tell the caller if it exists.
2182 lkclXXXX i have *no* idea if this is a problem or not
2183 or even if you are supposed to construct a different
2184 reply if the account already exists...
2187 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2188 strlower(account);
2190 pdb_init_sam(&sam_pass);
2192 become_root();
2193 ret = pdb_getsampwnam(sam_pass, account);
2194 unbecome_root();
2195 if (ret == True) {
2196 /* this account exists: say so */
2197 pdb_free_sam(&sam_pass);
2198 return NT_STATUS_USER_EXISTS;
2201 pdb_free_sam(&sam_pass);
2204 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2205 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2206 * that only people with write access to the smbpasswd file will be able
2207 * to create a user. JRA.
2211 * add the user in the /etc/passwd file or the unix authority system.
2212 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2213 * a) local_password_change() checks for us if the /etc/passwd account really exists
2214 * b) smb_create_user() would return an error if the account already exists
2215 * and as it could return an error also if it can't create the account, it would be tricky.
2217 * So we go the easy way, only check after if the account exists.
2218 * JFM (2/3/2001), to clear any possible bad understanding (-:
2220 * We now have seperate script paramaters for adding users/machines so we
2221 * now have some sainity-checking to match.
2224 DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2225 #if 0
2226 if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2227 pstrcpy(add_script, lp_addmachine_script());
2228 } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2229 pstrcpy(add_script, lp_adduser_script());
2230 } else {
2231 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2232 pdb_free_sam(&sam_pass);
2233 return NT_STATUS_UNSUCCESSFUL;
2235 #endif
2238 * we can't check both the ending $ and the acb_info.
2240 * UserManager creates trust accounts (ending in $,
2241 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2242 * JFM, 11/29/2001
2244 if (account[strlen(account)-1] == '$')
2245 pstrcpy(add_script, lp_addmachine_script());
2246 else
2247 pstrcpy(add_script, lp_adduser_script());
2249 if (*add_script) {
2250 int add_ret;
2251 all_string_sub(add_script, "%u", account, sizeof(account));
2252 add_ret = smbrun(add_script,NULL);
2253 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2256 pw = getpwnam_alloc(account);
2258 if (pw) {
2259 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sam_pass, pw))) {
2260 passwd_free(&pw);
2261 return nt_status;
2263 passwd_free(&pw); /* done with this now */
2264 } else {
2265 DEBUG(3,("attempting to create non-unix account %s\n", account));
2267 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sam_pass))) {
2268 return nt_status;
2271 if (!pdb_set_username(sam_pass, account)) {
2272 pdb_free_sam(&sam_pass);
2273 return NT_STATUS_NO_MEMORY;
2277 pdb_set_acct_ctrl(sam_pass, acb_info);
2279 if (!pdb_add_sam_account(sam_pass)) {
2280 pdb_free_sam(&sam_pass);
2281 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2282 account));
2283 return NT_STATUS_ACCESS_DENIED;
2286 pdb_reset_sam(sam_pass);
2288 if (!pdb_getsampwnam(sam_pass, account)) {
2289 pdb_free_sam(&sam_pass);
2290 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n",
2291 account));
2292 return NT_STATUS_ACCESS_DENIED;
2295 /* Get the user's SID */
2296 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2298 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2299 se_map_generic(&des_access, &usr_generic_mapping);
2300 if (!NT_STATUS_IS_OK(nt_status =
2301 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2302 des_access, &acc_granted, "_samr_create_user"))) {
2303 return nt_status;
2306 /* associate the user's SID with the new handle. */
2307 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2308 pdb_free_sam(&sam_pass);
2309 return NT_STATUS_NO_MEMORY;
2312 ZERO_STRUCTP(info);
2313 info->sid = sid;
2314 info->acc_granted = acc_granted;
2316 /* get a (unique) handle. open a policy on it. */
2317 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2318 pdb_free_sam(&sam_pass);
2319 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2322 r_u->user_rid=pdb_get_user_rid(sam_pass);
2324 r_u->access_granted = acc_granted;
2326 pdb_free_sam(&sam_pass);
2328 return NT_STATUS_OK;
2331 /*******************************************************************
2332 samr_reply_connect_anon
2333 ********************************************************************/
2335 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2337 struct samr_info *info = NULL;
2339 /* Access check */
2341 if (!pipe_access_check(p)) {
2342 DEBUG(3, ("access denied to samr_connect_anon\n"));
2343 r_u->status = NT_STATUS_ACCESS_DENIED;
2344 return r_u->status;
2347 /* set up the SAMR connect_anon response */
2349 r_u->status = NT_STATUS_OK;
2351 /* associate the user's SID with the new handle. */
2352 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2353 return NT_STATUS_NO_MEMORY;
2355 info->status = q_u->unknown_0;
2357 /* get a (unique) handle. open a policy on it. */
2358 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2359 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2361 return r_u->status;
2364 /*******************************************************************
2365 samr_reply_connect
2366 ********************************************************************/
2368 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2370 struct samr_info *info = NULL;
2371 SEC_DESC *psd = NULL;
2372 uint32 acc_granted;
2373 uint32 des_access = q_u->access_mask;
2374 size_t sd_size;
2375 NTSTATUS nt_status;
2378 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2380 /* Access check */
2382 if (!pipe_access_check(p)) {
2383 DEBUG(3, ("access denied to samr_connect\n"));
2384 r_u->status = NT_STATUS_ACCESS_DENIED;
2385 return r_u->status;
2388 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2389 se_map_generic(&des_access, &sam_generic_mapping);
2390 if (!NT_STATUS_IS_OK(nt_status =
2391 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2392 des_access, &acc_granted, "_samr_connect"))) {
2393 return nt_status;
2396 r_u->status = NT_STATUS_OK;
2398 /* associate the user's SID and access granted with the new handle. */
2399 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2400 return NT_STATUS_NO_MEMORY;
2402 info->acc_granted = acc_granted;
2403 info->status = q_u->access_mask;
2405 /* get a (unique) handle. open a policy on it. */
2406 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2407 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2409 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2411 return r_u->status;
2414 /*******************************************************************
2415 samr_connect4
2416 ********************************************************************/
2418 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2420 struct samr_info *info = NULL;
2421 SEC_DESC *psd = NULL;
2422 uint32 acc_granted;
2423 uint32 des_access = q_u->access_mask;
2424 size_t sd_size;
2425 NTSTATUS nt_status;
2428 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2430 /* Access check */
2432 if (!pipe_access_check(p)) {
2433 DEBUG(3, ("access denied to samr_connect4\n"));
2434 r_u->status = NT_STATUS_ACCESS_DENIED;
2435 return r_u->status;
2438 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2439 se_map_generic(&des_access, &sam_generic_mapping);
2440 if (!NT_STATUS_IS_OK(nt_status =
2441 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2442 des_access, &acc_granted, "_samr_connect"))) {
2443 return nt_status;
2446 r_u->status = NT_STATUS_OK;
2448 /* associate the user's SID and access granted with the new handle. */
2449 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2450 return NT_STATUS_NO_MEMORY;
2452 info->acc_granted = acc_granted;
2453 info->status = q_u->access_mask;
2455 /* get a (unique) handle. open a policy on it. */
2456 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2457 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2459 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2461 return r_u->status;
2464 /**********************************************************************
2465 api_samr_lookup_domain
2466 **********************************************************************/
2468 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2470 struct samr_info *info;
2471 fstring domain_name;
2472 DOM_SID sid;
2474 r_u->status = NT_STATUS_OK;
2476 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2477 return NT_STATUS_INVALID_HANDLE;
2479 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SAMR_ACCESS_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2480 return r_u->status;
2483 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2485 ZERO_STRUCT(sid);
2487 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2488 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2491 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2493 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2495 return r_u->status;
2498 /******************************************************************
2499 makes a SAMR_R_ENUM_DOMAINS structure.
2500 ********************************************************************/
2502 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2503 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2505 uint32 i;
2506 SAM_ENTRY *sam;
2507 UNISTR2 *uni_name;
2509 DEBUG(5, ("make_enum_domains\n"));
2511 *pp_sam = NULL;
2512 *pp_uni_name = NULL;
2514 if (num_sam_entries == 0)
2515 return True;
2517 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2518 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2520 if (sam == NULL || uni_name == NULL)
2521 return False;
2523 for (i = 0; i < num_sam_entries; i++) {
2524 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2526 init_sam_entry(&sam[i], len, 0);
2527 init_unistr2(&uni_name[i], doms[i], len);
2530 *pp_sam = sam;
2531 *pp_uni_name = uni_name;
2533 return True;
2536 /**********************************************************************
2537 api_samr_enum_domains
2538 **********************************************************************/
2540 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2542 struct samr_info *info;
2543 uint32 num_entries = 2;
2544 fstring dom[2];
2545 char *name;
2547 r_u->status = NT_STATUS_OK;
2549 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2550 return NT_STATUS_INVALID_HANDLE;
2552 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SAMR_ACCESS_ENUM_DOMAINS, "_samr_enum_domains"))) {
2553 return r_u->status;
2556 switch (lp_server_role()) {
2557 case ROLE_DOMAIN_PDC:
2558 case ROLE_DOMAIN_BDC:
2559 name = global_myworkgroup;
2560 break;
2561 default:
2562 name = global_myname;
2565 fstrcpy(dom[0],name);
2566 strupper(dom[0]);
2567 fstrcpy(dom[1],"Builtin");
2569 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2570 return NT_STATUS_NO_MEMORY;
2572 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2574 return r_u->status;
2577 /*******************************************************************
2578 api_samr_open_alias
2579 ********************************************************************/
2581 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2583 DOM_SID sid;
2584 POLICY_HND domain_pol = q_u->dom_pol;
2585 uint32 alias_rid = q_u->rid_alias;
2586 POLICY_HND *alias_pol = &r_u->pol;
2587 struct samr_info *info = NULL;
2588 SEC_DESC *psd = NULL;
2589 uint32 acc_granted;
2590 uint32 des_access = q_u->access_mask;
2591 size_t sd_size;
2592 NTSTATUS status;
2594 r_u->status = NT_STATUS_OK;
2596 /* find the domain policy and get the SID / access bits stored in the domain policy */
2597 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2598 return NT_STATUS_INVALID_HANDLE;
2600 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_open_alias"))) {
2601 return status;
2604 /* append the alias' RID to it */
2605 if (!sid_append_rid(&sid, alias_rid))
2606 return NT_STATUS_NO_SUCH_USER;
2608 /*check if access can be granted as requested by client. */
2609 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2610 se_map_generic(&des_access,&ali_generic_mapping);
2611 if (!NT_STATUS_IS_OK(status =
2612 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2613 des_access, &acc_granted, "_samr_open_alias"))) {
2614 return status;
2618 * we should check if the rid really exist !!!
2619 * JFM.
2622 /* associate the user's SID with the new handle. */
2623 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2624 return NT_STATUS_NO_MEMORY;
2626 info->acc_granted = acc_granted;
2628 /* get a (unique) handle. open a policy on it. */
2629 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2630 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2632 return r_u->status;
2635 /*******************************************************************
2636 set_user_info_10
2637 ********************************************************************/
2639 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2641 SAM_ACCOUNT *pwd =NULL;
2642 BOOL ret;
2644 pdb_init_sam(&pwd);
2646 ret = pdb_getsampwsid(pwd, sid);
2648 if(ret==False) {
2649 pdb_free_sam(&pwd);
2650 return False;
2653 if (id10 == NULL) {
2654 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2655 pdb_free_sam(&pwd);
2656 return False;
2659 if (!pdb_set_acct_ctrl(pwd, id10->acb_info)) {
2660 pdb_free_sam(&pwd);
2661 return False;
2664 if(!pdb_update_sam_account(pwd)) {
2665 pdb_free_sam(&pwd);
2666 return False;
2669 pdb_free_sam(&pwd);
2671 return True;
2674 /*******************************************************************
2675 set_user_info_12
2676 ********************************************************************/
2678 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2680 SAM_ACCOUNT *pwd = NULL;
2682 pdb_init_sam(&pwd);
2684 if(!pdb_getsampwsid(pwd, sid)) {
2685 pdb_free_sam(&pwd);
2686 return False;
2689 if (id12 == NULL) {
2690 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2691 pdb_free_sam(&pwd);
2692 return False;
2695 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd)) {
2696 pdb_free_sam(&pwd);
2697 return False;
2699 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd)) {
2700 pdb_free_sam(&pwd);
2701 return False;
2703 if (!pdb_set_pass_changed_now (pwd)) {
2704 pdb_free_sam(&pwd);
2705 return False;
2708 if(!pdb_update_sam_account(pwd)) {
2709 pdb_free_sam(&pwd);
2710 return False;
2713 pdb_free_sam(&pwd);
2714 return True;
2717 /*******************************************************************
2718 set_user_info_21
2719 ********************************************************************/
2721 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2723 SAM_ACCOUNT *pwd = NULL;
2725 if (id21 == NULL) {
2726 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2727 return False;
2730 pdb_init_sam(&pwd);
2732 if (!pdb_getsampwsid(pwd, sid)) {
2733 pdb_free_sam(&pwd);
2734 return False;
2737 copy_id21_to_sam_passwd(pwd, id21);
2740 * The funny part about the previous two calls is
2741 * that pwd still has the password hashes from the
2742 * passdb entry. These have not been updated from
2743 * id21. I don't know if they need to be set. --jerry
2746 /* write the change out */
2747 if(!pdb_update_sam_account(pwd)) {
2748 pdb_free_sam(&pwd);
2749 return False;
2752 pdb_free_sam(&pwd);
2754 return True;
2757 /*******************************************************************
2758 set_user_info_23
2759 ********************************************************************/
2761 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2763 SAM_ACCOUNT *pwd = NULL;
2764 pstring plaintext_buf;
2765 uint32 len;
2766 uint16 acct_ctrl;
2768 if (id23 == NULL) {
2769 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2770 return False;
2773 pdb_init_sam(&pwd);
2775 if (!pdb_getsampwsid(pwd, sid)) {
2776 pdb_free_sam(&pwd);
2777 return False;
2780 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2781 pdb_get_username(pwd)));
2783 acct_ctrl = pdb_get_acct_ctrl(pwd);
2785 copy_id23_to_sam_passwd(pwd, id23);
2787 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2788 pdb_free_sam(&pwd);
2789 return False;
2792 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2793 pdb_free_sam(&pwd);
2794 return False;
2797 /* if it's a trust account, don't update /etc/passwd */
2798 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2799 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2800 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2801 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2802 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2803 } else {
2804 /* update the UNIX password */
2805 if (lp_unix_password_sync() )
2806 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2807 pdb_free_sam(&pwd);
2808 return False;
2812 ZERO_STRUCT(plaintext_buf);
2814 if(!pdb_update_sam_account(pwd)) {
2815 pdb_free_sam(&pwd);
2816 return False;
2819 pdb_free_sam(&pwd);
2821 return True;
2824 /*******************************************************************
2825 set_user_info_pw
2826 ********************************************************************/
2828 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2830 SAM_ACCOUNT *pwd = NULL;
2831 uint32 len;
2832 pstring plaintext_buf;
2833 uint16 acct_ctrl;
2835 pdb_init_sam(&pwd);
2837 if (!pdb_getsampwsid(pwd, sid)) {
2838 pdb_free_sam(&pwd);
2839 return False;
2842 DEBUG(5, ("Attempting administrator password change for user %s\n",
2843 pdb_get_username(pwd)));
2845 acct_ctrl = pdb_get_acct_ctrl(pwd);
2847 ZERO_STRUCT(plaintext_buf);
2849 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2850 pdb_free_sam(&pwd);
2851 return False;
2854 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2855 pdb_free_sam(&pwd);
2856 return False;
2859 /* if it's a trust account, don't update /etc/passwd */
2860 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2861 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2862 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2863 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2864 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2865 } else {
2866 /* update the UNIX password */
2867 if (lp_unix_password_sync()) {
2868 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2869 pdb_free_sam(&pwd);
2870 return False;
2875 ZERO_STRUCT(plaintext_buf);
2877 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2879 /* update the SAMBA password */
2880 if(!pdb_update_sam_account(pwd)) {
2881 pdb_free_sam(&pwd);
2882 return False;
2885 pdb_free_sam(&pwd);
2887 return True;
2890 /*******************************************************************
2891 samr_reply_set_userinfo
2892 ********************************************************************/
2894 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2896 DOM_SID sid;
2897 POLICY_HND *pol = &q_u->pol;
2898 uint16 switch_value = q_u->switch_value;
2899 SAM_USERINFO_CTR *ctr = q_u->ctr;
2900 uint32 acc_granted;
2901 uint32 acc_required;
2903 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2905 r_u->status = NT_STATUS_OK;
2907 /* find the policy handle. open a policy on it. */
2908 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2909 return NT_STATUS_INVALID_HANDLE;
2911 acc_required = USER_ACCESS_SET_LOC_COM | USER_ACCESS_SET_ATTRIBUTES; /* This is probably wrong */
2912 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2913 return r_u->status;
2916 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2918 if (ctr == NULL) {
2919 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2920 return NT_STATUS_INVALID_INFO_CLASS;
2923 /* ok! user info levels (lots: see MSDEV help), off we go... */
2924 switch (switch_value) {
2925 case 0x12:
2926 if (!set_user_info_12(ctr->info.id12, &sid))
2927 return NT_STATUS_ACCESS_DENIED;
2928 break;
2930 case 24:
2931 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2933 dump_data(100, (char *)ctr->info.id24->pass, 516);
2935 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2936 return NT_STATUS_ACCESS_DENIED;
2937 break;
2939 case 25:
2940 #if 0
2942 * Currently we don't really know how to unmarshall
2943 * the level 25 struct, and the password encryption
2944 * is different. This is a placeholder for when we
2945 * do understand it. In the meantime just return INVALID
2946 * info level and W2K SP2 drops down to level 23... JRA.
2949 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
2951 dump_data(100, (char *)ctr->info.id25->pass, 532);
2953 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
2954 return NT_STATUS_ACCESS_DENIED;
2955 break;
2956 #endif
2957 return NT_STATUS_INVALID_INFO_CLASS;
2959 case 23:
2960 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
2962 dump_data(100, (char *)ctr->info.id23->pass, 516);
2964 if (!set_user_info_23(ctr->info.id23, &sid))
2965 return NT_STATUS_ACCESS_DENIED;
2966 break;
2968 default:
2969 return NT_STATUS_INVALID_INFO_CLASS;
2972 return r_u->status;
2975 /*******************************************************************
2976 samr_reply_set_userinfo2
2977 ********************************************************************/
2979 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2981 DOM_SID sid;
2982 SAM_USERINFO_CTR *ctr = q_u->ctr;
2983 POLICY_HND *pol = &q_u->pol;
2984 uint16 switch_value = q_u->switch_value;
2985 uint32 acc_granted;
2986 uint32 acc_required;
2988 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2990 r_u->status = NT_STATUS_OK;
2992 /* find the policy handle. open a policy on it. */
2993 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2994 return NT_STATUS_INVALID_HANDLE;
2996 acc_required = USER_ACCESS_SET_LOC_COM | USER_ACCESS_SET_ATTRIBUTES; /* This is probably wrong */
2997 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
2998 return r_u->status;
3001 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3003 if (ctr == NULL) {
3004 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3005 return NT_STATUS_INVALID_INFO_CLASS;
3008 switch_value=ctr->switch_value;
3010 /* ok! user info levels (lots: see MSDEV help), off we go... */
3011 switch (switch_value) {
3012 case 21:
3013 if (!set_user_info_21(ctr->info.id21, &sid))
3014 return NT_STATUS_ACCESS_DENIED;
3015 break;
3016 case 16:
3017 if (!set_user_info_10(ctr->info.id10, &sid))
3018 return NT_STATUS_ACCESS_DENIED;
3019 break;
3020 case 18:
3021 /* Used by AS/U JRA. */
3022 if (!set_user_info_12(ctr->info.id12, &sid))
3023 return NT_STATUS_ACCESS_DENIED;
3024 break;
3025 default:
3026 return NT_STATUS_INVALID_INFO_CLASS;
3029 return r_u->status;
3032 /*********************************************************************
3033 _samr_query_aliasmem
3034 *********************************************************************/
3036 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3038 int num_groups = 0, tmp_num_groups=0;
3039 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3040 struct samr_info *info = NULL;
3041 int i,j;
3042 /* until i see a real useraliases query, we fack one up */
3044 /* I have seen one, JFM 2/12/2001 */
3046 * Explanation of what this call does:
3047 * for all the SID given in the request:
3048 * return a list of alias (local groups)
3049 * that have those SID as members.
3051 * and that's the alias in the domain specified
3052 * in the policy_handle
3054 * if the policy handle is on an incorrect sid
3055 * for example a user's sid
3056 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3059 r_u->status = NT_STATUS_OK;
3061 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3063 /* find the policy handle. open a policy on it. */
3064 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3065 return NT_STATUS_INVALID_HANDLE;
3067 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, USER_ACCESS_GET_GROUPS, "_samr_query_useraliases"))) {
3068 return r_u->status;
3071 if (!sid_check_is_domain(&info->sid) &&
3072 !sid_check_is_builtin(&info->sid))
3073 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3076 for (i=0; i<q_u->num_sids1; i++) {
3078 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3081 * if there is an error, we just continue as
3082 * it can be an unfound user or group
3084 if (!NT_STATUS_IS_OK(r_u->status)) {
3085 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3086 continue;
3089 if (tmp_num_groups==0) {
3090 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3091 continue;
3094 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3095 if (new_rids==NULL) {
3096 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3097 return NT_STATUS_NO_MEMORY;
3099 rids=new_rids;
3101 for (j=0; j<tmp_num_groups; j++)
3102 rids[j+num_groups]=tmp_rids[j];
3104 safe_free(tmp_rids);
3106 num_groups+=tmp_num_groups;
3109 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3110 return NT_STATUS_OK;
3113 /*********************************************************************
3114 _samr_query_aliasmem
3115 *********************************************************************/
3117 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3119 int i;
3121 GROUP_MAP map;
3122 int num_uids = 0;
3123 DOM_SID2 *sid;
3124 uid_t *uid=NULL;
3126 DOM_SID alias_sid;
3127 DOM_SID als_sid;
3128 uint32 alias_rid;
3129 fstring alias_sid_str;
3130 DOM_SID temp_sid;
3132 SAM_ACCOUNT *sam_user = NULL;
3133 BOOL check;
3134 uint32 acc_granted;
3136 /* find the policy handle. open a policy on it. */
3137 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3138 return NT_STATUS_INVALID_HANDLE;
3140 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, ALIAS_ACCESS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3141 return r_u->status;
3144 sid_copy(&als_sid, &alias_sid);
3145 sid_to_string(alias_sid_str, &alias_sid);
3146 sid_split_rid(&alias_sid, &alias_rid);
3148 DEBUG(10, ("sid is %s\n", alias_sid_str));
3150 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3151 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3152 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3153 return NT_STATUS_NO_SUCH_ALIAS;
3154 } else {
3155 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3156 DEBUG(10, ("lookup on Server SID\n"));
3157 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3158 return NT_STATUS_NO_SUCH_ALIAS;
3162 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3163 return NT_STATUS_NO_SUCH_ALIAS;
3165 DEBUG(10, ("sid is %s\n", alias_sid_str));
3166 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3167 if (num_uids!=0 && sid == NULL)
3168 return NT_STATUS_NO_MEMORY;
3170 for (i = 0; i < num_uids; i++) {
3171 struct passwd *pass;
3172 uint32 rid;
3174 sid_copy(&temp_sid, get_global_sam_sid());
3176 pass = getpwuid_alloc(uid[i]);
3177 if (!pass) continue;
3179 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3180 passwd_free(&pass);
3181 continue;
3184 become_root();
3185 check = pdb_getsampwnam(sam_user, pass->pw_name);
3186 unbecome_root();
3188 if (check != True) {
3189 pdb_free_sam(&sam_user);
3190 passwd_free(&pass);
3191 continue;
3194 rid = pdb_get_user_rid(sam_user);
3195 if (rid == 0) {
3196 pdb_free_sam(&sam_user);
3197 passwd_free(&pass);
3198 continue;
3201 pdb_free_sam(&sam_user);
3202 passwd_free(&pass);
3204 sid_append_rid(&temp_sid, rid);
3206 init_dom_sid2(&sid[i], &temp_sid);
3209 DEBUG(10, ("sid is %s\n", alias_sid_str));
3210 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3212 return NT_STATUS_OK;
3215 /*********************************************************************
3216 _samr_query_groupmem
3217 *********************************************************************/
3219 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3221 int num_uids = 0;
3222 int i;
3223 DOM_SID group_sid;
3224 uint32 group_rid;
3225 fstring group_sid_str;
3226 uid_t *uid=NULL;
3228 GROUP_MAP map;
3230 uint32 *rid=NULL;
3231 uint32 *attr=NULL;
3233 SAM_ACCOUNT *sam_user = NULL;
3234 BOOL check;
3235 uint32 acc_granted;
3237 /* find the policy handle. open a policy on it. */
3238 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3239 return NT_STATUS_INVALID_HANDLE;
3241 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, GROUP_ACCESS_GET_MEMBERS, "_samr_query_groupmem"))) {
3242 return r_u->status;
3245 /* todo: change to use sid_compare_front */
3247 sid_split_rid(&group_sid, &group_rid);
3248 sid_to_string(group_sid_str, &group_sid);
3249 DEBUG(10, ("sid is %s\n", group_sid_str));
3251 /* can we get a query for an SID outside our domain ? */
3252 if (!sid_equal(&group_sid, get_global_sam_sid()))
3253 return NT_STATUS_NO_SUCH_GROUP;
3255 sid_append_rid(&group_sid, group_rid);
3256 DEBUG(10, ("lookup on Domain SID\n"));
3258 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3259 return NT_STATUS_NO_SUCH_GROUP;
3261 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3262 return NT_STATUS_NO_SUCH_GROUP;
3264 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3265 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3267 if (num_uids!=0 && (rid==NULL || attr==NULL))
3268 return NT_STATUS_NO_MEMORY;
3270 for (i=0; i<num_uids; i++) {
3271 struct passwd *pass;
3272 uint32 urid;
3274 pass = getpwuid_alloc(uid[i]);
3275 if (!pass) continue;
3277 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3278 passwd_free(&pass);
3279 continue;
3282 become_root();
3283 check = pdb_getsampwnam(sam_user, pass->pw_name);
3284 unbecome_root();
3286 if (check != True) {
3287 pdb_free_sam(&sam_user);
3288 passwd_free(&pass);
3289 continue;
3292 urid = pdb_get_user_rid(sam_user);
3293 if (urid == 0) {
3294 pdb_free_sam(&sam_user);
3295 passwd_free(&pass);
3296 continue;
3299 pdb_free_sam(&sam_user);
3300 passwd_free(&pass);
3302 rid[i] = urid;
3303 attr[i] = SID_NAME_USER;
3306 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3308 return NT_STATUS_OK;
3311 /*********************************************************************
3312 _samr_add_aliasmem
3313 *********************************************************************/
3315 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3317 DOM_SID alias_sid;
3318 fstring alias_sid_str;
3319 uid_t uid;
3320 struct passwd *pwd;
3321 struct group *grp;
3322 fstring grp_name;
3323 GROUP_MAP map;
3324 NTSTATUS ret;
3325 SAM_ACCOUNT *sam_user = NULL;
3326 BOOL check;
3327 uint32 acc_granted;
3329 /* Find the policy handle. Open a policy on it. */
3330 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3331 return NT_STATUS_INVALID_HANDLE;
3333 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, ALIAS_ACCESS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3334 return r_u->status;
3337 sid_to_string(alias_sid_str, &alias_sid);
3338 DEBUG(10, ("sid is %s\n", alias_sid_str));
3340 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3341 DEBUG(10, ("adding member on Server SID\n"));
3342 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3343 return NT_STATUS_NO_SUCH_ALIAS;
3345 } else {
3346 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3347 DEBUG(10, ("adding member on BUILTIN SID\n"));
3348 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3349 return NT_STATUS_NO_SUCH_ALIAS;
3351 } else
3352 return NT_STATUS_NO_SUCH_ALIAS;
3355 ret = pdb_init_sam(&sam_user);
3356 if (!NT_STATUS_IS_OK(ret))
3357 return ret;
3359 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3361 if (check != True) {
3362 pdb_free_sam(&sam_user);
3363 return NT_STATUS_NO_SUCH_USER;
3366 uid = pdb_get_uid(sam_user);
3367 if (uid == -1) {
3368 pdb_free_sam(&sam_user);
3369 return NT_STATUS_NO_SUCH_USER;
3372 pdb_free_sam(&sam_user);
3374 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3375 return NT_STATUS_NO_SUCH_USER;
3376 } else {
3377 passwd_free(&pwd);
3380 if ((grp=getgrgid(map.gid)) == NULL)
3381 return NT_STATUS_NO_SUCH_ALIAS;
3383 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3384 fstrcpy(grp_name, grp->gr_name);
3386 /* if the user is already in the group */
3387 if(user_in_group_list(pwd->pw_name, grp_name))
3388 return NT_STATUS_MEMBER_IN_ALIAS;
3391 * ok, the group exist, the user exist, the user is not in the group,
3392 * we can (finally) add it to the group !
3394 smb_add_user_group(grp_name, pwd->pw_name);
3396 /* check if the user has been added then ... */
3397 if(!user_in_group_list(pwd->pw_name, grp_name))
3398 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3400 return NT_STATUS_OK;
3403 /*********************************************************************
3404 _samr_del_aliasmem
3405 *********************************************************************/
3407 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3409 DOM_SID alias_sid;
3410 fstring alias_sid_str;
3411 struct group *grp;
3412 fstring grp_name;
3413 GROUP_MAP map;
3414 SAM_ACCOUNT *sam_pass=NULL;
3415 uint32 acc_granted;
3417 /* Find the policy handle. Open a policy on it. */
3418 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3419 return NT_STATUS_INVALID_HANDLE;
3421 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, ALIAS_ACCESS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3422 return r_u->status;
3425 sid_to_string(alias_sid_str, &alias_sid);
3426 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3428 if (!sid_check_is_in_our_domain(&alias_sid) &&
3429 !sid_check_is_in_builtin(&alias_sid)) {
3430 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3431 return NT_STATUS_NO_SUCH_ALIAS;
3434 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3435 return NT_STATUS_NO_SUCH_ALIAS;
3437 if ((grp=getgrgid(map.gid)) == NULL)
3438 return NT_STATUS_NO_SUCH_ALIAS;
3440 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3441 fstrcpy(grp_name, grp->gr_name);
3443 /* check if the user exists before trying to remove it from the group */
3444 pdb_init_sam(&sam_pass);
3445 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3446 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3447 pdb_free_sam(&sam_pass);
3448 return NT_STATUS_NO_SUCH_USER;
3451 /* if the user is not in the group */
3452 if(!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3453 pdb_free_sam(&sam_pass);
3454 return NT_STATUS_MEMBER_IN_ALIAS;
3457 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3459 /* check if the user has been removed then ... */
3460 if(user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3461 pdb_free_sam(&sam_pass);
3462 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3465 pdb_free_sam(&sam_pass);
3466 return NT_STATUS_OK;
3469 /*********************************************************************
3470 _samr_add_groupmem
3471 *********************************************************************/
3473 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3475 DOM_SID group_sid;
3476 DOM_SID user_sid;
3477 fstring group_sid_str;
3478 struct passwd *pwd;
3479 struct group *grp;
3480 fstring grp_name;
3481 GROUP_MAP map;
3482 uid_t uid;
3483 NTSTATUS ret;
3484 SAM_ACCOUNT *sam_user;
3485 BOOL check;
3486 uint32 acc_granted;
3488 /* Find the policy handle. Open a policy on it. */
3489 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3490 return NT_STATUS_INVALID_HANDLE;
3492 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, GROUP_ACCESS_ADD_MEMBER, "_samr_add_groupmem"))) {
3493 return r_u->status;
3496 sid_to_string(group_sid_str, &group_sid);
3497 DEBUG(10, ("sid is %s\n", group_sid_str));
3499 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3500 return NT_STATUS_NO_SUCH_GROUP;
3502 DEBUG(10, ("lookup on Domain SID\n"));
3504 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3505 return NT_STATUS_NO_SUCH_GROUP;
3507 sid_copy(&user_sid, get_global_sam_sid());
3508 sid_append_rid(&user_sid, q_u->rid);
3510 ret = pdb_init_sam(&sam_user);
3511 if (!NT_STATUS_IS_OK(ret))
3512 return ret;
3514 check = pdb_getsampwsid(sam_user, &user_sid);
3516 if (check != True) {
3517 pdb_free_sam(&sam_user);
3518 return NT_STATUS_NO_SUCH_USER;
3521 uid = pdb_get_uid(sam_user);
3522 if (uid == -1) {
3523 pdb_free_sam(&sam_user);
3524 return NT_STATUS_NO_SUCH_USER;
3527 pdb_free_sam(&sam_user);
3529 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3530 return NT_STATUS_NO_SUCH_USER;
3531 } else {
3532 passwd_free(&pwd);
3535 if ((grp=getgrgid(map.gid)) == NULL)
3536 return NT_STATUS_NO_SUCH_GROUP;
3538 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3539 fstrcpy(grp_name, grp->gr_name);
3541 /* if the user is already in the group */
3542 if(user_in_group_list(pwd->pw_name, grp_name))
3543 return NT_STATUS_MEMBER_IN_GROUP;
3546 * ok, the group exist, the user exist, the user is not in the group,
3548 * we can (finally) add it to the group !
3551 smb_add_user_group(grp_name, pwd->pw_name);
3553 /* check if the user has been added then ... */
3554 if(!user_in_group_list(pwd->pw_name, grp_name))
3555 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3557 return NT_STATUS_OK;
3560 /*********************************************************************
3561 _samr_del_groupmem
3562 *********************************************************************/
3564 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3566 DOM_SID group_sid;
3567 DOM_SID user_sid;
3568 SAM_ACCOUNT *sam_pass=NULL;
3569 GROUP_MAP map;
3570 fstring grp_name;
3571 struct group *grp;
3572 uint32 acc_granted;
3575 * delete the group member named q_u->rid
3576 * who is a member of the sid associated with the handle
3577 * the rid is a user's rid as the group is a domain group.
3580 /* Find the policy handle. Open a policy on it. */
3581 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3582 return NT_STATUS_INVALID_HANDLE;
3584 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, GROUP_ACCESS_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3585 return r_u->status;
3588 if (!sid_check_is_in_our_domain(&group_sid))
3589 return NT_STATUS_NO_SUCH_GROUP;
3591 sid_copy(&user_sid, get_global_sam_sid());
3592 sid_append_rid(&user_sid, q_u->rid);
3594 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3595 return NT_STATUS_NO_SUCH_GROUP;
3597 if ((grp=getgrgid(map.gid)) == NULL)
3598 return NT_STATUS_NO_SUCH_GROUP;
3600 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3601 fstrcpy(grp_name, grp->gr_name);
3603 /* check if the user exists before trying to remove it from the group */
3604 pdb_init_sam(&sam_pass);
3605 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3606 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3607 pdb_free_sam(&sam_pass);
3608 return NT_STATUS_NO_SUCH_USER;
3611 /* if the user is not in the group */
3612 if (!user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3613 pdb_free_sam(&sam_pass);
3614 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3617 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3619 /* check if the user has been removed then ... */
3620 if (user_in_group_list(pdb_get_username(sam_pass), grp_name)) {
3621 pdb_free_sam(&sam_pass);
3622 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3625 pdb_free_sam(&sam_pass);
3626 return NT_STATUS_OK;
3630 /****************************************************************************
3631 Delete a UNIX user on demand.
3632 ****************************************************************************/
3634 static int smb_delete_user(const char *unix_user)
3636 pstring del_script;
3637 int ret;
3639 pstrcpy(del_script, lp_deluser_script());
3640 if (! *del_script)
3641 return -1;
3642 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3643 ret = smbrun(del_script,NULL);
3644 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3645 return ret;
3648 /*********************************************************************
3649 _samr_delete_dom_user
3650 *********************************************************************/
3652 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3654 DOM_SID user_sid;
3655 SAM_ACCOUNT *sam_pass=NULL;
3656 uint32 acc_granted;
3658 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3660 /* Find the policy handle. Open a policy on it. */
3661 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3662 return NT_STATUS_INVALID_HANDLE;
3664 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DELETE_ACCESS, "_samr_delete_dom_user"))) {
3665 return r_u->status;
3668 if (!sid_check_is_in_our_domain(&user_sid))
3669 return NT_STATUS_CANNOT_DELETE;
3671 /* check if the user exists before trying to delete */
3672 pdb_init_sam(&sam_pass);
3673 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3674 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3675 pdb_free_sam(&sam_pass);
3676 return NT_STATUS_NO_SUCH_USER;
3679 /* delete the unix side */
3681 * note: we don't check if the delete really happened
3682 * as the script is not necessary present
3683 * and maybe the sysadmin doesn't want to delete the unix side
3685 smb_delete_user(pdb_get_username(sam_pass));
3687 /* and delete the samba side */
3688 if (!pdb_delete_sam_account(sam_pass)) {
3689 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3690 pdb_free_sam(&sam_pass);
3691 return NT_STATUS_CANNOT_DELETE;
3694 pdb_free_sam(&sam_pass);
3696 if (!close_policy_hnd(p, &q_u->user_pol))
3697 return NT_STATUS_OBJECT_NAME_INVALID;
3699 return NT_STATUS_OK;
3702 /*********************************************************************
3703 _samr_delete_dom_group
3704 *********************************************************************/
3706 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3708 DOM_SID group_sid;
3709 DOM_SID dom_sid;
3710 uint32 group_rid;
3711 fstring group_sid_str;
3712 gid_t gid;
3713 struct group *grp;
3714 GROUP_MAP map;
3715 uint32 acc_granted;
3717 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3719 /* Find the policy handle. Open a policy on it. */
3720 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3721 return NT_STATUS_INVALID_HANDLE;
3723 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DELETE_ACCESS, "_samr_delete_dom_group"))) {
3724 return r_u->status;
3727 sid_copy(&dom_sid, &group_sid);
3728 sid_to_string(group_sid_str, &dom_sid);
3729 sid_split_rid(&dom_sid, &group_rid);
3731 DEBUG(10, ("sid is %s\n", group_sid_str));
3733 /* we check if it's our SID before deleting */
3734 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3735 return NT_STATUS_NO_SUCH_GROUP;
3737 DEBUG(10, ("lookup on Domain SID\n"));
3739 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3740 return NT_STATUS_NO_SUCH_GROUP;
3742 gid=map.gid;
3744 /* check if group really exists */
3745 if ( (grp=getgrgid(gid)) == NULL)
3746 return NT_STATUS_NO_SUCH_GROUP;
3748 /* we can delete the UNIX group */
3749 smb_delete_group(grp->gr_name);
3751 /* check if the group has been successfully deleted */
3752 if ( (grp=getgrgid(gid)) != NULL)
3753 return NT_STATUS_ACCESS_DENIED;
3755 if(!group_map_remove(group_sid))
3756 return NT_STATUS_ACCESS_DENIED;
3758 if (!close_policy_hnd(p, &q_u->group_pol))
3759 return NT_STATUS_OBJECT_NAME_INVALID;
3761 return NT_STATUS_OK;
3764 /*********************************************************************
3765 _samr_delete_dom_alias
3766 *********************************************************************/
3768 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3770 DOM_SID alias_sid;
3771 DOM_SID dom_sid;
3772 uint32 alias_rid;
3773 fstring alias_sid_str;
3774 gid_t gid;
3775 struct group *grp;
3776 GROUP_MAP map;
3777 uint32 acc_granted;
3779 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3781 /* Find the policy handle. Open a policy on it. */
3782 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3783 return NT_STATUS_INVALID_HANDLE;
3785 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3786 return r_u->status;
3789 sid_copy(&dom_sid, &alias_sid);
3790 sid_to_string(alias_sid_str, &dom_sid);
3791 sid_split_rid(&dom_sid, &alias_rid);
3793 DEBUG(10, ("sid is %s\n", alias_sid_str));
3795 /* we check if it's our SID before deleting */
3796 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3797 return NT_STATUS_NO_SUCH_ALIAS;
3799 DEBUG(10, ("lookup on Local SID\n"));
3801 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3802 return NT_STATUS_NO_SUCH_ALIAS;
3804 gid=map.gid;
3806 /* check if group really exists */
3807 if ( (grp=getgrgid(gid)) == NULL)
3808 return NT_STATUS_NO_SUCH_ALIAS;
3810 /* we can delete the UNIX group */
3811 smb_delete_group(grp->gr_name);
3813 /* check if the group has been successfully deleted */
3814 if ( (grp=getgrgid(gid)) != NULL)
3815 return NT_STATUS_ACCESS_DENIED;
3817 /* don't check if we removed it as it could be an un-mapped group */
3818 group_map_remove(alias_sid);
3820 if (!close_policy_hnd(p, &q_u->alias_pol))
3821 return NT_STATUS_OBJECT_NAME_INVALID;
3823 return NT_STATUS_OK;
3826 /*********************************************************************
3827 _samr_create_dom_group
3828 *********************************************************************/
3830 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3832 DOM_SID dom_sid;
3833 DOM_SID info_sid;
3834 fstring name;
3835 fstring sid_string;
3836 struct group *grp;
3837 struct samr_info *info;
3838 PRIVILEGE_SET priv_set;
3839 uint32 acc_granted;
3841 init_privilege(&priv_set);
3843 /* Find the policy handle. Open a policy on it. */
3844 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3845 return NT_STATUS_INVALID_HANDLE;
3847 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_CREATE_GROUP, "_samr_create_dom_group"))) {
3848 return r_u->status;
3851 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3852 return NT_STATUS_ACCESS_DENIED;
3854 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3856 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3858 /* check if group already exist */
3859 if ((grp=getgrnam(name)) != NULL)
3860 return NT_STATUS_GROUP_EXISTS;
3862 /* we can create the UNIX group */
3863 smb_create_group(name);
3865 /* check if the group has been successfully created */
3866 if ((grp=getgrnam(name)) == NULL)
3867 return NT_STATUS_ACCESS_DENIED;
3869 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3871 /* add the group to the mapping table */
3872 sid_copy(&info_sid, get_global_sam_sid());
3873 sid_append_rid(&info_sid, r_u->rid);
3874 sid_to_string(sid_string, &info_sid);
3876 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3877 return NT_STATUS_ACCESS_DENIED;
3879 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3880 return NT_STATUS_NO_MEMORY;
3882 /* get a (unique) handle. open a policy on it. */
3883 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3884 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3886 return NT_STATUS_OK;
3889 /*********************************************************************
3890 _samr_create_dom_alias
3891 *********************************************************************/
3893 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3895 DOM_SID dom_sid;
3896 DOM_SID info_sid;
3897 fstring name;
3898 fstring sid_string;
3899 struct group *grp;
3900 struct samr_info *info;
3901 PRIVILEGE_SET priv_set;
3902 uint32 acc_granted;
3904 init_privilege(&priv_set);
3906 /* Find the policy handle. Open a policy on it. */
3907 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3908 return NT_STATUS_INVALID_HANDLE;
3910 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_CREATE_ALIAS, "_samr_create_alias"))) {
3911 return r_u->status;
3914 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3915 return NT_STATUS_ACCESS_DENIED;
3917 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3919 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3921 /* check if group already exists */
3922 if ( (grp=getgrnam(name)) != NULL)
3923 return NT_STATUS_GROUP_EXISTS;
3925 /* we can create the UNIX group */
3926 smb_create_group(name);
3928 /* check if the group has been successfully created */
3929 if ((grp=getgrnam(name)) == NULL)
3930 return NT_STATUS_ACCESS_DENIED;
3932 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3934 sid_copy(&info_sid, get_global_sam_sid());
3935 sid_append_rid(&info_sid, r_u->rid);
3936 sid_to_string(sid_string, &info_sid);
3938 /* add the group to the mapping table */
3939 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3940 return NT_STATUS_ACCESS_DENIED;
3942 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3943 return NT_STATUS_NO_MEMORY;
3945 /* get a (unique) handle. open a policy on it. */
3946 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3947 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3949 return NT_STATUS_OK;
3952 /*********************************************************************
3953 _samr_query_groupinfo
3955 sends the name/comment pair of a domain group
3956 level 1 send also the number of users of that group
3957 *********************************************************************/
3959 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3961 DOM_SID group_sid;
3962 GROUP_MAP map;
3963 uid_t *uid=NULL;
3964 int num_uids=0;
3965 GROUP_INFO_CTR *ctr;
3966 uint32 acc_granted;
3968 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3969 return NT_STATUS_INVALID_HANDLE;
3971 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, GROUP_ACCESS_LOOKUP_INFO, "_samr_query_groupinfo"))) {
3972 return r_u->status;
3975 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3976 return NT_STATUS_INVALID_HANDLE;
3978 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
3979 if (ctr==NULL)
3980 return NT_STATUS_NO_MEMORY;
3982 switch (q_u->switch_level) {
3983 case 1:
3984 ctr->switch_value1 = 1;
3985 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3986 return NT_STATUS_NO_SUCH_GROUP;
3987 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
3988 SAFE_FREE(uid);
3989 break;
3990 case 3:
3991 ctr->switch_value1 = 3;
3992 init_samr_group_info3(&ctr->group.info3);
3993 break;
3994 case 4:
3995 ctr->switch_value1 = 4;
3996 init_samr_group_info4(&ctr->group.info4, map.comment);
3997 break;
3998 default:
3999 return NT_STATUS_INVALID_INFO_CLASS;
4002 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4004 return NT_STATUS_OK;
4007 /*********************************************************************
4008 _samr_set_groupinfo
4010 update a domain group's comment.
4011 *********************************************************************/
4013 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4015 DOM_SID group_sid;
4016 GROUP_MAP map;
4017 GROUP_INFO_CTR *ctr;
4018 uint32 acc_granted;
4020 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4021 return NT_STATUS_INVALID_HANDLE;
4023 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, GROUP_ACCESS_SET_INFO, "_samr_set_groupinfo"))) {
4024 return r_u->status;
4027 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4028 return NT_STATUS_NO_SUCH_GROUP;
4030 ctr=q_u->ctr;
4032 switch (ctr->switch_value1) {
4033 case 1:
4034 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4035 break;
4036 case 4:
4037 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4038 break;
4039 default:
4040 free_privilege(&map.priv_set);
4041 return NT_STATUS_INVALID_INFO_CLASS;
4044 if(!add_mapping_entry(&map, TDB_REPLACE)) {
4045 free_privilege(&map.priv_set);
4046 return NT_STATUS_NO_SUCH_GROUP;
4049 free_privilege(&map.priv_set);
4051 return NT_STATUS_OK;
4054 /*********************************************************************
4055 _samr_set_groupinfo
4057 update a domain group's comment.
4058 *********************************************************************/
4060 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4062 DOM_SID group_sid;
4063 GROUP_MAP map;
4064 ALIAS_INFO_CTR *ctr;
4065 uint32 acc_granted;
4067 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4068 return NT_STATUS_INVALID_HANDLE;
4070 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, ALIAS_ACCESS_SET_INFO, "_samr_set_aliasinfo"))) {
4071 return r_u->status;
4074 if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4075 return NT_STATUS_NO_SUCH_GROUP;
4077 ctr=&q_u->ctr;
4079 switch (ctr->switch_value1) {
4080 case 3:
4081 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4082 break;
4083 default:
4084 free_privilege(&map.priv_set);
4085 return NT_STATUS_INVALID_INFO_CLASS;
4088 if(!add_mapping_entry(&map, TDB_REPLACE)) {
4089 free_privilege(&map.priv_set);
4090 return NT_STATUS_NO_SUCH_GROUP;
4093 free_privilege(&map.priv_set);
4095 return NT_STATUS_OK;
4098 /*********************************************************************
4099 _samr_get_dom_pwinfo
4100 *********************************************************************/
4102 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4104 /* Perform access check. Since this rpc does not require a
4105 policy handle it will not be caught by the access checks on
4106 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4108 if (!pipe_access_check(p)) {
4109 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4110 r_u->status = NT_STATUS_ACCESS_DENIED;
4111 return r_u->status;
4114 /* Actually, returning zeros here works quite well :-). */
4116 return NT_STATUS_OK;
4119 /*********************************************************************
4120 _samr_open_group
4121 *********************************************************************/
4123 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4125 DOM_SID sid;
4126 DOM_SID info_sid;
4127 GROUP_MAP map;
4128 struct samr_info *info;
4129 SEC_DESC *psd = NULL;
4130 uint32 acc_granted;
4131 uint32 des_access;
4132 size_t sd_size;
4133 NTSTATUS status;
4134 fstring sid_string;
4136 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4137 return NT_STATUS_INVALID_HANDLE;
4139 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_open_group"))) {
4140 return status;
4143 /*check if access can be granted as requested by client. */
4144 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4145 se_map_generic(&des_access,&grp_generic_mapping);
4146 if (!NT_STATUS_IS_OK(status =
4147 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4148 des_access, &acc_granted, "_samr_open_group"))) {
4149 return status;
4153 /* this should not be hard-coded like this */
4154 if (!sid_equal(&sid, get_global_sam_sid()))
4155 return NT_STATUS_ACCESS_DENIED;
4157 sid_copy(&info_sid, get_global_sam_sid());
4158 sid_append_rid(&info_sid, q_u->rid_group);
4159 sid_to_string(sid_string, &info_sid);
4161 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4162 return NT_STATUS_NO_MEMORY;
4164 info->acc_granted = acc_granted;
4166 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4168 /* check if that group really exists */
4169 if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
4170 return NT_STATUS_NO_SUCH_GROUP;
4172 /* get a (unique) handle. open a policy on it. */
4173 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4174 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4176 return NT_STATUS_OK;
4179 /*********************************************************************
4180 _samr_unknown_2d
4181 *********************************************************************/
4183 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4185 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4186 return NT_STATUS_NOT_IMPLEMENTED;
4189 /*******************************************************************
4190 _samr_unknown_2e
4191 ********************************************************************/
4193 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4195 struct samr_info *info = NULL;
4196 SAM_UNK_CTR *ctr;
4197 uint32 min_pass_len,pass_hist,flag;
4198 time_t u_expire, u_min_age;
4199 NTTIME nt_expire, nt_min_age;
4201 time_t u_lock_duration, u_reset_time;
4202 NTTIME nt_lock_duration, nt_reset_time;
4203 uint32 lockout;
4205 time_t u_logout;
4206 NTTIME nt_logout;
4208 uint32 num_users=0, num_groups=0, num_aliases=0;
4210 uint32 account_policy_temp;
4212 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4213 return NT_STATUS_NO_MEMORY;
4215 ZERO_STRUCTP(ctr);
4217 r_u->status = NT_STATUS_OK;
4219 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4221 /* find the policy handle. open a policy on it. */
4222 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4223 return NT_STATUS_INVALID_HANDLE;
4225 switch (q_u->switch_value) {
4226 case 0x01:
4227 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4228 min_pass_len = account_policy_temp;
4230 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4231 pass_hist = account_policy_temp;
4233 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4234 flag = account_policy_temp;
4236 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4237 u_expire = account_policy_temp;
4239 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4240 u_min_age = account_policy_temp;
4242 unix_to_nt_time_abs(&nt_expire, u_expire);
4243 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4245 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4246 flag, nt_expire, nt_min_age);
4247 break;
4248 case 0x02:
4249 become_root();
4250 r_u->status=load_sampwd_entries(info, ACB_NORMAL);
4251 unbecome_root();
4252 if (!NT_STATUS_IS_OK(r_u->status)) {
4253 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
4254 return r_u->status;
4256 num_users=info->disp_info.num_user_account;
4257 free_samr_db(info);
4259 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4260 if (NT_STATUS_IS_ERR(r_u->status)) {
4261 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
4262 return r_u->status;
4264 num_groups=info->disp_info.num_group_account;
4265 free_samr_db(info);
4267 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4268 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL),
4269 num_users, num_groups, num_aliases);
4270 break;
4271 case 0x03:
4272 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4273 u_logout = account_policy_temp;
4275 unix_to_nt_time_abs(&nt_logout, u_logout);
4277 init_unk_info3(&ctr->info.inf3, nt_logout);
4278 break;
4279 case 0x05:
4280 init_unk_info5(&ctr->info.inf5, global_myname);
4281 break;
4282 case 0x06:
4283 init_unk_info6(&ctr->info.inf6);
4284 break;
4285 case 0x07:
4286 init_unk_info7(&ctr->info.inf7);
4287 break;
4288 case 0x0c:
4289 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4290 u_lock_duration = account_policy_temp;
4292 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4293 u_reset_time = account_policy_temp;
4295 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4296 lockout = account_policy_temp;
4298 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4299 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4301 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4302 break;
4303 default:
4304 return NT_STATUS_INVALID_INFO_CLASS;
4307 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4309 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4311 return r_u->status;
4314 /*******************************************************************
4315 _samr_
4316 ********************************************************************/
4318 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4320 time_t u_expire, u_min_age;
4321 time_t u_logout;
4322 time_t u_lock_duration, u_reset_time;
4324 r_u->status = NT_STATUS_OK;
4326 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4328 /* find the policy handle. open a policy on it. */
4329 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4330 return NT_STATUS_INVALID_HANDLE;
4332 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4334 switch (q_u->switch_value) {
4335 case 0x01:
4336 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4337 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4339 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4340 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4341 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4342 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4343 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4344 break;
4345 case 0x02:
4346 break;
4347 case 0x03:
4348 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4349 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4350 break;
4351 case 0x05:
4352 break;
4353 case 0x06:
4354 break;
4355 case 0x07:
4356 break;
4357 case 0x0c:
4358 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4359 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4361 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4362 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4363 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4364 break;
4365 default:
4366 return NT_STATUS_INVALID_INFO_CLASS;
4369 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4371 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4373 return r_u->status;