r2176: syncing necessary changes for 3.0.7
[Samba.git] / source / rpc_server / srv_samr_nt.c
blobce6d9dd37ec4f323d0dcbc15c8c5870f56844a60
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003,
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
32 #include "includes.h"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
44 typedef struct _disp_info {
45 BOOL user_dbloaded;
46 uint32 num_user_account;
47 SAM_ACCOUNT *disp_user_info;
48 BOOL group_dbloaded;
49 uint32 num_group_account;
50 DOMAIN_GRP *disp_group_info;
51 } DISP_INFO;
53 struct samr_info {
54 /* for use by the \PIPE\samr policy */
55 DOM_SID sid;
56 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
57 uint32 acc_granted;
58 uint16 acb_mask;
59 BOOL all_machines;
60 DISP_INFO disp_info;
62 TALLOC_CTX *mem_ctx;
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
79 uint32 *acc_granted, const char *debug)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
83 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84 *acc_granted = des_access;
85 if (geteuid() == sec_initial_uid()) {
86 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
87 debug, des_access));
88 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89 status = NT_STATUS_OK;
91 else {
92 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
93 debug, des_access));
96 return status;
99 /*******************************************************************
100 Checks if access to a function can be granted
101 ********************************************************************/
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
105 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
106 debug, acc_granted, acc_required));
107 if ((acc_granted & acc_required) != acc_required) {
108 if (geteuid() == sec_initial_uid()) {
109 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
110 debug, acc_granted, acc_required));
111 DEBUGADD(4,("but overwritten by euid == 0\n"));
112 return NT_STATUS_OK;
114 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
115 debug, acc_granted, acc_required));
116 return NT_STATUS_ACCESS_DENIED;
118 return NT_STATUS_OK;
122 /*******************************************************************
123 Create a samr_info struct.
124 ********************************************************************/
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
128 struct samr_info *info;
129 fstring sid_str;
130 TALLOC_CTX *mem_ctx;
132 if (psid) {
133 sid_to_string(sid_str, psid);
134 } else {
135 fstrcpy(sid_str,"(NULL)");
138 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
140 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
141 return NULL;
143 ZERO_STRUCTP(info);
144 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
145 if (psid) {
146 sid_copy( &info->sid, psid);
147 } else {
148 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
150 info->mem_ctx = mem_ctx;
151 return info;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
158 static void free_samr_users(struct samr_info *info)
160 int i;
162 if (info->disp_info.user_dbloaded){
163 for (i=0; i<info->disp_info.num_user_account; i++) {
164 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165 /* Not really a free, actually a 'clear' */
166 pdb_free_sam(&sam);
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
187 static void free_samr_info(void *ptr)
189 struct samr_info *info=(struct samr_info *) ptr;
191 free_samr_db(info);
192 talloc_destroy(info->mem_ctx);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
202 if (!sam_pass)
203 return;
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
214 SAM_ACCOUNT *pwd = NULL;
215 SAM_ACCOUNT *pwd_array = NULL;
216 NTSTATUS nt_status = NT_STATUS_OK;
217 TALLOC_CTX *mem_ctx = info->mem_ctx;
219 DEBUG(10,("load_sampwd_entries\n"));
221 /* if the snapshoot is already loaded, return */
222 if ((info->disp_info.user_dbloaded==True)
223 && (info->acb_mask == acb_mask)
224 && (info->all_machines == all_machines)) {
225 DEBUG(10,("load_sampwd_entries: already in memory\n"));
226 return NT_STATUS_OK;
229 free_samr_users(info);
231 if (!pdb_setsampwent(False)) {
232 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233 return NT_STATUS_ACCESS_DENIED;
236 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
237 && pdb_getsampwent(pwd) == True; pwd=NULL) {
239 if (all_machines) {
240 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
241 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
243 pdb_free_sam(&pwd);
244 continue;
246 } else {
247 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
248 pdb_free_sam(&pwd);
249 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
250 continue;
254 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
257 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258 pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
259 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
261 if (pwd_array==NULL)
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* Copy the SAM_ACCOUNT into the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
270 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
272 info->disp_info.num_user_account++;
275 pdb_endsampwent();
277 /* the snapshoot is in memory, we're ready to enumerate fast */
279 info->acb_mask = acb_mask;
280 info->all_machines = all_machines;
281 info->disp_info.user_dbloaded=True;
283 DEBUG(10,("load_sampwd_entries: done\n"));
285 return nt_status;
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
290 GROUP_MAP *map=NULL;
291 DOMAIN_GRP *grp_array = NULL;
292 uint32 group_entries = 0;
293 uint32 i;
294 TALLOC_CTX *mem_ctx = info->mem_ctx;
295 BOOL ret;
297 DEBUG(10,("load_group_domain_entries\n"));
299 /* if the snapshoot is already loaded, return */
300 if (info->disp_info.group_dbloaded==True) {
301 DEBUG(10,("load_group_domain_entries: already in memory\n"));
302 return NT_STATUS_OK;
305 if (sid_equal(sid, &global_sid_Builtin)) {
306 /* No domain groups for now in the BUILTIN domain */
307 info->disp_info.num_group_account=0;
308 info->disp_info.disp_group_info=NULL;
309 info->disp_info.group_dbloaded=True;
310 return NT_STATUS_OK;
313 become_root();
314 ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
315 unbecome_root();
317 if ( !ret ) {
318 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
319 return NT_STATUS_NO_MEMORY;
323 info->disp_info.num_group_account=group_entries;
325 grp_array=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
326 if (group_entries!=0 && grp_array==NULL) {
327 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
328 SAFE_FREE(map);
329 return NT_STATUS_NO_MEMORY;
332 info->disp_info.disp_group_info=grp_array;
334 for (i=0; i<group_entries; i++) {
335 fstrcpy(grp_array[i].name, map[i].nt_name);
336 fstrcpy(grp_array[i].comment, map[i].comment);
337 sid_split_rid(&map[i].sid, &grp_array[i].rid);
338 grp_array[i].attr=SID_NAME_DOM_GRP;
341 SAFE_FREE(map);
343 /* the snapshoot is in memory, we're ready to enumerate fast */
345 info->disp_info.group_dbloaded=True;
347 DEBUG(10,("load_group_domain_entries: done\n"));
349 return NT_STATUS_OK;
353 /*******************************************************************
354 _samr_close_hnd
355 ********************************************************************/
357 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
359 r_u->status = NT_STATUS_OK;
361 /* close the policy handle */
362 if (!close_policy_hnd(p, &q_u->pol))
363 return NT_STATUS_OBJECT_NAME_INVALID;
365 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
367 return r_u->status;
370 /*******************************************************************
371 samr_reply_open_domain
372 ********************************************************************/
374 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
376 struct samr_info *info;
377 SEC_DESC *psd = NULL;
378 uint32 acc_granted;
379 uint32 des_access = q_u->flags;
380 size_t sd_size;
381 NTSTATUS status;
383 r_u->status = NT_STATUS_OK;
385 /* find the connection policy handle. */
386 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
387 return NT_STATUS_INVALID_HANDLE;
389 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
390 return status;
393 /*check if access can be granted as requested by client. */
394 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
395 se_map_generic(&des_access,&dom_generic_mapping);
397 if (!NT_STATUS_IS_OK(status =
398 access_check_samr_object(psd, p->pipe_user.nt_user_token,
399 des_access, &acc_granted, "_samr_open_domain"))) {
400 return status;
403 /* associate the domain SID with the (unique) handle. */
404 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
405 return NT_STATUS_NO_MEMORY;
406 info->acc_granted = acc_granted;
408 /* get a (unique) handle. open a policy on it. */
409 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
410 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
412 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
414 return r_u->status;
417 /*******************************************************************
418 _samr_get_usrdom_pwinfo
419 ********************************************************************/
421 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
423 struct samr_info *info = NULL;
425 r_u->status = NT_STATUS_OK;
427 /* find the policy handle. open a policy on it. */
428 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
429 return NT_STATUS_INVALID_HANDLE;
431 if (!sid_check_is_in_our_domain(&info->sid))
432 return NT_STATUS_OBJECT_TYPE_MISMATCH;
434 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
436 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
439 * NT sometimes return NT_STATUS_ACCESS_DENIED
440 * I don't know yet why.
443 return r_u->status;
446 /*******************************************************************
447 samr_make_dom_obj_sd
448 ********************************************************************/
450 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
452 extern DOM_SID global_sid_World;
453 DOM_SID adm_sid;
454 DOM_SID act_sid;
456 SEC_ACE ace[3];
457 SEC_ACCESS mask;
459 SEC_ACL *psa = NULL;
461 sid_copy(&adm_sid, &global_sid_Builtin);
462 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
464 sid_copy(&act_sid, &global_sid_Builtin);
465 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
467 /*basic access for every one*/
468 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
469 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
471 /*full access for builtin aliases Administrators and Account Operators*/
472 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
473 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
474 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
476 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
477 return NT_STATUS_NO_MEMORY;
479 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
480 return NT_STATUS_NO_MEMORY;
482 return NT_STATUS_OK;
485 /*******************************************************************
486 samr_make_usr_obj_sd
487 ********************************************************************/
489 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
491 extern DOM_SID global_sid_World;
492 DOM_SID adm_sid;
493 DOM_SID act_sid;
495 SEC_ACE ace[4];
496 SEC_ACCESS mask;
498 SEC_ACL *psa = NULL;
500 sid_copy(&adm_sid, &global_sid_Builtin);
501 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
503 sid_copy(&act_sid, &global_sid_Builtin);
504 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
506 /*basic access for every one*/
507 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
508 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 /*full access for builtin aliases Administrators and Account Operators*/
511 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
512 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
513 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
515 /*extended access for the user*/
516 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
517 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
519 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
520 return NT_STATUS_NO_MEMORY;
522 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
523 return NT_STATUS_NO_MEMORY;
525 return NT_STATUS_OK;
528 /*******************************************************************
529 samr_make_grp_obj_sd
530 ********************************************************************/
532 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
534 extern DOM_SID global_sid_World;
535 DOM_SID adm_sid;
536 DOM_SID act_sid;
538 SEC_ACE ace[3];
539 SEC_ACCESS mask;
541 SEC_ACL *psa = NULL;
543 sid_copy(&adm_sid, &global_sid_Builtin);
544 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
546 sid_copy(&act_sid, &global_sid_Builtin);
547 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
549 /*basic access for every one*/
550 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
551 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
553 /*full access for builtin aliases Administrators and Account Operators*/
554 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
555 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
556 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
558 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
559 return NT_STATUS_NO_MEMORY;
561 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
562 return NT_STATUS_NO_MEMORY;
564 return NT_STATUS_OK;
567 /*******************************************************************
568 samr_make_ali_obj_sd
569 ********************************************************************/
571 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
573 extern DOM_SID global_sid_World;
574 DOM_SID adm_sid;
575 DOM_SID act_sid;
577 SEC_ACE ace[3];
578 SEC_ACCESS mask;
580 SEC_ACL *psa = NULL;
582 sid_copy(&adm_sid, &global_sid_Builtin);
583 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
585 sid_copy(&act_sid, &global_sid_Builtin);
586 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
588 /*basic access for every one*/
589 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
590 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
592 /*full access for builtin aliases Administrators and Account Operators*/
593 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
594 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
595 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
597 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
598 return NT_STATUS_NO_MEMORY;
600 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
601 return NT_STATUS_NO_MEMORY;
603 return NT_STATUS_OK;
606 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
608 struct samr_info *info = NULL;
610 /* find the policy handle. open a policy on it. */
611 if (!find_policy_by_hnd(p, pol, (void **)&info))
612 return False;
614 if (!info)
615 return False;
617 *sid = info->sid;
618 *acc_granted = info->acc_granted;
619 return True;
622 /*******************************************************************
623 _samr_set_sec_obj
624 ********************************************************************/
626 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
628 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
629 return NT_STATUS_NOT_IMPLEMENTED;
633 /*******************************************************************
634 _samr_query_sec_obj
635 ********************************************************************/
637 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
639 DOM_SID pol_sid;
640 fstring str_sid;
641 SEC_DESC * psd = NULL;
642 size_t sd_size;
643 uint32 acc_granted;
645 r_u->status = NT_STATUS_OK;
647 /* Get the SID. */
648 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
649 return NT_STATUS_INVALID_HANDLE;
653 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
655 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
657 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
658 if (pol_sid.sid_rev_num == 0)
660 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
661 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
663 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
666 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
667 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
669 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
671 /* TODO: Builtin probably needs a different SD with restricted write access*/
672 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
673 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
675 else if (sid_check_is_in_our_domain(&pol_sid) ||
676 sid_check_is_in_builtin(&pol_sid))
678 /* TODO: different SDs have to be generated for aliases groups and users.
679 Currently all three get a default user SD */
680 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
681 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
683 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
685 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
686 return NT_STATUS_NO_MEMORY;
688 if (NT_STATUS_IS_OK(r_u->status))
689 r_u->ptr = 1;
691 return r_u->status;
694 /*******************************************************************
695 makes a SAM_ENTRY / UNISTR2* structure from a user list.
696 ********************************************************************/
698 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
699 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
700 DOM_SID *domain_sid)
702 uint32 i;
703 SAM_ENTRY *sam;
704 UNISTR2 *uni_name;
705 SAM_ACCOUNT *pwd = NULL;
706 UNISTR2 uni_temp_name;
707 const char *temp_name;
708 const DOM_SID *user_sid;
709 uint32 user_rid;
710 fstring user_sid_string;
711 fstring domain_sid_string;
713 *sam_pp = NULL;
714 *uni_name_pp = NULL;
716 if (num_entries == 0)
717 return NT_STATUS_OK;
719 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
721 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
723 if (sam == NULL || uni_name == NULL) {
724 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
725 return NT_STATUS_NO_MEMORY;
728 for (i = 0; i < num_entries; i++) {
729 pwd = &disp_user_info[i+start_idx];
730 temp_name = pdb_get_username(pwd);
731 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
732 user_sid = pdb_get_user_sid(pwd);
734 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
735 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
736 "the domain sid %s. Failing operation.\n",
737 temp_name,
738 sid_to_string(user_sid_string, user_sid),
739 sid_to_string(domain_sid_string, domain_sid)));
740 return NT_STATUS_UNSUCCESSFUL;
743 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
744 copy_unistr2(&uni_name[i], &uni_temp_name);
747 *sam_pp = sam;
748 *uni_name_pp = uni_name;
749 return NT_STATUS_OK;
752 /*******************************************************************
753 samr_reply_enum_dom_users
754 ********************************************************************/
756 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
757 SAMR_R_ENUM_DOM_USERS *r_u)
759 struct samr_info *info = NULL;
760 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
761 int num_account;
762 uint32 enum_context=q_u->start_idx;
763 uint32 max_size=q_u->max_size;
764 uint32 temp_size;
765 enum remote_arch_types ra_type = get_remote_arch();
766 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
767 uint32 max_entries = max_sam_entries;
768 DOM_SID domain_sid;
770 r_u->status = NT_STATUS_OK;
772 /* find the policy handle. open a policy on it. */
773 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
774 return NT_STATUS_INVALID_HANDLE;
776 domain_sid = info->sid;
778 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
779 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
780 "_samr_enum_dom_users"))) {
781 return r_u->status;
784 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
786 become_root();
787 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
788 unbecome_root();
790 if (!NT_STATUS_IS_OK(r_u->status))
791 return r_u->status;
793 num_account = info->disp_info.num_user_account;
795 if (enum_context > num_account) {
796 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
797 return NT_STATUS_OK;
800 /* verify we won't overflow */
801 if (max_entries > num_account-enum_context) {
802 max_entries = num_account-enum_context;
803 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
806 /* calculate the size and limit on the number of entries we will return */
807 temp_size=max_entries*struct_size;
809 if (temp_size>max_size) {
810 max_entries=MIN((max_size/struct_size),max_entries);;
811 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
815 * Note from JRA. total_entries is not being used here. Currently if there is a
816 * large user base then it looks like NT will enumerate until get_sampwd_entries
817 * returns False due to num_entries being zero. This will cause an access denied
818 * return. I don't think this is right and needs further investigation. Note that
819 * this is also the same in the TNG code (I don't think that has been tested with
820 * a very large user list as MAX_SAM_ENTRIES is set to 600).
822 * I also think that one of the 'num_entries' return parameters is probably
823 * the "max entries" parameter - but in the TNG code they're all currently set to the same
824 * value (again I think this is wrong).
827 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
828 max_entries, enum_context,
829 info->disp_info.disp_user_info,
830 &domain_sid);
832 if (!NT_STATUS_IS_OK(r_u->status))
833 return r_u->status;
835 if (enum_context+max_entries < num_account)
836 r_u->status = STATUS_MORE_ENTRIES;
838 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
840 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
842 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
844 return r_u->status;
847 /*******************************************************************
848 makes a SAM_ENTRY / UNISTR2* structure from a group list.
849 ********************************************************************/
851 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
852 uint32 num_sam_entries, DOMAIN_GRP *grp)
854 uint32 i;
855 SAM_ENTRY *sam;
856 UNISTR2 *uni_name;
858 *sam_pp = NULL;
859 *uni_name_pp = NULL;
861 if (num_sam_entries == 0)
862 return;
864 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
866 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
868 if (sam == NULL || uni_name == NULL) {
869 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
870 return;
873 for (i = 0; i < num_sam_entries; i++) {
875 * JRA. I think this should include the null. TNG does not.
877 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
878 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
881 *sam_pp = sam;
882 *uni_name_pp = uni_name;
885 /*******************************************************************
886 Get the group entries - similar to get_sampwd_entries().
887 ******************************************************************/
889 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
890 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
891 uint32 *p_num_entries, uint32 max_entries )
893 GROUP_MAP *map=NULL;
894 int i;
895 uint32 group_entries = 0;
896 uint32 num_entries = 0;
898 *p_num_entries = 0;
900 /* access checks for the users were performed higher up. become/unbecome_root()
901 needed for some passdb backends to enumerate groups */
903 become_root();
904 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
905 ENUM_ONLY_MAPPED);
906 unbecome_root();
908 num_entries=group_entries-start_idx;
910 /* limit the number of entries */
911 if (num_entries>max_entries) {
912 DEBUG(5,("Limiting to %d entries\n", max_entries));
913 num_entries=max_entries;
916 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
917 if (num_entries!=0 && *d_grp==NULL){
918 SAFE_FREE(map);
919 return NT_STATUS_NO_MEMORY;
922 for (i=0; i<num_entries; i++) {
923 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
924 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
925 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
926 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
929 SAFE_FREE(map);
931 *p_num_entries = num_entries;
933 DEBUG(10,("get_group_domain_entries: returning %d entries\n",
934 *p_num_entries));
936 return NT_STATUS_OK;
939 /*******************************************************************
940 Wrapper for enumerating local groups
941 ******************************************************************/
943 static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
944 const DOM_SID *sid, uint32 start_idx,
945 uint32 *p_num_entries, uint32 max_entries )
947 struct acct_info *info;
948 int i;
949 BOOL res;
951 become_root();
952 res = pdb_enum_aliases(sid, start_idx, max_entries,
953 p_num_entries, &info);
954 unbecome_root();
956 if (!res)
957 return NT_STATUS_ACCESS_DENIED;
959 if (*p_num_entries == 0)
960 return NT_STATUS_OK;
962 *d_grp = talloc(ctx, sizeof(DOMAIN_GRP) * (*p_num_entries));
964 if (*d_grp == NULL) {
965 SAFE_FREE(info);
966 return NT_STATUS_NO_MEMORY;
969 for (i=0; i<*p_num_entries; i++) {
970 fstrcpy((*d_grp)[i].name, info[i].acct_name);
971 fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
972 (*d_grp)[i].rid = info[i].rid;
973 (*d_grp)[i].attr = SID_NAME_ALIAS;
976 SAFE_FREE(info);
977 return NT_STATUS_OK;
980 /*******************************************************************
981 samr_reply_enum_dom_groups
982 ********************************************************************/
984 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
986 DOMAIN_GRP *grp=NULL;
987 uint32 num_entries;
988 DOM_SID sid;
989 uint32 acc_granted;
991 r_u->status = NT_STATUS_OK;
993 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
994 return NT_STATUS_INVALID_HANDLE;
996 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
997 return r_u->status;
1000 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1002 /* the domain group array is being allocated in the function below */
1003 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))) {
1004 return r_u->status;
1007 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1009 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1011 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1013 return r_u->status;
1017 /*******************************************************************
1018 samr_reply_enum_dom_aliases
1019 ********************************************************************/
1021 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1023 DOMAIN_GRP *grp=NULL;
1024 uint32 num_entries = 0;
1025 fstring sid_str;
1026 DOM_SID sid;
1027 NTSTATUS status;
1028 uint32 acc_granted;
1030 r_u->status = NT_STATUS_OK;
1032 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1033 return NT_STATUS_INVALID_HANDLE;
1035 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1036 return r_u->status;
1039 sid_to_string(sid_str, &sid);
1040 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1042 status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1043 &num_entries, MAX_SAM_ENTRIES);
1044 if (!NT_STATUS_IS_OK(status)) return status;
1046 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1048 /*safe_free(grp);*/
1050 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1052 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1054 return r_u->status;
1057 /*******************************************************************
1058 samr_reply_query_dispinfo
1059 ********************************************************************/
1061 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1062 SAMR_R_QUERY_DISPINFO *r_u)
1064 struct samr_info *info = NULL;
1065 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1067 uint32 max_entries=q_u->max_entries;
1068 uint32 enum_context=q_u->start_idx;
1069 uint32 max_size=q_u->max_size;
1071 SAM_DISPINFO_CTR *ctr;
1072 uint32 temp_size=0, total_data_size=0;
1073 NTSTATUS disp_ret;
1074 uint32 num_account = 0;
1075 enum remote_arch_types ra_type = get_remote_arch();
1076 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1077 DOM_SID domain_sid;
1079 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1080 r_u->status = NT_STATUS_OK;
1082 /* find the policy handle. open a policy on it. */
1083 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1084 return NT_STATUS_INVALID_HANDLE;
1086 domain_sid = info->sid;
1089 * calculate how many entries we will return.
1090 * based on
1091 * - the number of entries the client asked
1092 * - our limit on that
1093 * - the starting point (enumeration context)
1094 * - the buffer size the client will accept
1098 * We are a lot more like W2K. Instead of reading the SAM
1099 * each time to find the records we need to send back,
1100 * we read it once and link that copy to the sam handle.
1101 * For large user list (over the MAX_SAM_ENTRIES)
1102 * it's a definitive win.
1103 * second point to notice: between enumerations
1104 * our sam is now the same as it's a snapshoot.
1105 * third point: got rid of the static SAM_USER_21 struct
1106 * no more intermediate.
1107 * con: it uses much more memory, as a full copy is stored
1108 * in memory.
1110 * If you want to change it, think twice and think
1111 * of the second point , that's really important.
1113 * JFM, 12/20/2001
1116 /* Get what we need from the password database */
1117 switch (q_u->switch_level) {
1118 case 0x1:
1119 /* When playing with usrmgr, this is necessary
1120 if you want immediate refresh after editing
1121 a user. I would like to do this after the
1122 setuserinfo2, but we do not have access to
1123 the domain handle in that call, only to the
1124 user handle. Where else does this hurt?
1125 -- Volker
1127 #if 0
1128 /* We cannot do this here - it kills performace. JRA. */
1129 free_samr_users(info);
1130 #endif
1131 case 0x2:
1132 case 0x4:
1133 become_root();
1134 /* Level 2 is for all machines, otherwise only 'normal' users */
1135 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1136 unbecome_root();
1137 if (!NT_STATUS_IS_OK(r_u->status)) {
1138 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1139 return r_u->status;
1141 num_account = info->disp_info.num_user_account;
1142 break;
1143 case 0x3:
1144 case 0x5:
1145 r_u->status = load_group_domain_entries(info, &info->sid);
1146 if (!NT_STATUS_IS_OK(r_u->status))
1147 return r_u->status;
1148 num_account = info->disp_info.num_group_account;
1149 break;
1150 default:
1151 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1152 return NT_STATUS_INVALID_INFO_CLASS;
1155 /* first limit the number of entries we will return */
1156 if(max_entries > max_sam_entries) {
1157 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1158 max_entries = max_sam_entries;
1161 if (enum_context > num_account) {
1162 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1163 return NT_STATUS_NO_MORE_ENTRIES;
1166 /* verify we won't overflow */
1167 if (max_entries > num_account-enum_context) {
1168 max_entries = num_account-enum_context;
1169 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1172 /* calculate the size and limit on the number of entries we will return */
1173 temp_size=max_entries*struct_size;
1175 if (temp_size>max_size) {
1176 max_entries=MIN((max_size/struct_size),max_entries);;
1177 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1180 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1181 return NT_STATUS_NO_MEMORY;
1183 ZERO_STRUCTP(ctr);
1185 /* Now create reply structure */
1186 switch (q_u->switch_level) {
1187 case 0x1:
1188 if (max_entries) {
1189 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1190 return NT_STATUS_NO_MEMORY;
1192 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1193 info->disp_info.disp_user_info, &domain_sid);
1194 if (!NT_STATUS_IS_OK(disp_ret))
1195 return disp_ret;
1196 break;
1197 case 0x2:
1198 if (max_entries) {
1199 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1200 return NT_STATUS_NO_MEMORY;
1202 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1203 info->disp_info.disp_user_info, &domain_sid);
1204 if (!NT_STATUS_IS_OK(disp_ret))
1205 return disp_ret;
1206 break;
1207 case 0x3:
1208 if (max_entries) {
1209 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1210 return NT_STATUS_NO_MEMORY;
1212 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1213 if (!NT_STATUS_IS_OK(disp_ret))
1214 return disp_ret;
1215 break;
1216 case 0x4:
1217 if (max_entries) {
1218 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1219 return NT_STATUS_NO_MEMORY;
1221 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1222 if (!NT_STATUS_IS_OK(disp_ret))
1223 return disp_ret;
1224 break;
1225 case 0x5:
1226 if (max_entries) {
1227 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1228 return NT_STATUS_NO_MEMORY;
1230 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1231 if (!NT_STATUS_IS_OK(disp_ret))
1232 return disp_ret;
1233 break;
1235 default:
1236 ctr->sam.info = NULL;
1237 return NT_STATUS_INVALID_INFO_CLASS;
1240 /* calculate the total size */
1241 total_data_size=num_account*struct_size;
1243 if (enum_context+max_entries < num_account)
1244 r_u->status = STATUS_MORE_ENTRIES;
1246 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1248 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1250 return r_u->status;
1254 /*******************************************************************
1255 samr_reply_query_aliasinfo
1256 ********************************************************************/
1258 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1260 DOM_SID sid;
1261 struct acct_info info;
1262 uint32 acc_granted;
1263 BOOL ret;
1265 r_u->status = NT_STATUS_OK;
1267 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1269 /* find the policy handle. open a policy on it. */
1270 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1271 return NT_STATUS_INVALID_HANDLE;
1272 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1273 return r_u->status;
1276 become_root();
1277 ret = pdb_get_aliasinfo(&sid, &info);
1278 unbecome_root();
1280 if ( !ret )
1281 return NT_STATUS_NO_SUCH_ALIAS;
1283 switch (q_u->switch_level) {
1284 case 1:
1285 r_u->ptr = 1;
1286 r_u->ctr.switch_value1 = 1;
1287 init_samr_alias_info1(&r_u->ctr.alias.info1,
1288 info.acct_name, 1, info.acct_desc);
1289 break;
1290 case 3:
1291 r_u->ptr = 1;
1292 r_u->ctr.switch_value1 = 3;
1293 init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1294 break;
1295 default:
1296 return NT_STATUS_INVALID_INFO_CLASS;
1299 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1301 return r_u->status;
1304 #if 0
1305 /*******************************************************************
1306 samr_reply_lookup_ids
1307 ********************************************************************/
1309 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1311 uint32 rid[MAX_SAM_ENTRIES];
1312 int num_rids = q_u->num_sids1;
1314 r_u->status = NT_STATUS_OK;
1316 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1318 if (num_rids > MAX_SAM_ENTRIES) {
1319 num_rids = MAX_SAM_ENTRIES;
1320 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1323 #if 0
1324 int i;
1325 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1327 for (i = 0; i < num_rids && status == 0; i++)
1329 struct sam_passwd *sam_pass;
1330 fstring user_name;
1333 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1334 q_u->uni_user_name[i].uni_str_len));
1336 /* find the user account */
1337 become_root();
1338 sam_pass = get_smb21pwd_entry(user_name, 0);
1339 unbecome_root();
1341 if (sam_pass == NULL)
1343 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1344 rid[i] = 0;
1346 else
1348 rid[i] = sam_pass->user_rid;
1351 #endif
1353 num_rids = 1;
1354 rid[0] = BUILTIN_ALIAS_RID_USERS;
1356 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1358 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1360 return r_u->status;
1362 #endif
1364 /*******************************************************************
1365 _samr_lookup_names
1366 ********************************************************************/
1368 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1370 uint32 rid[MAX_SAM_ENTRIES];
1371 uint32 local_rid;
1372 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1373 enum SID_NAME_USE local_type;
1374 int i;
1375 int num_rids = q_u->num_names2;
1376 DOM_SID pol_sid;
1377 fstring sid_str;
1378 uint32 acc_granted;
1380 r_u->status = NT_STATUS_OK;
1382 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1384 ZERO_ARRAY(rid);
1385 ZERO_ARRAY(type);
1387 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1388 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1389 return r_u->status;
1392 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 */
1393 return r_u->status;
1396 if (num_rids > MAX_SAM_ENTRIES) {
1397 num_rids = MAX_SAM_ENTRIES;
1398 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1401 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1403 for (i = 0; i < num_rids; i++) {
1404 fstring name;
1405 DOM_SID sid;
1406 int ret;
1408 r_u->status = NT_STATUS_NONE_MAPPED;
1410 rid [i] = 0xffffffff;
1411 type[i] = SID_NAME_UNKNOWN;
1413 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1416 * we are only looking for a name
1417 * the SID we get back can be outside
1418 * the scope of the pol_sid
1420 * in clear: it prevents to reply to domain\group: yes
1421 * when only builtin\group exists.
1423 * a cleaner code is to add the sid of the domain we're looking in
1424 * to the local_lookup_name function.
1427 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1428 sid_split_rid(&sid, &local_rid);
1430 if (sid_equal(&sid, &pol_sid)) {
1431 rid[i]=local_rid;
1433 /* Windows does not return WKN_GRP here, even
1434 * on lookups in builtin */
1435 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1436 SID_NAME_ALIAS : local_type;
1438 r_u->status = NT_STATUS_OK;
1443 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1445 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1447 return r_u->status;
1450 /*******************************************************************
1451 _samr_chgpasswd_user
1452 ********************************************************************/
1454 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1456 fstring user_name;
1457 fstring wks;
1459 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1461 r_u->status = NT_STATUS_OK;
1463 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1464 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1466 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1469 * Pass the user through the NT -> unix user mapping
1470 * function.
1473 (void)map_username(user_name);
1476 * UNIX username case mangling not required, pass_oem_change
1477 * is case insensitive.
1480 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1481 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1483 init_samr_r_chgpasswd_user(r_u, r_u->status);
1485 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1487 return r_u->status;
1490 /*******************************************************************
1491 makes a SAMR_R_LOOKUP_RIDS structure.
1492 ********************************************************************/
1494 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1495 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1497 uint32 i;
1498 UNIHDR *hdr_name=NULL;
1499 UNISTR2 *uni_name=NULL;
1501 *pp_uni_name = NULL;
1502 *pp_hdr_name = NULL;
1504 if (num_names != 0) {
1505 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1506 if (hdr_name == NULL)
1507 return False;
1509 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1510 if (uni_name == NULL)
1511 return False;
1514 for (i = 0; i < num_names; i++) {
1515 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1516 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1517 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1520 *pp_uni_name = uni_name;
1521 *pp_hdr_name = hdr_name;
1523 return True;
1526 /*******************************************************************
1527 _samr_lookup_rids
1528 ********************************************************************/
1530 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1532 fstring group_names[MAX_SAM_ENTRIES];
1533 uint32 *group_attrs = NULL;
1534 UNIHDR *hdr_name = NULL;
1535 UNISTR2 *uni_name = NULL;
1536 DOM_SID pol_sid;
1537 int num_rids = q_u->num_rids1;
1538 int i;
1539 uint32 acc_granted;
1541 r_u->status = NT_STATUS_OK;
1543 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1545 /* find the policy handle. open a policy on it. */
1546 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1547 return NT_STATUS_INVALID_HANDLE;
1549 if (num_rids > MAX_SAM_ENTRIES) {
1550 num_rids = MAX_SAM_ENTRIES;
1551 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1554 if (num_rids) {
1555 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1556 return NT_STATUS_NO_MEMORY;
1559 r_u->status = NT_STATUS_NONE_MAPPED;
1561 become_root(); /* lookup_sid can require root privs */
1563 for (i = 0; i < num_rids; i++) {
1564 fstring tmpname;
1565 fstring domname;
1566 DOM_SID sid;
1567 enum SID_NAME_USE type;
1569 group_attrs[i] = SID_NAME_UNKNOWN;
1570 *group_names[i] = '\0';
1572 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1573 sid_copy(&sid, &pol_sid);
1574 sid_append_rid(&sid, q_u->rid[i]);
1576 if (lookup_sid(&sid, domname, tmpname, &type)) {
1577 r_u->status = NT_STATUS_OK;
1578 group_attrs[i] = (uint32)type;
1579 fstrcpy(group_names[i],tmpname);
1580 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1585 unbecome_root();
1587 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1588 return NT_STATUS_NO_MEMORY;
1590 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1592 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1594 return r_u->status;
1597 /*******************************************************************
1598 _samr_open_user. Safe - gives out no passwd info.
1599 ********************************************************************/
1601 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1603 SAM_ACCOUNT *sampass=NULL;
1604 DOM_SID sid;
1605 POLICY_HND domain_pol = q_u->domain_pol;
1606 POLICY_HND *user_pol = &r_u->user_pol;
1607 struct samr_info *info = NULL;
1608 SEC_DESC *psd = NULL;
1609 uint32 acc_granted;
1610 uint32 des_access = q_u->access_mask;
1611 size_t sd_size;
1612 BOOL ret;
1613 NTSTATUS nt_status;
1615 r_u->status = NT_STATUS_OK;
1617 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1618 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1619 return NT_STATUS_INVALID_HANDLE;
1621 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1622 return nt_status;
1625 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1626 if (!NT_STATUS_IS_OK(nt_status)) {
1627 return nt_status;
1630 /* append the user's RID to it */
1631 if (!sid_append_rid(&sid, q_u->user_rid))
1632 return NT_STATUS_NO_SUCH_USER;
1634 /* check if access can be granted as requested by client. */
1635 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1636 se_map_generic(&des_access, &usr_generic_mapping);
1637 if (!NT_STATUS_IS_OK(nt_status =
1638 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1639 des_access, &acc_granted, "_samr_open_user"))) {
1640 return nt_status;
1643 become_root();
1644 ret=pdb_getsampwsid(sampass, &sid);
1645 unbecome_root();
1647 /* check that the SID exists in our domain. */
1648 if (ret == False) {
1649 return NT_STATUS_NO_SUCH_USER;
1652 pdb_free_sam(&sampass);
1654 /* associate the user's SID and access bits with the new handle. */
1655 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1656 return NT_STATUS_NO_MEMORY;
1657 info->acc_granted = acc_granted;
1659 /* get a (unique) handle. open a policy on it. */
1660 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1661 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1663 return r_u->status;
1666 /*************************************************************************
1667 get_user_info_10. Safe. Only gives out acb bits.
1668 *************************************************************************/
1670 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1672 SAM_ACCOUNT *smbpass=NULL;
1673 BOOL ret;
1674 NTSTATUS nt_status;
1676 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1678 if (!NT_STATUS_IS_OK(nt_status)) {
1679 return nt_status;
1682 become_root();
1683 ret = pdb_getsampwsid(smbpass, user_sid);
1684 unbecome_root();
1686 if (ret==False) {
1687 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1688 return NT_STATUS_NO_SUCH_USER;
1691 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1693 ZERO_STRUCTP(id10);
1694 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1696 pdb_free_sam(&smbpass);
1698 return NT_STATUS_OK;
1701 /*************************************************************************
1702 get_user_info_12. OK - this is the killer as it gives out password info.
1703 Ensure that this is only allowed on an encrypted connection with a root
1704 user. JRA.
1705 *************************************************************************/
1707 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1709 SAM_ACCOUNT *smbpass=NULL;
1710 BOOL ret;
1711 NTSTATUS nt_status;
1713 if (!p->ntlmssp_auth_validated)
1714 return NT_STATUS_ACCESS_DENIED;
1716 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1717 return NT_STATUS_ACCESS_DENIED;
1720 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1723 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1725 if (!NT_STATUS_IS_OK(nt_status)) {
1726 return nt_status;
1729 ret = pdb_getsampwsid(smbpass, user_sid);
1731 if (ret == False) {
1732 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1733 pdb_free_sam(&smbpass);
1734 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1737 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1739 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1740 pdb_free_sam(&smbpass);
1741 return NT_STATUS_ACCOUNT_DISABLED;
1744 ZERO_STRUCTP(id12);
1745 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1747 pdb_free_sam(&smbpass);
1749 return NT_STATUS_OK;
1752 /*************************************************************************
1753 get_user_info_20
1754 *************************************************************************/
1756 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1758 SAM_ACCOUNT *sampass=NULL;
1759 BOOL ret;
1761 pdb_init_sam_talloc(mem_ctx, &sampass);
1763 become_root();
1764 ret = pdb_getsampwsid(sampass, user_sid);
1765 unbecome_root();
1767 if (ret == False) {
1768 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1769 return NT_STATUS_NO_SUCH_USER;
1772 samr_clear_sam_passwd(sampass);
1774 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1776 ZERO_STRUCTP(id20);
1777 init_sam_user_info20A(id20, sampass);
1779 pdb_free_sam(&sampass);
1781 return NT_STATUS_OK;
1784 /*************************************************************************
1785 get_user_info_21
1786 *************************************************************************/
1788 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1789 DOM_SID *user_sid, DOM_SID *domain_sid)
1791 SAM_ACCOUNT *sampass=NULL;
1792 BOOL ret;
1793 NTSTATUS nt_status;
1795 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1796 if (!NT_STATUS_IS_OK(nt_status)) {
1797 return nt_status;
1800 become_root();
1801 ret = pdb_getsampwsid(sampass, user_sid);
1802 unbecome_root();
1804 if (ret == False) {
1805 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1806 return NT_STATUS_NO_SUCH_USER;
1809 samr_clear_sam_passwd(sampass);
1811 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1813 ZERO_STRUCTP(id21);
1814 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1816 pdb_free_sam(&sampass);
1818 return NT_STATUS_OK;
1821 /*******************************************************************
1822 _samr_query_userinfo
1823 ********************************************************************/
1825 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1827 SAM_USERINFO_CTR *ctr;
1828 struct samr_info *info = NULL;
1829 DOM_SID domain_sid;
1830 uint32 rid;
1832 r_u->status=NT_STATUS_OK;
1834 /* search for the handle */
1835 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1836 return NT_STATUS_INVALID_HANDLE;
1838 domain_sid = info->sid;
1840 sid_split_rid(&domain_sid, &rid);
1842 if (!sid_check_is_in_our_domain(&info->sid))
1843 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1845 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1847 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1848 if (!ctr)
1849 return NT_STATUS_NO_MEMORY;
1851 ZERO_STRUCTP(ctr);
1853 /* ok! user info levels (lots: see MSDEV help), off we go... */
1854 ctr->switch_value = q_u->switch_value;
1856 switch (q_u->switch_value) {
1857 case 0x10:
1858 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1859 if (ctr->info.id10 == NULL)
1860 return NT_STATUS_NO_MEMORY;
1862 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1863 return r_u->status;
1864 break;
1866 #if 0
1867 /* whoops - got this wrong. i think. or don't understand what's happening. */
1868 case 0x11:
1870 NTTIME expire;
1871 info = (void *)&id11;
1873 expire.low = 0xffffffff;
1874 expire.high = 0x7fffffff;
1876 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1877 sizeof
1878 (*ctr->
1879 info.
1880 id11));
1881 ZERO_STRUCTP(ctr->info.id11);
1882 init_sam_user_info11(ctr->info.id11, &expire,
1883 "BROOKFIELDS$", /* name */
1884 0x03ef, /* user rid */
1885 0x201, /* group rid */
1886 0x0080); /* acb info */
1888 break;
1890 #endif
1892 case 0x12:
1893 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1894 if (ctr->info.id12 == NULL)
1895 return NT_STATUS_NO_MEMORY;
1897 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1898 return r_u->status;
1899 break;
1901 case 20:
1902 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1903 if (ctr->info.id20 == NULL)
1904 return NT_STATUS_NO_MEMORY;
1905 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1906 return r_u->status;
1907 break;
1909 case 21:
1910 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1911 if (ctr->info.id21 == NULL)
1912 return NT_STATUS_NO_MEMORY;
1913 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1914 &info->sid, &domain_sid)))
1915 return r_u->status;
1916 break;
1918 default:
1919 return NT_STATUS_INVALID_INFO_CLASS;
1922 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1924 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1926 return r_u->status;
1929 /*******************************************************************
1930 samr_reply_query_usergroups
1931 ********************************************************************/
1933 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1935 SAM_ACCOUNT *sam_pass=NULL;
1936 DOM_SID sid;
1937 DOM_GID *gids = NULL;
1938 int num_groups = 0;
1939 uint32 acc_granted;
1940 BOOL ret;
1943 * from the SID in the request:
1944 * we should send back the list of DOMAIN GROUPS
1945 * the user is a member of
1947 * and only the DOMAIN GROUPS
1948 * no ALIASES !!! neither aliases of the domain
1949 * nor aliases of the builtin SID
1951 * JFM, 12/2/2001
1954 r_u->status = NT_STATUS_OK;
1956 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1958 /* find the policy handle. open a policy on it. */
1959 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1960 return NT_STATUS_INVALID_HANDLE;
1962 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1963 return r_u->status;
1966 if (!sid_check_is_in_our_domain(&sid))
1967 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1969 pdb_init_sam(&sam_pass);
1971 become_root();
1972 ret = pdb_getsampwsid(sam_pass, &sid);
1973 unbecome_root();
1975 if (ret == False) {
1976 pdb_free_sam(&sam_pass);
1977 return NT_STATUS_NO_SUCH_USER;
1980 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
1981 pdb_free_sam(&sam_pass);
1982 return NT_STATUS_NO_SUCH_GROUP;
1985 /* construct the response. lkclXXXX: gids are not copied! */
1986 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1988 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1990 pdb_free_sam(&sam_pass);
1992 return r_u->status;
1995 /*******************************************************************
1996 _samr_query_dom_info
1997 ********************************************************************/
1999 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2001 struct samr_info *info = NULL;
2002 SAM_UNK_CTR *ctr;
2003 uint32 min_pass_len,pass_hist,flag;
2004 time_t u_expire, u_min_age;
2005 NTTIME nt_expire, nt_min_age;
2007 time_t u_lock_duration, u_reset_time;
2008 NTTIME nt_lock_duration, nt_reset_time;
2009 uint32 lockout;
2011 time_t u_logout;
2012 NTTIME nt_logout;
2014 uint32 account_policy_temp;
2016 uint32 num_users=0, num_groups=0, num_aliases=0;
2018 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2019 return NT_STATUS_NO_MEMORY;
2021 ZERO_STRUCTP(ctr);
2023 r_u->status = NT_STATUS_OK;
2025 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2027 /* find the policy handle. open a policy on it. */
2028 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2029 return NT_STATUS_INVALID_HANDLE;
2031 switch (q_u->switch_value) {
2032 case 0x01:
2034 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2035 min_pass_len = account_policy_temp;
2037 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2038 pass_hist = account_policy_temp;
2040 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2041 flag = account_policy_temp;
2043 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2044 u_expire = account_policy_temp;
2046 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2047 u_min_age = account_policy_temp;
2049 unix_to_nt_time_abs(&nt_expire, u_expire);
2050 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2052 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2053 flag, nt_expire, nt_min_age);
2054 break;
2055 case 0x02:
2056 become_root();
2057 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2058 unbecome_root();
2059 if (!NT_STATUS_IS_OK(r_u->status)) {
2060 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2061 return r_u->status;
2063 num_users=info->disp_info.num_user_account;
2064 free_samr_db(info);
2066 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2067 if (!NT_STATUS_IS_OK(r_u->status)) {
2068 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2069 return r_u->status;
2071 num_groups=info->disp_info.num_group_account;
2072 free_samr_db(info);
2074 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2075 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2076 num_users, num_groups, num_aliases);
2077 break;
2078 case 0x03:
2079 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2080 unix_to_nt_time_abs(&nt_logout, u_logout);
2082 init_unk_info3(&ctr->info.inf3, nt_logout);
2083 break;
2084 case 0x05:
2085 init_unk_info5(&ctr->info.inf5, global_myname());
2086 break;
2087 case 0x06:
2088 init_unk_info6(&ctr->info.inf6);
2089 break;
2090 case 0x07:
2091 init_unk_info7(&ctr->info.inf7);
2092 break;
2093 case 0x0c:
2094 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2095 u_lock_duration = account_policy_temp * 60;
2097 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2098 u_reset_time = account_policy_temp * 60;
2100 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2101 lockout = account_policy_temp;
2103 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2104 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2106 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2107 break;
2108 default:
2109 return NT_STATUS_INVALID_INFO_CLASS;
2112 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2114 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2116 return r_u->status;
2119 /*******************************************************************
2120 _samr_create_user
2121 Create an account, can be either a normal user or a machine.
2122 This funcion will need to be updated for bdc/domain trusts.
2123 ********************************************************************/
2125 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2127 SAM_ACCOUNT *sam_pass=NULL;
2128 fstring account;
2129 DOM_SID sid;
2130 pstring add_script;
2131 POLICY_HND dom_pol = q_u->domain_pol;
2132 UNISTR2 user_account = q_u->uni_name;
2133 uint16 acb_info = q_u->acb_info;
2134 POLICY_HND *user_pol = &r_u->user_pol;
2135 struct samr_info *info = NULL;
2136 BOOL ret;
2137 NTSTATUS nt_status;
2138 struct passwd *pw;
2139 uint32 acc_granted;
2140 SEC_DESC *psd;
2141 size_t sd_size;
2142 uint32 new_rid = 0;
2143 /* check this, when giving away 'add computer to domain' privs */
2144 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2146 /* Get the domain SID stored in the domain policy */
2147 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2148 return NT_STATUS_INVALID_HANDLE;
2150 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2151 return nt_status;
2154 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2155 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2156 this parameter is not an account type */
2157 return NT_STATUS_INVALID_PARAMETER;
2160 /* find the account: tell the caller if it exists.
2161 lkclXXXX i have *no* idea if this is a problem or not
2162 or even if you are supposed to construct a different
2163 reply if the account already exists...
2166 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2167 strlower_m(account);
2169 pdb_init_sam(&sam_pass);
2171 become_root();
2172 ret = pdb_getsampwnam(sam_pass, account);
2173 unbecome_root();
2174 if (ret == True) {
2175 /* this account exists: say so */
2176 pdb_free_sam(&sam_pass);
2177 return NT_STATUS_USER_EXISTS;
2180 pdb_free_sam(&sam_pass);
2183 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2184 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2185 * that only people with write access to the smbpasswd file will be able
2186 * to create a user. JRA.
2190 * add the user in the /etc/passwd file or the unix authority system.
2191 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2192 * a) local_password_change() checks for us if the /etc/passwd account really exists
2193 * b) smb_create_user() would return an error if the account already exists
2194 * and as it could return an error also if it can't create the account, it would be tricky.
2196 * So we go the easy way, only check after if the account exists.
2197 * JFM (2/3/2001), to clear any possible bad understanding (-:
2199 * We now have seperate script paramaters for adding users/machines so we
2200 * now have some sainity-checking to match.
2203 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2206 * we used to have code here that made sure the acb_info flags
2207 * matched with the users named (e.g. an account flags as a machine
2208 * trust account ended in '$'). It has been ifdef'd out for a long
2209 * time, so I replaced it with this comment. --jerry
2212 /* the passdb lookup has failed; check to see if we need to run the
2213 add user/machine script */
2215 pw = Get_Pwnam(account);
2217 /*********************************************************************
2218 * HEADS UP! If we have to create a new user account, we have to get
2219 * a new RID from somewhere. This used to be done by the passdb
2220 * backend. It has been moved into idmap now. Since idmap is now
2221 * wrapped up behind winbind, this means you have to run winbindd if you
2222 * want new accounts to get a new RID when "enable rid algorithm = no".
2223 * Tough. We now have a uniform way of allocating RIDs regardless
2224 * of what ever passdb backend people may use.
2225 * --jerry (2003-07-10)
2226 *********************************************************************/
2228 if ( !pw ) {
2230 * we can't check both the ending $ and the acb_info.
2232 * UserManager creates trust accounts (ending in $,
2233 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2234 * JFM, 11/29/2001
2236 if (account[strlen(account)-1] == '$')
2237 pstrcpy(add_script, lp_addmachine_script());
2238 else
2239 pstrcpy(add_script, lp_adduser_script());
2241 if (*add_script) {
2242 int add_ret;
2243 all_string_sub(add_script, "%u", account, sizeof(account));
2244 add_ret = smbrun(add_script,NULL);
2245 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2247 else /* no add user script -- ask winbindd to do it */
2249 if ( !winbind_create_user( account, &new_rid ) ) {
2250 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2251 account));
2257 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2259 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2260 return nt_status;
2262 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2264 if (!pdb_add_sam_account(sam_pass)) {
2265 pdb_free_sam(&sam_pass);
2266 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2267 account));
2268 return NT_STATUS_ACCESS_DENIED;
2271 /* Get the user's SID */
2272 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2274 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2275 se_map_generic(&des_access, &usr_generic_mapping);
2276 if (!NT_STATUS_IS_OK(nt_status =
2277 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2278 des_access, &acc_granted, "_samr_create_user"))) {
2279 return nt_status;
2282 /* associate the user's SID with the new handle. */
2283 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2284 pdb_free_sam(&sam_pass);
2285 return NT_STATUS_NO_MEMORY;
2288 ZERO_STRUCTP(info);
2289 info->sid = sid;
2290 info->acc_granted = acc_granted;
2292 /* get a (unique) handle. open a policy on it. */
2293 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2294 pdb_free_sam(&sam_pass);
2295 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2298 r_u->user_rid=pdb_get_user_rid(sam_pass);
2300 r_u->access_granted = acc_granted;
2302 pdb_free_sam(&sam_pass);
2304 return NT_STATUS_OK;
2307 /*******************************************************************
2308 samr_reply_connect_anon
2309 ********************************************************************/
2311 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2313 struct samr_info *info = NULL;
2314 uint32 des_access = q_u->access_mask;
2316 /* Access check */
2318 if (!pipe_access_check(p)) {
2319 DEBUG(3, ("access denied to samr_connect_anon\n"));
2320 r_u->status = NT_STATUS_ACCESS_DENIED;
2321 return r_u->status;
2324 /* set up the SAMR connect_anon response */
2326 r_u->status = NT_STATUS_OK;
2328 /* associate the user's SID with the new handle. */
2329 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2330 return NT_STATUS_NO_MEMORY;
2332 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2333 was observed from a win98 client trying to enumerate users (when configured
2334 user level access control on shares) --jerry */
2336 se_map_generic( &des_access, &sam_generic_mapping );
2337 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2339 info->status = q_u->unknown_0;
2341 /* get a (unique) handle. open a policy on it. */
2342 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2343 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2345 return r_u->status;
2348 /*******************************************************************
2349 samr_reply_connect
2350 ********************************************************************/
2352 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2354 struct samr_info *info = NULL;
2355 SEC_DESC *psd = NULL;
2356 uint32 acc_granted;
2357 uint32 des_access = q_u->access_mask;
2358 size_t sd_size;
2359 NTSTATUS nt_status;
2362 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2364 /* Access check */
2366 if (!pipe_access_check(p)) {
2367 DEBUG(3, ("access denied to samr_connect\n"));
2368 r_u->status = NT_STATUS_ACCESS_DENIED;
2369 return r_u->status;
2372 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2373 se_map_generic(&des_access, &sam_generic_mapping);
2374 if (!NT_STATUS_IS_OK(nt_status =
2375 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2376 des_access, &acc_granted, "_samr_connect"))) {
2377 return nt_status;
2380 r_u->status = NT_STATUS_OK;
2382 /* associate the user's SID and access granted with the new handle. */
2383 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2384 return NT_STATUS_NO_MEMORY;
2386 info->acc_granted = acc_granted;
2387 info->status = q_u->access_mask;
2389 /* get a (unique) handle. open a policy on it. */
2390 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2391 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2393 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2395 return r_u->status;
2398 /*******************************************************************
2399 samr_connect4
2400 ********************************************************************/
2402 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2404 struct samr_info *info = NULL;
2405 SEC_DESC *psd = NULL;
2406 uint32 acc_granted;
2407 uint32 des_access = q_u->access_mask;
2408 size_t sd_size;
2409 NTSTATUS nt_status;
2412 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2414 /* Access check */
2416 if (!pipe_access_check(p)) {
2417 DEBUG(3, ("access denied to samr_connect4\n"));
2418 r_u->status = NT_STATUS_ACCESS_DENIED;
2419 return r_u->status;
2422 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2423 se_map_generic(&des_access, &sam_generic_mapping);
2424 if (!NT_STATUS_IS_OK(nt_status =
2425 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2426 des_access, &acc_granted, "_samr_connect"))) {
2427 return nt_status;
2430 r_u->status = NT_STATUS_OK;
2432 /* associate the user's SID and access granted with the new handle. */
2433 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2434 return NT_STATUS_NO_MEMORY;
2436 info->acc_granted = acc_granted;
2437 info->status = q_u->access_mask;
2439 /* get a (unique) handle. open a policy on it. */
2440 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2441 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2443 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2445 return r_u->status;
2448 /**********************************************************************
2449 api_samr_lookup_domain
2450 **********************************************************************/
2452 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2454 struct samr_info *info;
2455 fstring domain_name;
2456 DOM_SID sid;
2458 r_u->status = NT_STATUS_OK;
2460 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2461 return NT_STATUS_INVALID_HANDLE;
2463 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2464 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2466 return r_u->status;
2469 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2471 ZERO_STRUCT(sid);
2473 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2474 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2477 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2479 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2481 return r_u->status;
2484 /******************************************************************
2485 makes a SAMR_R_ENUM_DOMAINS structure.
2486 ********************************************************************/
2488 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2489 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2491 uint32 i;
2492 SAM_ENTRY *sam;
2493 UNISTR2 *uni_name;
2495 DEBUG(5, ("make_enum_domains\n"));
2497 *pp_sam = NULL;
2498 *pp_uni_name = NULL;
2500 if (num_sam_entries == 0)
2501 return True;
2503 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2504 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2506 if (sam == NULL || uni_name == NULL)
2507 return False;
2509 for (i = 0; i < num_sam_entries; i++) {
2510 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2511 init_sam_entry(&sam[i], &uni_name[i], 0);
2514 *pp_sam = sam;
2515 *pp_uni_name = uni_name;
2517 return True;
2520 /**********************************************************************
2521 api_samr_enum_domains
2522 **********************************************************************/
2524 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2526 struct samr_info *info;
2527 uint32 num_entries = 2;
2528 fstring dom[2];
2529 const char *name;
2531 r_u->status = NT_STATUS_OK;
2533 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2534 return NT_STATUS_INVALID_HANDLE;
2536 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2537 return r_u->status;
2540 name = get_global_sam_name();
2542 fstrcpy(dom[0],name);
2543 strupper_m(dom[0]);
2544 fstrcpy(dom[1],"Builtin");
2546 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2547 return NT_STATUS_NO_MEMORY;
2549 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2551 return r_u->status;
2554 /*******************************************************************
2555 api_samr_open_alias
2556 ********************************************************************/
2558 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2560 DOM_SID sid;
2561 POLICY_HND domain_pol = q_u->dom_pol;
2562 uint32 alias_rid = q_u->rid_alias;
2563 POLICY_HND *alias_pol = &r_u->pol;
2564 struct samr_info *info = NULL;
2565 SEC_DESC *psd = NULL;
2566 uint32 acc_granted;
2567 uint32 des_access = q_u->access_mask;
2568 size_t sd_size;
2569 NTSTATUS status;
2571 r_u->status = NT_STATUS_OK;
2573 /* find the domain policy and get the SID / access bits stored in the domain policy */
2574 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2575 return NT_STATUS_INVALID_HANDLE;
2577 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2578 return status;
2581 /* append the alias' RID to it */
2582 if (!sid_append_rid(&sid, alias_rid))
2583 return NT_STATUS_NO_SUCH_USER;
2585 /*check if access can be granted as requested by client. */
2586 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2587 se_map_generic(&des_access,&ali_generic_mapping);
2588 if (!NT_STATUS_IS_OK(status =
2589 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2590 des_access, &acc_granted, "_samr_open_alias"))) {
2591 return status;
2595 * we should check if the rid really exist !!!
2596 * JFM.
2599 /* associate the user's SID with the new handle. */
2600 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2601 return NT_STATUS_NO_MEMORY;
2603 info->acc_granted = acc_granted;
2605 /* get a (unique) handle. open a policy on it. */
2606 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2607 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2609 return r_u->status;
2612 /*******************************************************************
2613 set_user_info_10
2614 ********************************************************************/
2616 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2618 SAM_ACCOUNT *pwd =NULL;
2619 BOOL ret;
2621 pdb_init_sam(&pwd);
2623 ret = pdb_getsampwsid(pwd, sid);
2625 if(ret==False) {
2626 pdb_free_sam(&pwd);
2627 return False;
2630 if (id10 == NULL) {
2631 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2632 pdb_free_sam(&pwd);
2633 return False;
2636 /* FIX ME: check if the value is really changed --metze */
2637 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2638 pdb_free_sam(&pwd);
2639 return False;
2642 if(!pdb_update_sam_account(pwd)) {
2643 pdb_free_sam(&pwd);
2644 return False;
2647 pdb_free_sam(&pwd);
2649 return True;
2652 /*******************************************************************
2653 set_user_info_12
2654 ********************************************************************/
2656 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2658 SAM_ACCOUNT *pwd = NULL;
2660 pdb_init_sam(&pwd);
2662 if(!pdb_getsampwsid(pwd, sid)) {
2663 pdb_free_sam(&pwd);
2664 return False;
2667 if (id12 == NULL) {
2668 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2669 pdb_free_sam(&pwd);
2670 return False;
2673 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2674 pdb_free_sam(&pwd);
2675 return False;
2677 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2678 pdb_free_sam(&pwd);
2679 return False;
2681 if (!pdb_set_pass_changed_now (pwd)) {
2682 pdb_free_sam(&pwd);
2683 return False;
2686 if(!pdb_update_sam_account(pwd)) {
2687 pdb_free_sam(&pwd);
2688 return False;
2691 pdb_free_sam(&pwd);
2692 return True;
2695 /*******************************************************************
2696 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2697 ********************************************************************/
2698 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2700 struct group *grp;
2701 gid_t gid;
2703 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2704 &gid))) {
2705 DEBUG(2,("Could not get gid for primary group of "
2706 "user %s\n", pdb_get_username(sampass)));
2707 return False;
2710 grp = getgrgid(gid);
2712 if (grp == NULL) {
2713 DEBUG(2,("Could not find primary group %lu for "
2714 "user %s\n", (unsigned long)gid,
2715 pdb_get_username(sampass)));
2716 return False;
2719 if (smb_set_primary_group(grp->gr_name,
2720 pdb_get_username(sampass)) != 0) {
2721 DEBUG(2,("Could not set primary group for user %s to "
2722 "%s\n",
2723 pdb_get_username(sampass), grp->gr_name));
2724 return False;
2727 return True;
2731 /*******************************************************************
2732 set_user_info_20
2733 ********************************************************************/
2735 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2737 SAM_ACCOUNT *pwd = NULL;
2739 if (id20 == NULL) {
2740 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2741 return False;
2744 pdb_init_sam(&pwd);
2746 if (!pdb_getsampwsid(pwd, sid)) {
2747 pdb_free_sam(&pwd);
2748 return False;
2751 copy_id20_to_sam_passwd(pwd, id20);
2753 /* write the change out */
2754 if(!pdb_update_sam_account(pwd)) {
2755 pdb_free_sam(&pwd);
2756 return False;
2759 pdb_free_sam(&pwd);
2761 return True;
2763 /*******************************************************************
2764 set_user_info_21
2765 ********************************************************************/
2767 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2769 SAM_ACCOUNT *pwd = NULL;
2771 if (id21 == NULL) {
2772 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2773 return False;
2776 pdb_init_sam(&pwd);
2778 if (!pdb_getsampwsid(pwd, sid)) {
2779 pdb_free_sam(&pwd);
2780 return False;
2783 copy_id21_to_sam_passwd(pwd, id21);
2786 * The funny part about the previous two calls is
2787 * that pwd still has the password hashes from the
2788 * passdb entry. These have not been updated from
2789 * id21. I don't know if they need to be set. --jerry
2792 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2793 set_unix_primary_group(pwd);
2795 /* write the change out */
2796 if(!pdb_update_sam_account(pwd)) {
2797 pdb_free_sam(&pwd);
2798 return False;
2801 pdb_free_sam(&pwd);
2803 return True;
2806 /*******************************************************************
2807 set_user_info_23
2808 ********************************************************************/
2810 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2812 SAM_ACCOUNT *pwd = NULL;
2813 pstring plaintext_buf;
2814 uint32 len;
2815 uint16 acct_ctrl;
2817 if (id23 == NULL) {
2818 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2819 return False;
2822 pdb_init_sam(&pwd);
2824 if (!pdb_getsampwsid(pwd, sid)) {
2825 pdb_free_sam(&pwd);
2826 return False;
2829 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2830 pdb_get_username(pwd)));
2832 acct_ctrl = pdb_get_acct_ctrl(pwd);
2834 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2835 pdb_free_sam(&pwd);
2836 return False;
2839 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2840 pdb_free_sam(&pwd);
2841 return False;
2844 copy_id23_to_sam_passwd(pwd, id23);
2846 /* if it's a trust account, don't update /etc/passwd */
2847 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2848 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2849 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2850 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2851 } else {
2852 /* update the UNIX password */
2853 if (lp_unix_password_sync() ) {
2854 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2855 if (!passwd) {
2856 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2859 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2860 pdb_free_sam(&pwd);
2861 return False;
2866 ZERO_STRUCT(plaintext_buf);
2868 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2869 set_unix_primary_group(pwd);
2871 if(!pdb_update_sam_account(pwd)) {
2872 pdb_free_sam(&pwd);
2873 return False;
2876 pdb_free_sam(&pwd);
2878 return True;
2881 /*******************************************************************
2882 set_user_info_pw
2883 ********************************************************************/
2885 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2887 SAM_ACCOUNT *pwd = NULL;
2888 uint32 len;
2889 pstring plaintext_buf;
2890 uint16 acct_ctrl;
2892 pdb_init_sam(&pwd);
2894 if (!pdb_getsampwsid(pwd, sid)) {
2895 pdb_free_sam(&pwd);
2896 return False;
2899 DEBUG(5, ("Attempting administrator password change for user %s\n",
2900 pdb_get_username(pwd)));
2902 acct_ctrl = pdb_get_acct_ctrl(pwd);
2904 ZERO_STRUCT(plaintext_buf);
2906 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2907 pdb_free_sam(&pwd);
2908 return False;
2911 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2912 pdb_free_sam(&pwd);
2913 return False;
2916 /* if it's a trust account, don't update /etc/passwd */
2917 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2918 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2919 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2920 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2921 } else {
2922 /* update the UNIX password */
2923 if (lp_unix_password_sync()) {
2924 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2925 if (!passwd) {
2926 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2929 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2930 pdb_free_sam(&pwd);
2931 return False;
2936 ZERO_STRUCT(plaintext_buf);
2938 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2940 /* update the SAMBA password */
2941 if(!pdb_update_sam_account(pwd)) {
2942 pdb_free_sam(&pwd);
2943 return False;
2946 pdb_free_sam(&pwd);
2948 return True;
2951 /*******************************************************************
2952 samr_reply_set_userinfo
2953 ********************************************************************/
2955 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2957 DOM_SID sid;
2958 POLICY_HND *pol = &q_u->pol;
2959 uint16 switch_value = q_u->switch_value;
2960 SAM_USERINFO_CTR *ctr = q_u->ctr;
2961 uint32 acc_granted;
2962 uint32 acc_required;
2964 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2966 r_u->status = NT_STATUS_OK;
2968 /* find the policy handle. open a policy on it. */
2969 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2970 return NT_STATUS_INVALID_HANDLE;
2972 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2973 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2974 return r_u->status;
2977 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2979 if (ctr == NULL) {
2980 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2981 return NT_STATUS_INVALID_INFO_CLASS;
2984 /* ok! user info levels (lots: see MSDEV help), off we go... */
2985 switch (switch_value) {
2986 case 0x12:
2987 if (!set_user_info_12(ctr->info.id12, &sid))
2988 return NT_STATUS_ACCESS_DENIED;
2989 break;
2991 case 24:
2992 if (!p->session_key.length) {
2993 return NT_STATUS_NO_USER_SESSION_KEY;
2995 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
2997 dump_data(100, (char *)ctr->info.id24->pass, 516);
2999 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3000 return NT_STATUS_ACCESS_DENIED;
3001 break;
3003 case 25:
3004 #if 0
3006 * Currently we don't really know how to unmarshall
3007 * the level 25 struct, and the password encryption
3008 * is different. This is a placeholder for when we
3009 * do understand it. In the meantime just return INVALID
3010 * info level and W2K SP2 drops down to level 23... JRA.
3013 if (!p->session_key.length) {
3014 return NT_STATUS_NO_USER_SESSION_KEY;
3016 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3018 dump_data(100, (char *)ctr->info.id25->pass, 532);
3020 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3021 return NT_STATUS_ACCESS_DENIED;
3022 break;
3023 #endif
3024 return NT_STATUS_INVALID_INFO_CLASS;
3026 case 23:
3027 if (!p->session_key.length) {
3028 return NT_STATUS_NO_USER_SESSION_KEY;
3030 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3032 dump_data(100, (char *)ctr->info.id23->pass, 516);
3034 if (!set_user_info_23(ctr->info.id23, &sid))
3035 return NT_STATUS_ACCESS_DENIED;
3036 break;
3038 default:
3039 return NT_STATUS_INVALID_INFO_CLASS;
3042 return r_u->status;
3045 /*******************************************************************
3046 samr_reply_set_userinfo2
3047 ********************************************************************/
3049 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3051 DOM_SID sid;
3052 SAM_USERINFO_CTR *ctr = q_u->ctr;
3053 POLICY_HND *pol = &q_u->pol;
3054 uint16 switch_value = q_u->switch_value;
3055 uint32 acc_granted;
3056 uint32 acc_required;
3058 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3060 r_u->status = NT_STATUS_OK;
3062 /* find the policy handle. open a policy on it. */
3063 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3064 return NT_STATUS_INVALID_HANDLE;
3066 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3067 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3068 return r_u->status;
3071 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3073 if (ctr == NULL) {
3074 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3075 return NT_STATUS_INVALID_INFO_CLASS;
3078 switch_value=ctr->switch_value;
3080 /* ok! user info levels (lots: see MSDEV help), off we go... */
3081 switch (switch_value) {
3082 case 21:
3083 if (!set_user_info_21(ctr->info.id21, &sid))
3084 return NT_STATUS_ACCESS_DENIED;
3085 break;
3086 case 20:
3087 if (!set_user_info_20(ctr->info.id20, &sid))
3088 return NT_STATUS_ACCESS_DENIED;
3089 break;
3090 case 16:
3091 if (!set_user_info_10(ctr->info.id10, &sid))
3092 return NT_STATUS_ACCESS_DENIED;
3093 break;
3094 case 18:
3095 /* Used by AS/U JRA. */
3096 if (!set_user_info_12(ctr->info.id12, &sid))
3097 return NT_STATUS_ACCESS_DENIED;
3098 break;
3099 default:
3100 return NT_STATUS_INVALID_INFO_CLASS;
3103 return r_u->status;
3106 /*********************************************************************
3107 _samr_query_aliasmem
3108 *********************************************************************/
3110 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3112 int num_groups = 0, tmp_num_groups=0;
3113 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3114 struct samr_info *info = NULL;
3115 int i,j;
3117 NTSTATUS ntstatus1;
3118 NTSTATUS ntstatus2;
3120 /* until i see a real useraliases query, we fack one up */
3122 /* I have seen one, JFM 2/12/2001 */
3124 * Explanation of what this call does:
3125 * for all the SID given in the request:
3126 * return a list of alias (local groups)
3127 * that have those SID as members.
3129 * and that's the alias in the domain specified
3130 * in the policy_handle
3132 * if the policy handle is on an incorrect sid
3133 * for example a user's sid
3134 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3137 r_u->status = NT_STATUS_OK;
3139 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3141 /* find the policy handle. open a policy on it. */
3142 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3143 return NT_STATUS_INVALID_HANDLE;
3145 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3146 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3148 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3149 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3150 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3151 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3155 if (!sid_check_is_domain(&info->sid) &&
3156 !sid_check_is_builtin(&info->sid))
3157 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3160 for (i=0; i<q_u->num_sids1; i++) {
3162 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3165 * if there is an error, we just continue as
3166 * it can be an unfound user or group
3168 if (!NT_STATUS_IS_OK(r_u->status)) {
3169 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3170 continue;
3173 if (tmp_num_groups==0) {
3174 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3175 continue;
3178 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3179 if (new_rids==NULL) {
3180 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3181 return NT_STATUS_NO_MEMORY;
3183 rids=new_rids;
3185 for (j=0; j<tmp_num_groups; j++)
3186 rids[j+num_groups]=tmp_rids[j];
3188 safe_free(tmp_rids);
3190 num_groups+=tmp_num_groups;
3193 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3194 return NT_STATUS_OK;
3197 /*********************************************************************
3198 _samr_query_aliasmem
3199 *********************************************************************/
3201 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3203 int i;
3205 int num_sids = 0;
3206 DOM_SID2 *sid;
3207 DOM_SID *sids=NULL;
3209 DOM_SID alias_sid;
3211 uint32 acc_granted;
3213 /* find the policy handle. open a policy on it. */
3214 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3215 return NT_STATUS_INVALID_HANDLE;
3217 if (!NT_STATUS_IS_OK(r_u->status =
3218 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3219 return r_u->status;
3222 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3224 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3225 return NT_STATUS_NO_SUCH_ALIAS;
3227 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_sids);
3228 if (num_sids!=0 && sid == NULL) {
3229 SAFE_FREE(sids);
3230 return NT_STATUS_NO_MEMORY;
3233 for (i = 0; i < num_sids; i++) {
3234 init_dom_sid2(&sid[i], &sids[i]);
3237 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3239 SAFE_FREE(sids);
3241 return NT_STATUS_OK;
3244 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3246 int i;
3248 for (i=0; i<*num; i++) {
3249 if ((*uids)[i] == uid)
3250 return;
3253 *uids = Realloc(*uids, (*num+1) * sizeof(uid_t));
3255 if (*uids == NULL)
3256 return;
3258 (*uids)[*num] = uid;
3259 *num += 1;
3263 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3265 struct group *grp;
3266 char **gr;
3267 struct sys_pwent *userlist, *user;
3269 *uids = NULL;
3270 *num = 0;
3272 /* We only look at our own sam, so don't care about imported stuff */
3274 winbind_off();
3276 if ((grp = getgrgid(gid)) == NULL) {
3277 winbind_on();
3278 return False;
3281 /* Primary group members */
3283 userlist = getpwent_list();
3285 for (user = userlist; user != NULL; user = user->next) {
3286 if (user->pw_gid != gid)
3287 continue;
3288 add_uid_to_array_unique(user->pw_uid, uids, num);
3291 pwent_free(userlist);
3293 /* Secondary group members */
3295 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3296 struct passwd *pw = getpwnam(*gr);
3298 if (pw == NULL)
3299 continue;
3300 add_uid_to_array_unique(pw->pw_uid, uids, num);
3303 winbind_on();
3305 return True;
3308 /*********************************************************************
3309 _samr_query_groupmem
3310 *********************************************************************/
3312 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3314 int final_num_rids, i;
3315 DOM_SID group_sid;
3316 fstring group_sid_str;
3317 uid_t *uids;
3318 int num;
3319 gid_t gid;
3321 uint32 *rid=NULL;
3322 uint32 *attr=NULL;
3324 uint32 acc_granted;
3326 /* find the policy handle. open a policy on it. */
3327 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3328 return NT_STATUS_INVALID_HANDLE;
3330 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3331 return r_u->status;
3334 sid_to_string(group_sid_str, &group_sid);
3335 DEBUG(10, ("sid is %s\n", group_sid_str));
3337 if (!sid_check_is_in_our_domain(&group_sid)) {
3338 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3339 return NT_STATUS_NO_SUCH_GROUP;
3342 DEBUG(10, ("lookup on Domain SID\n"));
3344 if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3345 return NT_STATUS_NO_SUCH_GROUP;
3347 if(!get_memberuids(gid, &uids, &num))
3348 return NT_STATUS_NO_SUCH_GROUP;
3350 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
3351 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
3353 if (num!=0 && (rid==NULL || attr==NULL))
3354 return NT_STATUS_NO_MEMORY;
3356 final_num_rids = 0;
3358 for (i=0; i<num; i++) {
3359 DOM_SID sid;
3361 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3362 DEBUG(1, ("Could not map member uid to SID\n"));
3363 continue;
3366 if (!sid_check_is_in_our_domain(&sid)) {
3367 DEBUG(1, ("Inconsistent SAM -- group member uid not "
3368 "in our domain\n"));
3369 continue;
3372 sid_peek_rid(&sid, &rid[final_num_rids]);
3374 /* Hmm. In a trace I got the constant 7 here from NT. */
3375 attr[final_num_rids] = SID_NAME_USER;
3377 final_num_rids += 1;
3380 SAFE_FREE(uids);
3382 init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3383 NT_STATUS_OK);
3385 return NT_STATUS_OK;
3388 /*********************************************************************
3389 _samr_add_aliasmem
3390 *********************************************************************/
3392 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3394 DOM_SID alias_sid;
3395 uint32 acc_granted;
3397 /* Find the policy handle. Open a policy on it. */
3398 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3399 return NT_STATUS_INVALID_HANDLE;
3401 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3402 return r_u->status;
3405 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3407 if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
3408 return NT_STATUS_ACCESS_DENIED;
3410 return NT_STATUS_OK;
3413 /*********************************************************************
3414 _samr_del_aliasmem
3415 *********************************************************************/
3417 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3419 DOM_SID alias_sid;
3420 uint32 acc_granted;
3422 /* Find the policy handle. Open a policy on it. */
3423 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3424 return NT_STATUS_INVALID_HANDLE;
3426 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3427 return r_u->status;
3430 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3431 sid_string_static(&alias_sid)));
3433 if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
3434 return NT_STATUS_ACCESS_DENIED;
3436 return NT_STATUS_OK;
3439 /*********************************************************************
3440 _samr_add_groupmem
3441 *********************************************************************/
3443 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3445 DOM_SID group_sid;
3446 DOM_SID user_sid;
3447 fstring group_sid_str;
3448 uid_t uid;
3449 struct passwd *pwd;
3450 struct group *grp;
3451 fstring grp_name;
3452 GROUP_MAP map;
3453 NTSTATUS ret;
3454 SAM_ACCOUNT *sam_user=NULL;
3455 BOOL check;
3456 uint32 acc_granted;
3458 /* Find the policy handle. Open a policy on it. */
3459 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3460 return NT_STATUS_INVALID_HANDLE;
3462 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3463 return r_u->status;
3466 sid_to_string(group_sid_str, &group_sid);
3467 DEBUG(10, ("sid is %s\n", group_sid_str));
3469 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3470 return NT_STATUS_NO_SUCH_GROUP;
3472 DEBUG(10, ("lookup on Domain SID\n"));
3474 if(!get_domain_group_from_sid(group_sid, &map))
3475 return NT_STATUS_NO_SUCH_GROUP;
3477 sid_copy(&user_sid, get_global_sam_sid());
3478 sid_append_rid(&user_sid, q_u->rid);
3480 ret = pdb_init_sam(&sam_user);
3481 if (!NT_STATUS_IS_OK(ret))
3482 return ret;
3484 check = pdb_getsampwsid(sam_user, &user_sid);
3486 if (check != True) {
3487 pdb_free_sam(&sam_user);
3488 return NT_STATUS_NO_SUCH_USER;
3491 /* check a real user exist before we run the script to add a user to a group */
3492 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3493 pdb_free_sam(&sam_user);
3494 return NT_STATUS_NO_SUCH_USER;
3497 pdb_free_sam(&sam_user);
3499 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3500 return NT_STATUS_NO_SUCH_USER;
3503 if ((grp=getgrgid(map.gid)) == NULL) {
3504 passwd_free(&pwd);
3505 return NT_STATUS_NO_SUCH_GROUP;
3508 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3509 fstrcpy(grp_name, grp->gr_name);
3511 /* if the user is already in the group */
3512 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3513 passwd_free(&pwd);
3514 return NT_STATUS_MEMBER_IN_GROUP;
3518 * ok, the group exist, the user exist, the user is not in the group,
3520 * we can (finally) add it to the group !
3523 smb_add_user_group(grp_name, pwd->pw_name);
3525 /* check if the user has been added then ... */
3526 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3527 passwd_free(&pwd);
3528 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3531 passwd_free(&pwd);
3532 return NT_STATUS_OK;
3535 /*********************************************************************
3536 _samr_del_groupmem
3537 *********************************************************************/
3539 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3541 DOM_SID group_sid;
3542 DOM_SID user_sid;
3543 SAM_ACCOUNT *sam_pass=NULL;
3544 GROUP_MAP map;
3545 fstring grp_name;
3546 struct group *grp;
3547 uint32 acc_granted;
3550 * delete the group member named q_u->rid
3551 * who is a member of the sid associated with the handle
3552 * the rid is a user's rid as the group is a domain group.
3555 /* Find the policy handle. Open a policy on it. */
3556 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3557 return NT_STATUS_INVALID_HANDLE;
3559 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3560 return r_u->status;
3563 if (!sid_check_is_in_our_domain(&group_sid))
3564 return NT_STATUS_NO_SUCH_GROUP;
3566 sid_copy(&user_sid, get_global_sam_sid());
3567 sid_append_rid(&user_sid, q_u->rid);
3569 if (!get_domain_group_from_sid(group_sid, &map))
3570 return NT_STATUS_NO_SUCH_GROUP;
3572 if ((grp=getgrgid(map.gid)) == NULL)
3573 return NT_STATUS_NO_SUCH_GROUP;
3575 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3576 fstrcpy(grp_name, grp->gr_name);
3578 /* check if the user exists before trying to remove it from the group */
3579 pdb_init_sam(&sam_pass);
3580 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3581 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3582 pdb_free_sam(&sam_pass);
3583 return NT_STATUS_NO_SUCH_USER;
3586 /* if the user is not in the group */
3587 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3588 pdb_free_sam(&sam_pass);
3589 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3592 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3594 /* check if the user has been removed then ... */
3595 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3596 pdb_free_sam(&sam_pass);
3597 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3600 pdb_free_sam(&sam_pass);
3601 return NT_STATUS_OK;
3605 /****************************************************************************
3606 Delete a UNIX user on demand.
3607 ****************************************************************************/
3609 static int smb_delete_user(const char *unix_user)
3611 pstring del_script;
3612 int ret;
3614 /* try winbindd first since it is impossible to determine where
3615 a user came from via NSS. Try the delete user script if this fails
3616 meaning the user did not exist in winbindd's list of accounts */
3618 if ( winbind_delete_user( unix_user ) ) {
3619 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3620 return 0;
3624 /* fall back to 'delete user script' */
3626 pstrcpy(del_script, lp_deluser_script());
3627 if (! *del_script)
3628 return -1;
3629 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3630 ret = smbrun(del_script,NULL);
3631 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3633 return ret;
3636 /*********************************************************************
3637 _samr_delete_dom_user
3638 *********************************************************************/
3640 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3642 DOM_SID user_sid;
3643 SAM_ACCOUNT *sam_pass=NULL;
3644 uint32 acc_granted;
3646 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3648 /* Find the policy handle. Open a policy on it. */
3649 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3650 return NT_STATUS_INVALID_HANDLE;
3652 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3653 return r_u->status;
3656 if (!sid_check_is_in_our_domain(&user_sid))
3657 return NT_STATUS_CANNOT_DELETE;
3659 /* check if the user exists before trying to delete */
3660 pdb_init_sam(&sam_pass);
3661 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3662 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3663 sid_string_static(&user_sid)));
3664 pdb_free_sam(&sam_pass);
3665 return NT_STATUS_NO_SUCH_USER;
3668 /* delete the unix side */
3670 * note: we don't check if the delete really happened
3671 * as the script is not necessary present
3672 * and maybe the sysadmin doesn't want to delete the unix side
3674 smb_delete_user(pdb_get_username(sam_pass));
3676 /* and delete the samba side */
3677 if (!pdb_delete_sam_account(sam_pass)) {
3678 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3679 pdb_free_sam(&sam_pass);
3680 return NT_STATUS_CANNOT_DELETE;
3683 pdb_free_sam(&sam_pass);
3685 if (!close_policy_hnd(p, &q_u->user_pol))
3686 return NT_STATUS_OBJECT_NAME_INVALID;
3688 return NT_STATUS_OK;
3691 /*********************************************************************
3692 _samr_delete_dom_group
3693 *********************************************************************/
3695 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3697 DOM_SID group_sid;
3698 DOM_SID dom_sid;
3699 uint32 group_rid;
3700 fstring group_sid_str;
3701 gid_t gid;
3702 struct group *grp;
3703 GROUP_MAP map;
3704 uint32 acc_granted;
3706 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3708 /* Find the policy handle. Open a policy on it. */
3709 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3710 return NT_STATUS_INVALID_HANDLE;
3712 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3713 return r_u->status;
3716 sid_copy(&dom_sid, &group_sid);
3717 sid_to_string(group_sid_str, &dom_sid);
3718 sid_split_rid(&dom_sid, &group_rid);
3720 DEBUG(10, ("sid is %s\n", group_sid_str));
3722 /* we check if it's our SID before deleting */
3723 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3724 return NT_STATUS_NO_SUCH_GROUP;
3726 DEBUG(10, ("lookup on Domain SID\n"));
3728 if(!get_domain_group_from_sid(group_sid, &map))
3729 return NT_STATUS_NO_SUCH_GROUP;
3731 gid=map.gid;
3733 /* check if group really exists */
3734 if ( (grp=getgrgid(gid)) == NULL)
3735 return NT_STATUS_NO_SUCH_GROUP;
3737 /* delete mapping first */
3738 if(!pdb_delete_group_mapping_entry(group_sid))
3739 return NT_STATUS_ACCESS_DENIED;
3741 /* we can delete the UNIX group */
3742 smb_delete_group(grp->gr_name);
3744 /* check if the group has been successfully deleted */
3745 if ( (grp=getgrgid(gid)) != NULL)
3746 return NT_STATUS_ACCESS_DENIED;
3749 if (!close_policy_hnd(p, &q_u->group_pol))
3750 return NT_STATUS_OBJECT_NAME_INVALID;
3752 return NT_STATUS_OK;
3755 /*********************************************************************
3756 _samr_delete_dom_alias
3757 *********************************************************************/
3759 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3761 DOM_SID alias_sid;
3762 uint32 acc_granted;
3764 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3766 /* Find the policy handle. Open a policy on it. */
3767 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3768 return NT_STATUS_INVALID_HANDLE;
3770 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3771 return r_u->status;
3774 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3776 if (!sid_check_is_in_our_domain(&alias_sid))
3777 return NT_STATUS_NO_SUCH_ALIAS;
3779 DEBUG(10, ("lookup on Local SID\n"));
3781 /* Have passdb delete the alias */
3782 if (!pdb_delete_alias(&alias_sid))
3783 return NT_STATUS_ACCESS_DENIED;
3785 if (!close_policy_hnd(p, &q_u->alias_pol))
3786 return NT_STATUS_OBJECT_NAME_INVALID;
3788 return NT_STATUS_OK;
3791 /*********************************************************************
3792 _samr_create_dom_group
3793 *********************************************************************/
3795 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3797 DOM_SID dom_sid;
3798 DOM_SID info_sid;
3799 fstring name;
3800 fstring sid_string;
3801 struct group *grp;
3802 struct samr_info *info;
3803 uint32 acc_granted;
3804 gid_t gid;
3806 /* Find the policy handle. Open a policy on it. */
3807 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3808 return NT_STATUS_INVALID_HANDLE;
3810 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3811 return r_u->status;
3814 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3815 return NT_STATUS_ACCESS_DENIED;
3817 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3819 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3821 /* check if group already exist */
3822 if ((grp=getgrnam(name)) != NULL)
3823 return NT_STATUS_GROUP_EXISTS;
3825 /* we can create the UNIX group */
3826 if (smb_create_group(name, &gid) != 0)
3827 return NT_STATUS_ACCESS_DENIED;
3829 /* check if the group has been successfully created */
3830 if ((grp=getgrgid(gid)) == NULL)
3831 return NT_STATUS_ACCESS_DENIED;
3833 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3835 /* add the group to the mapping table */
3836 sid_copy(&info_sid, get_global_sam_sid());
3837 sid_append_rid(&info_sid, r_u->rid);
3838 sid_to_string(sid_string, &info_sid);
3840 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3841 return NT_STATUS_ACCESS_DENIED;
3843 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3844 return NT_STATUS_NO_MEMORY;
3846 /* get a (unique) handle. open a policy on it. */
3847 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3848 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3850 return NT_STATUS_OK;
3853 /*********************************************************************
3854 _samr_create_dom_alias
3855 *********************************************************************/
3857 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3859 DOM_SID dom_sid;
3860 DOM_SID info_sid;
3861 fstring name;
3862 struct group *grp;
3863 struct samr_info *info;
3864 uint32 acc_granted;
3865 gid_t gid;
3866 NTSTATUS result;
3868 /* Find the policy handle. Open a policy on it. */
3869 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3870 return NT_STATUS_INVALID_HANDLE;
3872 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3873 return r_u->status;
3876 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3877 return NT_STATUS_ACCESS_DENIED;
3879 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3881 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3883 /* Have passdb create the alias */
3884 result = pdb_create_alias(name, &r_u->rid);
3886 if (!NT_STATUS_IS_OK(result))
3887 return result;
3889 sid_copy(&info_sid, get_global_sam_sid());
3890 sid_append_rid(&info_sid, r_u->rid);
3892 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
3893 return NT_STATUS_ACCESS_DENIED;
3895 /* check if the group has been successfully created */
3896 if ((grp=getgrgid(gid)) == NULL)
3897 return NT_STATUS_ACCESS_DENIED;
3899 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3900 return NT_STATUS_NO_MEMORY;
3902 /* get a (unique) handle. open a policy on it. */
3903 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3904 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3906 return NT_STATUS_OK;
3909 /*********************************************************************
3910 _samr_query_groupinfo
3912 sends the name/comment pair of a domain group
3913 level 1 send also the number of users of that group
3914 *********************************************************************/
3916 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3918 DOM_SID group_sid;
3919 GROUP_MAP map;
3920 DOM_SID *sids=NULL;
3921 uid_t *uids;
3922 int num=0;
3923 GROUP_INFO_CTR *ctr;
3924 uint32 acc_granted;
3925 BOOL ret;
3927 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3928 return NT_STATUS_INVALID_HANDLE;
3930 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
3931 return r_u->status;
3934 become_root();
3935 ret = get_domain_group_from_sid(group_sid, &map);
3936 unbecome_root();
3937 if (!ret)
3938 return NT_STATUS_INVALID_HANDLE;
3940 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
3941 if (ctr==NULL)
3942 return NT_STATUS_NO_MEMORY;
3944 switch (q_u->switch_level) {
3945 case 1:
3946 ctr->switch_value1 = 1;
3947 if(!get_memberuids(map.gid, &uids, &num))
3948 return NT_STATUS_NO_SUCH_GROUP;
3949 SAFE_FREE(uids);
3950 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
3951 SAFE_FREE(sids);
3952 break;
3953 case 3:
3954 ctr->switch_value1 = 3;
3955 init_samr_group_info3(&ctr->group.info3);
3956 break;
3957 case 4:
3958 ctr->switch_value1 = 4;
3959 init_samr_group_info4(&ctr->group.info4, map.comment);
3960 break;
3961 default:
3962 return NT_STATUS_INVALID_INFO_CLASS;
3965 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
3967 return NT_STATUS_OK;
3970 /*********************************************************************
3971 _samr_set_groupinfo
3973 update a domain group's comment.
3974 *********************************************************************/
3976 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
3978 DOM_SID group_sid;
3979 GROUP_MAP map;
3980 GROUP_INFO_CTR *ctr;
3981 uint32 acc_granted;
3983 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3984 return NT_STATUS_INVALID_HANDLE;
3986 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
3987 return r_u->status;
3990 if (!get_domain_group_from_sid(group_sid, &map))
3991 return NT_STATUS_NO_SUCH_GROUP;
3993 ctr=q_u->ctr;
3995 switch (ctr->switch_value1) {
3996 case 1:
3997 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
3998 break;
3999 case 4:
4000 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4001 break;
4002 default:
4003 return NT_STATUS_INVALID_INFO_CLASS;
4006 if(!pdb_update_group_mapping_entry(&map)) {
4007 return NT_STATUS_NO_SUCH_GROUP;
4010 return NT_STATUS_OK;
4013 /*********************************************************************
4014 _samr_set_aliasinfo
4016 update an alias's comment.
4017 *********************************************************************/
4019 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4021 DOM_SID group_sid;
4022 struct acct_info info;
4023 ALIAS_INFO_CTR *ctr;
4024 uint32 acc_granted;
4026 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4027 return NT_STATUS_INVALID_HANDLE;
4029 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4030 return r_u->status;
4033 ctr=&q_u->ctr;
4035 switch (ctr->switch_value1) {
4036 case 3:
4037 unistr2_to_ascii(info.acct_desc,
4038 &(ctr->alias.info3.uni_acct_desc),
4039 sizeof(info.acct_desc)-1);
4040 break;
4041 default:
4042 return NT_STATUS_INVALID_INFO_CLASS;
4045 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4046 return NT_STATUS_ACCESS_DENIED;
4049 return NT_STATUS_OK;
4052 /*********************************************************************
4053 _samr_get_dom_pwinfo
4054 *********************************************************************/
4056 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4058 /* Perform access check. Since this rpc does not require a
4059 policy handle it will not be caught by the access checks on
4060 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4062 if (!pipe_access_check(p)) {
4063 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4064 r_u->status = NT_STATUS_ACCESS_DENIED;
4065 return r_u->status;
4068 /* Actually, returning zeros here works quite well :-). */
4070 return NT_STATUS_OK;
4073 /*********************************************************************
4074 _samr_open_group
4075 *********************************************************************/
4077 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4079 DOM_SID sid;
4080 DOM_SID info_sid;
4081 GROUP_MAP map;
4082 struct samr_info *info;
4083 SEC_DESC *psd = NULL;
4084 uint32 acc_granted;
4085 uint32 des_access = q_u->access_mask;
4086 size_t sd_size;
4087 NTSTATUS status;
4088 fstring sid_string;
4089 BOOL ret;
4091 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4092 return NT_STATUS_INVALID_HANDLE;
4094 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4095 return status;
4098 /*check if access can be granted as requested by client. */
4099 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4100 se_map_generic(&des_access,&grp_generic_mapping);
4101 if (!NT_STATUS_IS_OK(status =
4102 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4103 des_access, &acc_granted, "_samr_open_group"))) {
4104 return status;
4108 /* this should not be hard-coded like this */
4109 if (!sid_equal(&sid, get_global_sam_sid()))
4110 return NT_STATUS_ACCESS_DENIED;
4112 sid_copy(&info_sid, get_global_sam_sid());
4113 sid_append_rid(&info_sid, q_u->rid_group);
4114 sid_to_string(sid_string, &info_sid);
4116 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4117 return NT_STATUS_NO_MEMORY;
4119 info->acc_granted = acc_granted;
4121 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4123 /* check if that group really exists */
4124 become_root();
4125 ret = get_domain_group_from_sid(info->sid, &map);
4126 unbecome_root();
4127 if (!ret)
4128 return NT_STATUS_NO_SUCH_GROUP;
4130 /* get a (unique) handle. open a policy on it. */
4131 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4132 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4134 return NT_STATUS_OK;
4137 /*********************************************************************
4138 _samr_remove_sid_foreign_domain
4139 *********************************************************************/
4141 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4142 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4143 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4145 DOM_SID delete_sid, alias_sid;
4146 SAM_ACCOUNT *sam_pass=NULL;
4147 uint32 acc_granted;
4148 GROUP_MAP map;
4149 BOOL is_user = False;
4150 NTSTATUS result;
4151 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4153 sid_copy( &delete_sid, &q_u->sid.sid );
4155 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4156 sid_string_static(&delete_sid)));
4158 /* Find the policy handle. Open a policy on it. */
4160 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4161 return NT_STATUS_INVALID_HANDLE;
4163 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4164 "_samr_remove_sid_foreign_domain");
4166 if (!NT_STATUS_IS_OK(result))
4167 return result;
4169 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4170 sid_string_static(&alias_sid)));
4172 /* make sure we can handle this */
4174 if ( sid_check_is_domain(&alias_sid) )
4175 type = SID_NAME_DOM_GRP;
4176 else if ( sid_check_is_builtin(&alias_sid) )
4177 type = SID_NAME_ALIAS;
4179 if ( type == SID_NAME_UNKNOWN ) {
4180 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4181 return NT_STATUS_OK;
4184 /* check if the user exists before trying to delete */
4186 pdb_init_sam(&sam_pass);
4188 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4189 is_user = True;
4190 } else {
4191 /* maybe it is a group */
4192 if( !pdb_getgrsid(&map, delete_sid) ) {
4193 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4194 sid_string_static(&delete_sid)));
4195 result = NT_STATUS_INVALID_SID;
4196 goto done;
4200 /* we can only delete a user from a group since we don't have
4201 nested groups anyways. So in the latter case, just say OK */
4203 if ( is_user ) {
4204 GROUP_MAP *mappings = NULL;
4205 int num_groups, i;
4206 struct group *grp2;
4208 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4210 /* interate over the groups */
4211 for ( i=0; i<num_groups; i++ ) {
4213 grp2 = getgrgid(mappings[i].gid);
4215 if ( !grp2 ) {
4216 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4217 continue;
4220 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4221 continue;
4223 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4225 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4226 /* should we fail here ? */
4227 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4228 pdb_get_username(sam_pass), grp2->gr_name ));
4229 continue;
4232 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4233 pdb_get_username(sam_pass), grp2->gr_name ));
4236 SAFE_FREE(mappings);
4240 result = NT_STATUS_OK;
4241 done:
4243 pdb_free_sam(&sam_pass);
4245 return result;
4248 /*******************************************************************
4249 _samr_unknown_2e
4250 ********************************************************************/
4252 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4254 struct samr_info *info = NULL;
4255 SAM_UNK_CTR *ctr;
4256 uint32 min_pass_len,pass_hist,flag;
4257 time_t u_expire, u_min_age;
4258 NTTIME nt_expire, nt_min_age;
4260 time_t u_lock_duration, u_reset_time;
4261 NTTIME nt_lock_duration, nt_reset_time;
4262 uint32 lockout;
4264 time_t u_logout;
4265 NTTIME nt_logout;
4267 uint32 num_users=0, num_groups=0, num_aliases=0;
4269 uint32 account_policy_temp;
4271 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4272 return NT_STATUS_NO_MEMORY;
4274 ZERO_STRUCTP(ctr);
4276 r_u->status = NT_STATUS_OK;
4278 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4280 /* find the policy handle. open a policy on it. */
4281 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4282 return NT_STATUS_INVALID_HANDLE;
4284 switch (q_u->switch_value) {
4285 case 0x01:
4286 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4287 min_pass_len = account_policy_temp;
4289 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4290 pass_hist = account_policy_temp;
4292 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4293 flag = account_policy_temp;
4295 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4296 u_expire = account_policy_temp;
4298 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4299 u_min_age = account_policy_temp;
4301 unix_to_nt_time_abs(&nt_expire, u_expire);
4302 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4304 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4305 flag, nt_expire, nt_min_age);
4306 break;
4307 case 0x02:
4308 become_root();
4309 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4310 unbecome_root();
4311 if (!NT_STATUS_IS_OK(r_u->status)) {
4312 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4313 return r_u->status;
4315 num_users=info->disp_info.num_user_account;
4316 free_samr_db(info);
4318 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4319 if (NT_STATUS_IS_ERR(r_u->status)) {
4320 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4321 return r_u->status;
4323 num_groups=info->disp_info.num_group_account;
4324 free_samr_db(info);
4326 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4327 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4328 num_users, num_groups, num_aliases);
4329 break;
4330 case 0x03:
4331 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4332 u_logout = account_policy_temp;
4334 unix_to_nt_time_abs(&nt_logout, u_logout);
4336 init_unk_info3(&ctr->info.inf3, nt_logout);
4337 break;
4338 case 0x05:
4339 init_unk_info5(&ctr->info.inf5, global_myname());
4340 break;
4341 case 0x06:
4342 init_unk_info6(&ctr->info.inf6);
4343 break;
4344 case 0x07:
4345 init_unk_info7(&ctr->info.inf7);
4346 break;
4347 case 0x0c:
4348 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4349 u_lock_duration = account_policy_temp * 60;
4351 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4352 u_reset_time = account_policy_temp * 60;
4354 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4355 lockout = account_policy_temp;
4357 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4358 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4360 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4361 break;
4362 default:
4363 return NT_STATUS_INVALID_INFO_CLASS;
4366 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4368 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4370 return r_u->status;
4373 /*******************************************************************
4374 _samr_
4375 ********************************************************************/
4377 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4379 time_t u_expire, u_min_age;
4380 time_t u_logout;
4381 time_t u_lock_duration, u_reset_time;
4383 r_u->status = NT_STATUS_OK;
4385 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4387 /* find the policy handle. open a policy on it. */
4388 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4389 return NT_STATUS_INVALID_HANDLE;
4391 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4393 switch (q_u->switch_value) {
4394 case 0x01:
4395 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4396 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4398 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4399 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4400 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4401 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4402 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4403 break;
4404 case 0x02:
4405 break;
4406 case 0x03:
4407 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4408 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4409 break;
4410 case 0x05:
4411 break;
4412 case 0x06:
4413 break;
4414 case 0x07:
4415 break;
4416 case 0x0c:
4417 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
4418 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4420 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4421 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4422 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4423 break;
4424 default:
4425 return NT_STATUS_INVALID_INFO_CLASS;
4428 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4430 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4432 return r_u->status;