r4231: commiting changes to 3.0.10
[Samba.git] / source / rpc_server / srv_samr_nt.c
blobc913a7dcb8fc32017c0e6ac6248df309f7177291
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 = TALLOC_P(mem_ctx, struct samr_info)) == NULL)
141 return NULL;
143 ZERO_STRUCTP(info);
144 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
145 if (psid) {
146 sid_copy( &info->sid, psid);
147 } else {
148 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
150 info->mem_ctx = mem_ctx;
151 return info;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
158 static void free_samr_users(struct samr_info *info)
160 int i;
162 if (info->disp_info.user_dbloaded){
163 for (i=0; i<info->disp_info.num_user_account; i++) {
164 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165 /* Not really a free, actually a 'clear' */
166 pdb_free_sam(&sam);
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
187 static void free_samr_info(void *ptr)
189 struct samr_info *info=(struct samr_info *) ptr;
191 free_samr_db(info);
192 talloc_destroy(info->mem_ctx);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
202 if (!sam_pass)
203 return;
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL 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=TALLOC_REALLOC_ARRAY(mem_ctx, info->disp_info.disp_user_info, SAM_ACCOUNT,
259 info->disp_info.num_user_account+MAX_SAM_ENTRIES);
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=TALLOC_ARRAY(mem_ctx, DOMAIN_GRP, info->disp_info.num_group_account);
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 = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries);
721 uni_name = TALLOC_ZERO_ARRAY(ctx, 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);
733 * usrmgr expects a non-NULL terminated string with
734 * trust relationships
736 if (pdb_get_acct_ctrl(pwd) & ACB_DOMTRUST) {
737 init_unistr2(&uni_temp_name, temp_name, UNI_FLAGS_NONE);
738 } else {
739 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
742 user_sid = pdb_get_user_sid(pwd);
744 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
745 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
746 "the domain sid %s. Failing operation.\n",
747 temp_name,
748 sid_to_string(user_sid_string, user_sid),
749 sid_to_string(domain_sid_string, domain_sid)));
750 return NT_STATUS_UNSUCCESSFUL;
753 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
754 copy_unistr2(&uni_name[i], &uni_temp_name);
757 *sam_pp = sam;
758 *uni_name_pp = uni_name;
759 return NT_STATUS_OK;
762 /*******************************************************************
763 samr_reply_enum_dom_users
764 ********************************************************************/
766 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
767 SAMR_R_ENUM_DOM_USERS *r_u)
769 struct samr_info *info = NULL;
770 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
771 int num_account;
772 uint32 enum_context=q_u->start_idx;
773 uint32 max_size=q_u->max_size;
774 uint32 temp_size;
775 enum remote_arch_types ra_type = get_remote_arch();
776 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
777 uint32 max_entries = max_sam_entries;
778 DOM_SID domain_sid;
780 r_u->status = NT_STATUS_OK;
782 /* find the policy handle. open a policy on it. */
783 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
784 return NT_STATUS_INVALID_HANDLE;
786 domain_sid = info->sid;
788 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
789 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
790 "_samr_enum_dom_users"))) {
791 return r_u->status;
794 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
796 become_root();
797 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
798 unbecome_root();
800 if (!NT_STATUS_IS_OK(r_u->status))
801 return r_u->status;
803 num_account = info->disp_info.num_user_account;
805 if (enum_context > num_account) {
806 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
807 return NT_STATUS_OK;
810 /* verify we won't overflow */
811 if (max_entries > num_account-enum_context) {
812 max_entries = num_account-enum_context;
813 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
816 /* calculate the size and limit on the number of entries we will return */
817 temp_size=max_entries*struct_size;
819 if (temp_size>max_size) {
820 max_entries=MIN((max_size/struct_size),max_entries);;
821 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
825 * Note from JRA. total_entries is not being used here. Currently if there is a
826 * large user base then it looks like NT will enumerate until get_sampwd_entries
827 * returns False due to num_entries being zero. This will cause an access denied
828 * return. I don't think this is right and needs further investigation. Note that
829 * this is also the same in the TNG code (I don't think that has been tested with
830 * a very large user list as MAX_SAM_ENTRIES is set to 600).
832 * I also think that one of the 'num_entries' return parameters is probably
833 * the "max entries" parameter - but in the TNG code they're all currently set to the same
834 * value (again I think this is wrong).
837 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
838 max_entries, enum_context,
839 info->disp_info.disp_user_info,
840 &domain_sid);
842 if (!NT_STATUS_IS_OK(r_u->status))
843 return r_u->status;
845 if (enum_context+max_entries < num_account)
846 r_u->status = STATUS_MORE_ENTRIES;
848 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
850 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
852 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
854 return r_u->status;
857 /*******************************************************************
858 makes a SAM_ENTRY / UNISTR2* structure from a group list.
859 ********************************************************************/
861 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
862 uint32 num_sam_entries, DOMAIN_GRP *grp)
864 uint32 i;
865 SAM_ENTRY *sam;
866 UNISTR2 *uni_name;
868 *sam_pp = NULL;
869 *uni_name_pp = NULL;
871 if (num_sam_entries == 0)
872 return;
874 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
875 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
877 if (sam == NULL || uni_name == NULL) {
878 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
879 return;
882 for (i = 0; i < num_sam_entries; i++) {
884 * JRA. I think this should include the null. TNG does not.
886 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
887 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
890 *sam_pp = sam;
891 *uni_name_pp = uni_name;
894 /*******************************************************************
895 Get the group entries - similar to get_sampwd_entries().
896 ******************************************************************/
898 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
899 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
900 uint32 *p_num_entries, uint32 max_entries )
902 GROUP_MAP *map=NULL;
903 int i;
904 uint32 group_entries = 0;
905 uint32 num_entries = 0;
907 *p_num_entries = 0;
909 /* access checks for the users were performed higher up. become/unbecome_root()
910 needed for some passdb backends to enumerate groups */
912 become_root();
913 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
914 ENUM_ONLY_MAPPED);
915 unbecome_root();
917 num_entries=group_entries-start_idx;
919 /* limit the number of entries */
920 if (num_entries>max_entries) {
921 DEBUG(5,("Limiting to %d entries\n", max_entries));
922 num_entries=max_entries;
925 *d_grp=TALLOC_ZERO_ARRAY(ctx, DOMAIN_GRP, num_entries);
926 if (num_entries!=0 && *d_grp==NULL){
927 SAFE_FREE(map);
928 return NT_STATUS_NO_MEMORY;
931 for (i=0; i<num_entries; i++) {
932 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
933 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
934 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
935 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
938 SAFE_FREE(map);
940 *p_num_entries = num_entries;
942 DEBUG(10,("get_group_domain_entries: returning %d entries\n",
943 *p_num_entries));
945 return NT_STATUS_OK;
948 /*******************************************************************
949 Wrapper for enumerating local groups
950 ******************************************************************/
952 static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
953 const DOM_SID *sid, uint32 start_idx,
954 uint32 *p_num_entries, uint32 max_entries )
956 struct acct_info *info;
957 int i;
958 BOOL res;
960 become_root();
961 res = pdb_enum_aliases(sid, start_idx, max_entries,
962 p_num_entries, &info);
963 unbecome_root();
965 if (!res)
966 return NT_STATUS_ACCESS_DENIED;
968 if (*p_num_entries == 0)
969 return NT_STATUS_OK;
971 *d_grp = TALLOC_ARRAY(ctx, DOMAIN_GRP, *p_num_entries);
973 if (*d_grp == NULL) {
974 SAFE_FREE(info);
975 return NT_STATUS_NO_MEMORY;
978 for (i=0; i<*p_num_entries; i++) {
979 fstrcpy((*d_grp)[i].name, info[i].acct_name);
980 fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
981 (*d_grp)[i].rid = info[i].rid;
982 (*d_grp)[i].attr = SID_NAME_ALIAS;
985 SAFE_FREE(info);
986 return NT_STATUS_OK;
989 /*******************************************************************
990 samr_reply_enum_dom_groups
991 ********************************************************************/
993 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
995 DOMAIN_GRP *grp=NULL;
996 uint32 num_entries;
997 DOM_SID sid;
998 uint32 acc_granted;
1000 r_u->status = NT_STATUS_OK;
1002 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1003 return NT_STATUS_INVALID_HANDLE;
1005 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1006 return r_u->status;
1009 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1011 /* the domain group array is being allocated in the function below */
1012 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))) {
1013 return r_u->status;
1016 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1018 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1020 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1022 return r_u->status;
1026 /*******************************************************************
1027 samr_reply_enum_dom_aliases
1028 ********************************************************************/
1030 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1032 DOMAIN_GRP *grp=NULL;
1033 uint32 num_entries = 0;
1034 fstring sid_str;
1035 DOM_SID sid;
1036 NTSTATUS status;
1037 uint32 acc_granted;
1039 r_u->status = NT_STATUS_OK;
1041 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1042 return NT_STATUS_INVALID_HANDLE;
1044 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1045 return r_u->status;
1048 sid_to_string(sid_str, &sid);
1049 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1051 status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1052 &num_entries, MAX_SAM_ENTRIES);
1053 if (!NT_STATUS_IS_OK(status)) return status;
1055 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1057 /*safe_free(grp);*/
1059 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1061 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1063 return r_u->status;
1066 /*******************************************************************
1067 samr_reply_query_dispinfo
1068 ********************************************************************/
1070 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1071 SAMR_R_QUERY_DISPINFO *r_u)
1073 struct samr_info *info = NULL;
1074 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1076 uint32 max_entries=q_u->max_entries;
1077 uint32 enum_context=q_u->start_idx;
1078 uint32 max_size=q_u->max_size;
1080 SAM_DISPINFO_CTR *ctr;
1081 uint32 temp_size=0, total_data_size=0;
1082 NTSTATUS disp_ret;
1083 uint32 num_account = 0;
1084 enum remote_arch_types ra_type = get_remote_arch();
1085 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1086 DOM_SID domain_sid;
1088 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1089 r_u->status = NT_STATUS_OK;
1091 /* find the policy handle. open a policy on it. */
1092 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1093 return NT_STATUS_INVALID_HANDLE;
1095 domain_sid = info->sid;
1098 * calculate how many entries we will return.
1099 * based on
1100 * - the number of entries the client asked
1101 * - our limit on that
1102 * - the starting point (enumeration context)
1103 * - the buffer size the client will accept
1107 * We are a lot more like W2K. Instead of reading the SAM
1108 * each time to find the records we need to send back,
1109 * we read it once and link that copy to the sam handle.
1110 * For large user list (over the MAX_SAM_ENTRIES)
1111 * it's a definitive win.
1112 * second point to notice: between enumerations
1113 * our sam is now the same as it's a snapshoot.
1114 * third point: got rid of the static SAM_USER_21 struct
1115 * no more intermediate.
1116 * con: it uses much more memory, as a full copy is stored
1117 * in memory.
1119 * If you want to change it, think twice and think
1120 * of the second point , that's really important.
1122 * JFM, 12/20/2001
1125 /* Get what we need from the password database */
1126 switch (q_u->switch_level) {
1127 case 0x1:
1128 /* When playing with usrmgr, this is necessary
1129 if you want immediate refresh after editing
1130 a user. I would like to do this after the
1131 setuserinfo2, but we do not have access to
1132 the domain handle in that call, only to the
1133 user handle. Where else does this hurt?
1134 -- Volker
1136 #if 0
1137 /* We cannot do this here - it kills performace. JRA. */
1138 free_samr_users(info);
1139 #endif
1140 case 0x2:
1141 case 0x4:
1142 become_root();
1143 /* Level 2 is for all machines, otherwise only 'normal' users */
1144 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1145 unbecome_root();
1146 if (!NT_STATUS_IS_OK(r_u->status)) {
1147 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1148 return r_u->status;
1150 num_account = info->disp_info.num_user_account;
1151 break;
1152 case 0x3:
1153 case 0x5:
1154 r_u->status = load_group_domain_entries(info, &info->sid);
1155 if (!NT_STATUS_IS_OK(r_u->status))
1156 return r_u->status;
1157 num_account = info->disp_info.num_group_account;
1158 break;
1159 default:
1160 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1161 return NT_STATUS_INVALID_INFO_CLASS;
1164 /* first limit the number of entries we will return */
1165 if(max_entries > max_sam_entries) {
1166 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1167 max_entries = max_sam_entries;
1170 if (enum_context > num_account) {
1171 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1172 return NT_STATUS_NO_MORE_ENTRIES;
1175 /* verify we won't overflow */
1176 if (max_entries > num_account-enum_context) {
1177 max_entries = num_account-enum_context;
1178 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1181 /* calculate the size and limit on the number of entries we will return */
1182 temp_size=max_entries*struct_size;
1184 if (temp_size>max_size) {
1185 max_entries=MIN((max_size/struct_size),max_entries);;
1186 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1189 if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
1190 return NT_STATUS_NO_MEMORY;
1192 ZERO_STRUCTP(ctr);
1194 /* Now create reply structure */
1195 switch (q_u->switch_level) {
1196 case 0x1:
1197 if (max_entries) {
1198 if (!(ctr->sam.info1 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_1,max_entries)))
1199 return NT_STATUS_NO_MEMORY;
1201 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1202 info->disp_info.disp_user_info, &domain_sid);
1203 if (!NT_STATUS_IS_OK(disp_ret))
1204 return disp_ret;
1205 break;
1206 case 0x2:
1207 if (max_entries) {
1208 if (!(ctr->sam.info2 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_2,max_entries)))
1209 return NT_STATUS_NO_MEMORY;
1211 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1212 info->disp_info.disp_user_info, &domain_sid);
1213 if (!NT_STATUS_IS_OK(disp_ret))
1214 return disp_ret;
1215 break;
1216 case 0x3:
1217 if (max_entries) {
1218 if (!(ctr->sam.info3 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_3,max_entries)))
1219 return NT_STATUS_NO_MEMORY;
1221 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1222 if (!NT_STATUS_IS_OK(disp_ret))
1223 return disp_ret;
1224 break;
1225 case 0x4:
1226 if (max_entries) {
1227 if (!(ctr->sam.info4 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_4,max_entries)))
1228 return NT_STATUS_NO_MEMORY;
1230 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1231 if (!NT_STATUS_IS_OK(disp_ret))
1232 return disp_ret;
1233 break;
1234 case 0x5:
1235 if (max_entries) {
1236 if (!(ctr->sam.info5 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_5,max_entries)))
1237 return NT_STATUS_NO_MEMORY;
1239 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1240 if (!NT_STATUS_IS_OK(disp_ret))
1241 return disp_ret;
1242 break;
1244 default:
1245 ctr->sam.info = NULL;
1246 return NT_STATUS_INVALID_INFO_CLASS;
1249 /* calculate the total size */
1250 total_data_size=num_account*struct_size;
1252 if (enum_context+max_entries < num_account)
1253 r_u->status = STATUS_MORE_ENTRIES;
1255 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1257 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1259 return r_u->status;
1263 /*******************************************************************
1264 samr_reply_query_aliasinfo
1265 ********************************************************************/
1267 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1269 DOM_SID sid;
1270 struct acct_info info;
1271 uint32 acc_granted;
1272 BOOL ret;
1274 r_u->status = NT_STATUS_OK;
1276 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1278 /* find the policy handle. open a policy on it. */
1279 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1280 return NT_STATUS_INVALID_HANDLE;
1281 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1282 return r_u->status;
1285 become_root();
1286 ret = pdb_get_aliasinfo(&sid, &info);
1287 unbecome_root();
1289 if ( !ret )
1290 return NT_STATUS_NO_SUCH_ALIAS;
1292 switch (q_u->switch_level) {
1293 case 1:
1294 r_u->ptr = 1;
1295 r_u->ctr.switch_value1 = 1;
1296 init_samr_alias_info1(&r_u->ctr.alias.info1,
1297 info.acct_name, 1, info.acct_desc);
1298 break;
1299 case 3:
1300 r_u->ptr = 1;
1301 r_u->ctr.switch_value1 = 3;
1302 init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1303 break;
1304 default:
1305 return NT_STATUS_INVALID_INFO_CLASS;
1308 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1310 return r_u->status;
1313 #if 0
1314 /*******************************************************************
1315 samr_reply_lookup_ids
1316 ********************************************************************/
1318 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1320 uint32 rid[MAX_SAM_ENTRIES];
1321 int num_rids = q_u->num_sids1;
1323 r_u->status = NT_STATUS_OK;
1325 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1327 if (num_rids > MAX_SAM_ENTRIES) {
1328 num_rids = MAX_SAM_ENTRIES;
1329 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1332 #if 0
1333 int i;
1334 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1336 for (i = 0; i < num_rids && status == 0; i++)
1338 struct sam_passwd *sam_pass;
1339 fstring user_name;
1342 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1343 q_u->uni_user_name[i].uni_str_len));
1345 /* find the user account */
1346 become_root();
1347 sam_pass = get_smb21pwd_entry(user_name, 0);
1348 unbecome_root();
1350 if (sam_pass == NULL)
1352 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1353 rid[i] = 0;
1355 else
1357 rid[i] = sam_pass->user_rid;
1360 #endif
1362 num_rids = 1;
1363 rid[0] = BUILTIN_ALIAS_RID_USERS;
1365 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1367 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1369 return r_u->status;
1371 #endif
1373 /*******************************************************************
1374 _samr_lookup_names
1375 ********************************************************************/
1377 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1379 uint32 rid[MAX_SAM_ENTRIES];
1380 uint32 local_rid;
1381 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1382 enum SID_NAME_USE local_type;
1383 int i;
1384 int num_rids = q_u->num_names2;
1385 DOM_SID pol_sid;
1386 fstring sid_str;
1387 uint32 acc_granted;
1389 r_u->status = NT_STATUS_OK;
1391 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1393 ZERO_ARRAY(rid);
1394 ZERO_ARRAY(type);
1396 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1397 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1398 return r_u->status;
1401 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 */
1402 return r_u->status;
1405 if (num_rids > MAX_SAM_ENTRIES) {
1406 num_rids = MAX_SAM_ENTRIES;
1407 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1410 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1412 for (i = 0; i < num_rids; i++) {
1413 fstring name;
1414 DOM_SID sid;
1415 int ret;
1417 r_u->status = NT_STATUS_NONE_MAPPED;
1419 rid [i] = 0xffffffff;
1420 type[i] = SID_NAME_UNKNOWN;
1422 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1425 * we are only looking for a name
1426 * the SID we get back can be outside
1427 * the scope of the pol_sid
1429 * in clear: it prevents to reply to domain\group: yes
1430 * when only builtin\group exists.
1432 * a cleaner code is to add the sid of the domain we're looking in
1433 * to the local_lookup_name function.
1436 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1437 sid_split_rid(&sid, &local_rid);
1439 if (sid_equal(&sid, &pol_sid)) {
1440 rid[i]=local_rid;
1442 /* Windows does not return WKN_GRP here, even
1443 * on lookups in builtin */
1444 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1445 SID_NAME_ALIAS : local_type;
1447 r_u->status = NT_STATUS_OK;
1452 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1454 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1456 return r_u->status;
1459 /*******************************************************************
1460 _samr_chgpasswd_user
1461 ********************************************************************/
1463 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1465 fstring user_name;
1466 fstring wks;
1468 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1470 r_u->status = NT_STATUS_OK;
1472 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1473 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1475 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1478 * Pass the user through the NT -> unix user mapping
1479 * function.
1482 (void)map_username(user_name);
1485 * UNIX username case mangling not required, pass_oem_change
1486 * is case insensitive.
1489 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1490 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1492 init_samr_r_chgpasswd_user(r_u, r_u->status);
1494 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1496 return r_u->status;
1499 /*******************************************************************
1500 makes a SAMR_R_LOOKUP_RIDS structure.
1501 ********************************************************************/
1503 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1504 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1506 uint32 i;
1507 UNIHDR *hdr_name=NULL;
1508 UNISTR2 *uni_name=NULL;
1510 *pp_uni_name = NULL;
1511 *pp_hdr_name = NULL;
1513 if (num_names != 0) {
1514 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1515 if (hdr_name == NULL)
1516 return False;
1518 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1519 if (uni_name == NULL)
1520 return False;
1523 for (i = 0; i < num_names; i++) {
1524 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1525 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1526 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1529 *pp_uni_name = uni_name;
1530 *pp_hdr_name = hdr_name;
1532 return True;
1535 /*******************************************************************
1536 _samr_lookup_rids
1537 ********************************************************************/
1539 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1541 fstring group_names[MAX_SAM_ENTRIES];
1542 uint32 *group_attrs = NULL;
1543 UNIHDR *hdr_name = NULL;
1544 UNISTR2 *uni_name = NULL;
1545 DOM_SID pol_sid;
1546 int num_rids = q_u->num_rids1;
1547 int i;
1548 uint32 acc_granted;
1550 r_u->status = NT_STATUS_OK;
1552 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1554 /* find the policy handle. open a policy on it. */
1555 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1556 return NT_STATUS_INVALID_HANDLE;
1558 if (num_rids > MAX_SAM_ENTRIES) {
1559 num_rids = MAX_SAM_ENTRIES;
1560 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1563 if (num_rids) {
1564 if ((group_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids )) == NULL)
1565 return NT_STATUS_NO_MEMORY;
1568 r_u->status = NT_STATUS_NONE_MAPPED;
1570 become_root(); /* lookup_sid can require root privs */
1572 for (i = 0; i < num_rids; i++) {
1573 fstring tmpname;
1574 fstring domname;
1575 DOM_SID sid;
1576 enum SID_NAME_USE type;
1578 group_attrs[i] = SID_NAME_UNKNOWN;
1579 *group_names[i] = '\0';
1581 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1582 sid_copy(&sid, &pol_sid);
1583 sid_append_rid(&sid, q_u->rid[i]);
1585 if (lookup_sid(&sid, domname, tmpname, &type)) {
1586 r_u->status = NT_STATUS_OK;
1587 group_attrs[i] = (uint32)type;
1588 fstrcpy(group_names[i],tmpname);
1589 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1594 unbecome_root();
1596 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1597 return NT_STATUS_NO_MEMORY;
1599 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1601 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1603 return r_u->status;
1606 /*******************************************************************
1607 _samr_open_user. Safe - gives out no passwd info.
1608 ********************************************************************/
1610 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1612 SAM_ACCOUNT *sampass=NULL;
1613 DOM_SID sid;
1614 POLICY_HND domain_pol = q_u->domain_pol;
1615 POLICY_HND *user_pol = &r_u->user_pol;
1616 struct samr_info *info = NULL;
1617 SEC_DESC *psd = NULL;
1618 uint32 acc_granted;
1619 uint32 des_access = q_u->access_mask;
1620 size_t sd_size;
1621 BOOL ret;
1622 NTSTATUS nt_status;
1624 r_u->status = NT_STATUS_OK;
1626 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1627 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1628 return NT_STATUS_INVALID_HANDLE;
1630 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1631 return nt_status;
1634 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1635 if (!NT_STATUS_IS_OK(nt_status)) {
1636 return nt_status;
1639 /* append the user's RID to it */
1640 if (!sid_append_rid(&sid, q_u->user_rid))
1641 return NT_STATUS_NO_SUCH_USER;
1643 /* check if access can be granted as requested by client. */
1644 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1645 se_map_generic(&des_access, &usr_generic_mapping);
1646 if (!NT_STATUS_IS_OK(nt_status =
1647 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1648 des_access, &acc_granted, "_samr_open_user"))) {
1649 return nt_status;
1652 become_root();
1653 ret=pdb_getsampwsid(sampass, &sid);
1654 unbecome_root();
1656 /* check that the SID exists in our domain. */
1657 if (ret == False) {
1658 return NT_STATUS_NO_SUCH_USER;
1661 pdb_free_sam(&sampass);
1663 /* associate the user's SID and access bits with the new handle. */
1664 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1665 return NT_STATUS_NO_MEMORY;
1666 info->acc_granted = acc_granted;
1668 /* get a (unique) handle. open a policy on it. */
1669 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1670 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1672 return r_u->status;
1675 /*************************************************************************
1676 get_user_info_10. Safe. Only gives out acb bits.
1677 *************************************************************************/
1679 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1681 SAM_ACCOUNT *smbpass=NULL;
1682 BOOL ret;
1683 NTSTATUS nt_status;
1685 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1687 if (!NT_STATUS_IS_OK(nt_status)) {
1688 return nt_status;
1691 become_root();
1692 ret = pdb_getsampwsid(smbpass, user_sid);
1693 unbecome_root();
1695 if (ret==False) {
1696 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1697 return NT_STATUS_NO_SUCH_USER;
1700 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1702 ZERO_STRUCTP(id10);
1703 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1705 pdb_free_sam(&smbpass);
1707 return NT_STATUS_OK;
1710 /*************************************************************************
1711 get_user_info_12. OK - this is the killer as it gives out password info.
1712 Ensure that this is only allowed on an encrypted connection with a root
1713 user. JRA.
1714 *************************************************************************/
1716 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1718 SAM_ACCOUNT *smbpass=NULL;
1719 BOOL ret;
1720 NTSTATUS nt_status;
1722 if (!p->ntlmssp_auth_validated)
1723 return NT_STATUS_ACCESS_DENIED;
1725 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1726 return NT_STATUS_ACCESS_DENIED;
1729 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1732 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1734 if (!NT_STATUS_IS_OK(nt_status)) {
1735 return nt_status;
1738 ret = pdb_getsampwsid(smbpass, user_sid);
1740 if (ret == False) {
1741 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1742 pdb_free_sam(&smbpass);
1743 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1746 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1748 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1749 pdb_free_sam(&smbpass);
1750 return NT_STATUS_ACCOUNT_DISABLED;
1753 ZERO_STRUCTP(id12);
1754 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1756 pdb_free_sam(&smbpass);
1758 return NT_STATUS_OK;
1761 /*************************************************************************
1762 get_user_info_20
1763 *************************************************************************/
1765 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1767 SAM_ACCOUNT *sampass=NULL;
1768 BOOL ret;
1770 pdb_init_sam_talloc(mem_ctx, &sampass);
1772 become_root();
1773 ret = pdb_getsampwsid(sampass, user_sid);
1774 unbecome_root();
1776 if (ret == False) {
1777 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1778 return NT_STATUS_NO_SUCH_USER;
1781 samr_clear_sam_passwd(sampass);
1783 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1785 ZERO_STRUCTP(id20);
1786 init_sam_user_info20A(id20, sampass);
1788 pdb_free_sam(&sampass);
1790 return NT_STATUS_OK;
1793 /*************************************************************************
1794 get_user_info_21
1795 *************************************************************************/
1797 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1798 DOM_SID *user_sid, DOM_SID *domain_sid)
1800 SAM_ACCOUNT *sampass=NULL;
1801 BOOL ret;
1802 NTSTATUS nt_status;
1804 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1805 if (!NT_STATUS_IS_OK(nt_status)) {
1806 return nt_status;
1809 become_root();
1810 ret = pdb_getsampwsid(sampass, user_sid);
1811 unbecome_root();
1813 if (ret == False) {
1814 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1815 return NT_STATUS_NO_SUCH_USER;
1818 samr_clear_sam_passwd(sampass);
1820 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1822 ZERO_STRUCTP(id21);
1823 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1825 pdb_free_sam(&sampass);
1827 return NT_STATUS_OK;
1830 /*******************************************************************
1831 _samr_query_userinfo
1832 ********************************************************************/
1834 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1836 SAM_USERINFO_CTR *ctr;
1837 struct samr_info *info = NULL;
1838 DOM_SID domain_sid;
1839 uint32 rid;
1841 r_u->status=NT_STATUS_OK;
1843 /* search for the handle */
1844 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1845 return NT_STATUS_INVALID_HANDLE;
1847 domain_sid = info->sid;
1849 sid_split_rid(&domain_sid, &rid);
1851 if (!sid_check_is_in_our_domain(&info->sid))
1852 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1854 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1856 ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
1857 if (!ctr)
1858 return NT_STATUS_NO_MEMORY;
1860 ZERO_STRUCTP(ctr);
1862 /* ok! user info levels (lots: see MSDEV help), off we go... */
1863 ctr->switch_value = q_u->switch_value;
1865 switch (q_u->switch_value) {
1866 case 0x10:
1867 ctr->info.id10 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_10);
1868 if (ctr->info.id10 == NULL)
1869 return NT_STATUS_NO_MEMORY;
1871 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1872 return r_u->status;
1873 break;
1875 #if 0
1876 /* whoops - got this wrong. i think. or don't understand what's happening. */
1877 case 0x11:
1879 NTTIME expire;
1880 info = (void *)&id11;
1882 expire.low = 0xffffffff;
1883 expire.high = 0x7fffffff;
1885 ctr->info.id = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_11));
1886 ZERO_STRUCTP(ctr->info.id11);
1887 init_sam_user_info11(ctr->info.id11, &expire,
1888 "BROOKFIELDS$", /* name */
1889 0x03ef, /* user rid */
1890 0x201, /* group rid */
1891 0x0080); /* acb info */
1893 break;
1895 #endif
1897 case 0x12:
1898 ctr->info.id12 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_12);
1899 if (ctr->info.id12 == NULL)
1900 return NT_STATUS_NO_MEMORY;
1902 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1903 return r_u->status;
1904 break;
1906 case 20:
1907 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
1908 if (ctr->info.id20 == NULL)
1909 return NT_STATUS_NO_MEMORY;
1910 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1911 return r_u->status;
1912 break;
1914 case 21:
1915 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
1916 if (ctr->info.id21 == NULL)
1917 return NT_STATUS_NO_MEMORY;
1918 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1919 &info->sid, &domain_sid)))
1920 return r_u->status;
1921 break;
1923 default:
1924 return NT_STATUS_INVALID_INFO_CLASS;
1927 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1929 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1931 return r_u->status;
1934 /*******************************************************************
1935 samr_reply_query_usergroups
1936 ********************************************************************/
1938 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1940 SAM_ACCOUNT *sam_pass=NULL;
1941 DOM_SID sid;
1942 DOM_GID *gids = NULL;
1943 int num_groups = 0;
1944 uint32 acc_granted;
1945 BOOL ret;
1948 * from the SID in the request:
1949 * we should send back the list of DOMAIN GROUPS
1950 * the user is a member of
1952 * and only the DOMAIN GROUPS
1953 * no ALIASES !!! neither aliases of the domain
1954 * nor aliases of the builtin SID
1956 * JFM, 12/2/2001
1959 r_u->status = NT_STATUS_OK;
1961 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1963 /* find the policy handle. open a policy on it. */
1964 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1965 return NT_STATUS_INVALID_HANDLE;
1967 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1968 return r_u->status;
1971 if (!sid_check_is_in_our_domain(&sid))
1972 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1974 pdb_init_sam(&sam_pass);
1976 become_root();
1977 ret = pdb_getsampwsid(sam_pass, &sid);
1978 unbecome_root();
1980 if (ret == False) {
1981 pdb_free_sam(&sam_pass);
1982 return NT_STATUS_NO_SUCH_USER;
1985 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
1986 pdb_free_sam(&sam_pass);
1987 return NT_STATUS_NO_SUCH_GROUP;
1990 /* construct the response. lkclXXXX: gids are not copied! */
1991 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1993 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1995 pdb_free_sam(&sam_pass);
1997 return r_u->status;
2000 /*******************************************************************
2001 _samr_query_dom_info
2002 ********************************************************************/
2004 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2006 struct samr_info *info = NULL;
2007 SAM_UNK_CTR *ctr;
2008 uint32 min_pass_len,pass_hist,flag;
2009 time_t u_expire, u_min_age;
2010 NTTIME nt_expire, nt_min_age;
2012 time_t u_lock_duration, u_reset_time;
2013 NTTIME nt_lock_duration, nt_reset_time;
2014 uint32 lockout;
2016 time_t u_logout;
2017 NTTIME nt_logout;
2019 uint32 account_policy_temp;
2021 uint32 num_users=0, num_groups=0, num_aliases=0;
2023 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2024 return NT_STATUS_NO_MEMORY;
2026 ZERO_STRUCTP(ctr);
2028 r_u->status = NT_STATUS_OK;
2030 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2032 /* find the policy handle. open a policy on it. */
2033 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2034 return NT_STATUS_INVALID_HANDLE;
2036 switch (q_u->switch_value) {
2037 case 0x01:
2039 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2040 min_pass_len = account_policy_temp;
2042 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2043 pass_hist = account_policy_temp;
2045 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2046 flag = account_policy_temp;
2048 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2049 u_expire = account_policy_temp;
2051 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2052 u_min_age = account_policy_temp;
2054 unix_to_nt_time_abs(&nt_expire, u_expire);
2055 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2057 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2058 flag, nt_expire, nt_min_age);
2059 break;
2060 case 0x02:
2061 become_root();
2062 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2063 unbecome_root();
2064 if (!NT_STATUS_IS_OK(r_u->status)) {
2065 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2066 return r_u->status;
2068 num_users=info->disp_info.num_user_account;
2069 free_samr_db(info);
2071 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2072 if (!NT_STATUS_IS_OK(r_u->status)) {
2073 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2074 return r_u->status;
2076 num_groups=info->disp_info.num_group_account;
2077 free_samr_db(info);
2079 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2080 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2081 num_users, num_groups, num_aliases);
2082 break;
2083 case 0x03:
2084 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2085 unix_to_nt_time_abs(&nt_logout, u_logout);
2087 init_unk_info3(&ctr->info.inf3, nt_logout);
2088 break;
2089 case 0x05:
2090 init_unk_info5(&ctr->info.inf5, global_myname());
2091 break;
2092 case 0x06:
2093 init_unk_info6(&ctr->info.inf6);
2094 break;
2095 case 0x07:
2096 init_unk_info7(&ctr->info.inf7);
2097 break;
2098 case 0x0c:
2099 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2100 u_lock_duration = account_policy_temp * 60;
2102 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2103 u_reset_time = account_policy_temp * 60;
2105 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2106 lockout = account_policy_temp;
2108 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2109 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2111 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2112 break;
2113 default:
2114 return NT_STATUS_INVALID_INFO_CLASS;
2117 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2119 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2121 return r_u->status;
2124 /*******************************************************************
2125 _samr_create_user
2126 Create an account, can be either a normal user or a machine.
2127 This funcion will need to be updated for bdc/domain trusts.
2128 ********************************************************************/
2130 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2132 SAM_ACCOUNT *sam_pass=NULL;
2133 fstring account;
2134 DOM_SID sid;
2135 pstring add_script;
2136 POLICY_HND dom_pol = q_u->domain_pol;
2137 UNISTR2 user_account = q_u->uni_name;
2138 uint16 acb_info = q_u->acb_info;
2139 POLICY_HND *user_pol = &r_u->user_pol;
2140 struct samr_info *info = NULL;
2141 BOOL ret;
2142 NTSTATUS nt_status;
2143 struct passwd *pw;
2144 uint32 acc_granted;
2145 SEC_DESC *psd;
2146 size_t sd_size;
2147 uint32 new_rid = 0;
2148 /* check this, when giving away 'add computer to domain' privs */
2149 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2151 /* Get the domain SID stored in the domain policy */
2152 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2153 return NT_STATUS_INVALID_HANDLE;
2155 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2156 return nt_status;
2159 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2160 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2161 this parameter is not an account type */
2162 return NT_STATUS_INVALID_PARAMETER;
2165 /* find the account: tell the caller if it exists.
2166 lkclXXXX i have *no* idea if this is a problem or not
2167 or even if you are supposed to construct a different
2168 reply if the account already exists...
2171 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2172 strlower_m(account);
2174 pdb_init_sam(&sam_pass);
2176 become_root();
2177 ret = pdb_getsampwnam(sam_pass, account);
2178 unbecome_root();
2179 if (ret == True) {
2180 /* this account exists: say so */
2181 pdb_free_sam(&sam_pass);
2182 return NT_STATUS_USER_EXISTS;
2185 pdb_free_sam(&sam_pass);
2188 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2189 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2190 * that only people with write access to the smbpasswd file will be able
2191 * to create a user. JRA.
2195 * add the user in the /etc/passwd file or the unix authority system.
2196 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2197 * a) local_password_change() checks for us if the /etc/passwd account really exists
2198 * b) smb_create_user() would return an error if the account already exists
2199 * and as it could return an error also if it can't create the account, it would be tricky.
2201 * So we go the easy way, only check after if the account exists.
2202 * JFM (2/3/2001), to clear any possible bad understanding (-:
2204 * We now have seperate script paramaters for adding users/machines so we
2205 * now have some sainity-checking to match.
2208 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2211 * we used to have code here that made sure the acb_info flags
2212 * matched with the users named (e.g. an account flags as a machine
2213 * trust account ended in '$'). It has been ifdef'd out for a long
2214 * time, so I replaced it with this comment. --jerry
2217 /* the passdb lookup has failed; check to see if we need to run the
2218 add user/machine script */
2220 pw = Get_Pwnam(account);
2222 /*********************************************************************
2223 * HEADS UP! If we have to create a new user account, we have to get
2224 * a new RID from somewhere. This used to be done by the passdb
2225 * backend. It has been moved into idmap now. Since idmap is now
2226 * wrapped up behind winbind, this means you have to run winbindd if you
2227 * want new accounts to get a new RID when "enable rid algorithm = no".
2228 * Tough. We now have a uniform way of allocating RIDs regardless
2229 * of what ever passdb backend people may use.
2230 * --jerry (2003-07-10)
2231 *********************************************************************/
2233 if ( !pw ) {
2235 * we can't check both the ending $ and the acb_info.
2237 * UserManager creates trust accounts (ending in $,
2238 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2239 * JFM, 11/29/2001
2241 if (account[strlen(account)-1] == '$')
2242 pstrcpy(add_script, lp_addmachine_script());
2243 else
2244 pstrcpy(add_script, lp_adduser_script());
2246 if (*add_script) {
2247 int add_ret;
2248 all_string_sub(add_script, "%u", account, sizeof(add_script));
2249 add_ret = smbrun(add_script,NULL);
2250 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2252 else /* no add user script -- ask winbindd to do it */
2254 if ( !winbind_create_user( account, &new_rid ) ) {
2255 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2256 account));
2262 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2264 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2265 return nt_status;
2267 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2269 if (!pdb_add_sam_account(sam_pass)) {
2270 pdb_free_sam(&sam_pass);
2271 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2272 account));
2273 return NT_STATUS_ACCESS_DENIED;
2276 /* Get the user's SID */
2277 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2279 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2280 se_map_generic(&des_access, &usr_generic_mapping);
2281 if (!NT_STATUS_IS_OK(nt_status =
2282 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2283 des_access, &acc_granted, "_samr_create_user"))) {
2284 return nt_status;
2287 /* associate the user's SID with the new handle. */
2288 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2289 pdb_free_sam(&sam_pass);
2290 return NT_STATUS_NO_MEMORY;
2293 ZERO_STRUCTP(info);
2294 info->sid = sid;
2295 info->acc_granted = acc_granted;
2297 /* get a (unique) handle. open a policy on it. */
2298 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2299 pdb_free_sam(&sam_pass);
2300 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2303 r_u->user_rid=pdb_get_user_rid(sam_pass);
2305 r_u->access_granted = acc_granted;
2307 pdb_free_sam(&sam_pass);
2309 return NT_STATUS_OK;
2312 /*******************************************************************
2313 samr_reply_connect_anon
2314 ********************************************************************/
2316 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2318 struct samr_info *info = NULL;
2319 uint32 des_access = q_u->access_mask;
2321 /* Access check */
2323 if (!pipe_access_check(p)) {
2324 DEBUG(3, ("access denied to samr_connect_anon\n"));
2325 r_u->status = NT_STATUS_ACCESS_DENIED;
2326 return r_u->status;
2329 /* set up the SAMR connect_anon response */
2331 r_u->status = NT_STATUS_OK;
2333 /* associate the user's SID with the new handle. */
2334 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2335 return NT_STATUS_NO_MEMORY;
2337 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2338 was observed from a win98 client trying to enumerate users (when configured
2339 user level access control on shares) --jerry */
2341 se_map_generic( &des_access, &sam_generic_mapping );
2342 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2344 info->status = q_u->unknown_0;
2346 /* get a (unique) handle. open a policy on it. */
2347 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2348 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2350 return r_u->status;
2353 /*******************************************************************
2354 samr_reply_connect
2355 ********************************************************************/
2357 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2359 struct samr_info *info = NULL;
2360 SEC_DESC *psd = NULL;
2361 uint32 acc_granted;
2362 uint32 des_access = q_u->access_mask;
2363 size_t sd_size;
2364 NTSTATUS nt_status;
2367 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2369 /* Access check */
2371 if (!pipe_access_check(p)) {
2372 DEBUG(3, ("access denied to samr_connect\n"));
2373 r_u->status = NT_STATUS_ACCESS_DENIED;
2374 return r_u->status;
2377 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2378 se_map_generic(&des_access, &sam_generic_mapping);
2379 if (!NT_STATUS_IS_OK(nt_status =
2380 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2381 des_access, &acc_granted, "_samr_connect"))) {
2382 return nt_status;
2385 r_u->status = NT_STATUS_OK;
2387 /* associate the user's SID and access granted with the new handle. */
2388 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2389 return NT_STATUS_NO_MEMORY;
2391 info->acc_granted = acc_granted;
2392 info->status = q_u->access_mask;
2394 /* get a (unique) handle. open a policy on it. */
2395 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2396 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2398 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2400 return r_u->status;
2403 /*******************************************************************
2404 samr_connect4
2405 ********************************************************************/
2407 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2409 struct samr_info *info = NULL;
2410 SEC_DESC *psd = NULL;
2411 uint32 acc_granted;
2412 uint32 des_access = q_u->access_mask;
2413 size_t sd_size;
2414 NTSTATUS nt_status;
2417 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2419 /* Access check */
2421 if (!pipe_access_check(p)) {
2422 DEBUG(3, ("access denied to samr_connect4\n"));
2423 r_u->status = NT_STATUS_ACCESS_DENIED;
2424 return r_u->status;
2427 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2428 se_map_generic(&des_access, &sam_generic_mapping);
2429 if (!NT_STATUS_IS_OK(nt_status =
2430 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2431 des_access, &acc_granted, "_samr_connect"))) {
2432 return nt_status;
2435 r_u->status = NT_STATUS_OK;
2437 /* associate the user's SID and access granted with the new handle. */
2438 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2439 return NT_STATUS_NO_MEMORY;
2441 info->acc_granted = acc_granted;
2442 info->status = q_u->access_mask;
2444 /* get a (unique) handle. open a policy on it. */
2445 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2446 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2448 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2450 return r_u->status;
2453 /**********************************************************************
2454 api_samr_lookup_domain
2455 **********************************************************************/
2457 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2459 struct samr_info *info;
2460 fstring domain_name;
2461 DOM_SID sid;
2463 r_u->status = NT_STATUS_OK;
2465 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2466 return NT_STATUS_INVALID_HANDLE;
2468 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2469 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2471 return r_u->status;
2474 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2476 ZERO_STRUCT(sid);
2478 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2479 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2482 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2484 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2486 return r_u->status;
2489 /******************************************************************
2490 makes a SAMR_R_ENUM_DOMAINS structure.
2491 ********************************************************************/
2493 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2494 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2496 uint32 i;
2497 SAM_ENTRY *sam;
2498 UNISTR2 *uni_name;
2500 DEBUG(5, ("make_enum_domains\n"));
2502 *pp_sam = NULL;
2503 *pp_uni_name = NULL;
2505 if (num_sam_entries == 0)
2506 return True;
2508 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2509 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2511 if (sam == NULL || uni_name == NULL)
2512 return False;
2514 for (i = 0; i < num_sam_entries; i++) {
2515 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2516 init_sam_entry(&sam[i], &uni_name[i], 0);
2519 *pp_sam = sam;
2520 *pp_uni_name = uni_name;
2522 return True;
2525 /**********************************************************************
2526 api_samr_enum_domains
2527 **********************************************************************/
2529 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2531 struct samr_info *info;
2532 uint32 num_entries = 2;
2533 fstring dom[2];
2534 const char *name;
2536 r_u->status = NT_STATUS_OK;
2538 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2539 return NT_STATUS_INVALID_HANDLE;
2541 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2542 return r_u->status;
2545 name = get_global_sam_name();
2547 fstrcpy(dom[0],name);
2548 strupper_m(dom[0]);
2549 fstrcpy(dom[1],"Builtin");
2551 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2552 return NT_STATUS_NO_MEMORY;
2554 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2556 return r_u->status;
2559 /*******************************************************************
2560 api_samr_open_alias
2561 ********************************************************************/
2563 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2565 DOM_SID sid;
2566 POLICY_HND domain_pol = q_u->dom_pol;
2567 uint32 alias_rid = q_u->rid_alias;
2568 POLICY_HND *alias_pol = &r_u->pol;
2569 struct samr_info *info = NULL;
2570 SEC_DESC *psd = NULL;
2571 uint32 acc_granted;
2572 uint32 des_access = q_u->access_mask;
2573 size_t sd_size;
2574 NTSTATUS status;
2576 r_u->status = NT_STATUS_OK;
2578 /* find the domain policy and get the SID / access bits stored in the domain policy */
2579 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2580 return NT_STATUS_INVALID_HANDLE;
2582 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2583 return status;
2586 /* append the alias' RID to it */
2587 if (!sid_append_rid(&sid, alias_rid))
2588 return NT_STATUS_NO_SUCH_USER;
2590 /*check if access can be granted as requested by client. */
2591 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2592 se_map_generic(&des_access,&ali_generic_mapping);
2593 if (!NT_STATUS_IS_OK(status =
2594 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2595 des_access, &acc_granted, "_samr_open_alias"))) {
2596 return status;
2600 * we should check if the rid really exist !!!
2601 * JFM.
2604 /* associate the user's SID with the new handle. */
2605 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2606 return NT_STATUS_NO_MEMORY;
2608 info->acc_granted = acc_granted;
2610 /* get a (unique) handle. open a policy on it. */
2611 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2612 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2614 return r_u->status;
2617 /*******************************************************************
2618 set_user_info_10
2619 ********************************************************************/
2621 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2623 SAM_ACCOUNT *pwd =NULL;
2624 BOOL ret;
2626 pdb_init_sam(&pwd);
2628 ret = pdb_getsampwsid(pwd, sid);
2630 if(ret==False) {
2631 pdb_free_sam(&pwd);
2632 return False;
2635 if (id10 == NULL) {
2636 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2637 pdb_free_sam(&pwd);
2638 return False;
2641 /* FIX ME: check if the value is really changed --metze */
2642 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2643 pdb_free_sam(&pwd);
2644 return False;
2647 if(!pdb_update_sam_account(pwd)) {
2648 pdb_free_sam(&pwd);
2649 return False;
2652 pdb_free_sam(&pwd);
2654 return True;
2657 /*******************************************************************
2658 set_user_info_12
2659 ********************************************************************/
2661 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2663 SAM_ACCOUNT *pwd = NULL;
2665 pdb_init_sam(&pwd);
2667 if(!pdb_getsampwsid(pwd, sid)) {
2668 pdb_free_sam(&pwd);
2669 return False;
2672 if (id12 == NULL) {
2673 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2674 pdb_free_sam(&pwd);
2675 return False;
2678 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2679 pdb_free_sam(&pwd);
2680 return False;
2682 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2683 pdb_free_sam(&pwd);
2684 return False;
2686 if (!pdb_set_pass_changed_now (pwd)) {
2687 pdb_free_sam(&pwd);
2688 return False;
2691 if(!pdb_update_sam_account(pwd)) {
2692 pdb_free_sam(&pwd);
2693 return False;
2696 pdb_free_sam(&pwd);
2697 return True;
2700 /*******************************************************************
2701 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2702 ********************************************************************/
2703 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2705 struct group *grp;
2706 gid_t gid;
2708 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2709 &gid))) {
2710 DEBUG(2,("Could not get gid for primary group of "
2711 "user %s\n", pdb_get_username(sampass)));
2712 return False;
2715 grp = getgrgid(gid);
2717 if (grp == NULL) {
2718 DEBUG(2,("Could not find primary group %lu for "
2719 "user %s\n", (unsigned long)gid,
2720 pdb_get_username(sampass)));
2721 return False;
2724 if (smb_set_primary_group(grp->gr_name,
2725 pdb_get_username(sampass)) != 0) {
2726 DEBUG(2,("Could not set primary group for user %s to "
2727 "%s\n",
2728 pdb_get_username(sampass), grp->gr_name));
2729 return False;
2732 return True;
2736 /*******************************************************************
2737 set_user_info_20
2738 ********************************************************************/
2740 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2742 SAM_ACCOUNT *pwd = NULL;
2744 if (id20 == NULL) {
2745 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2746 return False;
2749 pdb_init_sam(&pwd);
2751 if (!pdb_getsampwsid(pwd, sid)) {
2752 pdb_free_sam(&pwd);
2753 return False;
2756 copy_id20_to_sam_passwd(pwd, id20);
2758 /* write the change out */
2759 if(!pdb_update_sam_account(pwd)) {
2760 pdb_free_sam(&pwd);
2761 return False;
2764 pdb_free_sam(&pwd);
2766 return True;
2768 /*******************************************************************
2769 set_user_info_21
2770 ********************************************************************/
2772 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2774 SAM_ACCOUNT *pwd = NULL;
2776 if (id21 == NULL) {
2777 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2778 return False;
2781 pdb_init_sam(&pwd);
2783 if (!pdb_getsampwsid(pwd, sid)) {
2784 pdb_free_sam(&pwd);
2785 return False;
2788 copy_id21_to_sam_passwd(pwd, id21);
2791 * The funny part about the previous two calls is
2792 * that pwd still has the password hashes from the
2793 * passdb entry. These have not been updated from
2794 * id21. I don't know if they need to be set. --jerry
2797 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2798 set_unix_primary_group(pwd);
2800 /* write the change out */
2801 if(!pdb_update_sam_account(pwd)) {
2802 pdb_free_sam(&pwd);
2803 return False;
2806 pdb_free_sam(&pwd);
2808 return True;
2811 /*******************************************************************
2812 set_user_info_23
2813 ********************************************************************/
2815 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2817 SAM_ACCOUNT *pwd = NULL;
2818 pstring plaintext_buf;
2819 uint32 len;
2820 uint16 acct_ctrl;
2822 if (id23 == NULL) {
2823 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2824 return False;
2827 pdb_init_sam(&pwd);
2829 if (!pdb_getsampwsid(pwd, sid)) {
2830 pdb_free_sam(&pwd);
2831 return False;
2834 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2835 pdb_get_username(pwd)));
2837 acct_ctrl = pdb_get_acct_ctrl(pwd);
2839 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2840 pdb_free_sam(&pwd);
2841 return False;
2844 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2845 pdb_free_sam(&pwd);
2846 return False;
2849 copy_id23_to_sam_passwd(pwd, id23);
2851 /* if it's a trust account, don't update /etc/passwd */
2852 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2853 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2854 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2855 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2856 } else {
2857 /* update the UNIX password */
2858 if (lp_unix_password_sync() ) {
2859 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2860 if (!passwd) {
2861 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2864 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2865 pdb_free_sam(&pwd);
2866 return False;
2871 ZERO_STRUCT(plaintext_buf);
2873 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2874 set_unix_primary_group(pwd);
2876 if(!pdb_update_sam_account(pwd)) {
2877 pdb_free_sam(&pwd);
2878 return False;
2881 pdb_free_sam(&pwd);
2883 return True;
2886 /*******************************************************************
2887 set_user_info_pw
2888 ********************************************************************/
2890 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2892 SAM_ACCOUNT *pwd = NULL;
2893 uint32 len;
2894 pstring plaintext_buf;
2895 uint16 acct_ctrl;
2897 pdb_init_sam(&pwd);
2899 if (!pdb_getsampwsid(pwd, sid)) {
2900 pdb_free_sam(&pwd);
2901 return False;
2904 DEBUG(5, ("Attempting administrator password change for user %s\n",
2905 pdb_get_username(pwd)));
2907 acct_ctrl = pdb_get_acct_ctrl(pwd);
2909 ZERO_STRUCT(plaintext_buf);
2911 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2912 pdb_free_sam(&pwd);
2913 return False;
2916 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2917 pdb_free_sam(&pwd);
2918 return False;
2921 /* if it's a trust account, don't update /etc/passwd */
2922 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2923 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2924 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2925 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2926 } else {
2927 /* update the UNIX password */
2928 if (lp_unix_password_sync()) {
2929 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2930 if (!passwd) {
2931 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2934 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2935 pdb_free_sam(&pwd);
2936 return False;
2941 ZERO_STRUCT(plaintext_buf);
2943 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2945 /* update the SAMBA password */
2946 if(!pdb_update_sam_account(pwd)) {
2947 pdb_free_sam(&pwd);
2948 return False;
2951 pdb_free_sam(&pwd);
2953 return True;
2956 /*******************************************************************
2957 samr_reply_set_userinfo
2958 ********************************************************************/
2960 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2962 DOM_SID sid;
2963 POLICY_HND *pol = &q_u->pol;
2964 uint16 switch_value = q_u->switch_value;
2965 SAM_USERINFO_CTR *ctr = q_u->ctr;
2966 uint32 acc_granted;
2967 uint32 acc_required;
2969 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2971 r_u->status = NT_STATUS_OK;
2973 /* find the policy handle. open a policy on it. */
2974 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2975 return NT_STATUS_INVALID_HANDLE;
2977 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2978 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2979 return r_u->status;
2982 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2984 if (ctr == NULL) {
2985 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2986 return NT_STATUS_INVALID_INFO_CLASS;
2989 /* ok! user info levels (lots: see MSDEV help), off we go... */
2990 switch (switch_value) {
2991 case 0x12:
2992 if (!set_user_info_12(ctr->info.id12, &sid))
2993 return NT_STATUS_ACCESS_DENIED;
2994 break;
2996 case 24:
2997 if (!p->session_key.length) {
2998 return NT_STATUS_NO_USER_SESSION_KEY;
3000 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3002 dump_data(100, (char *)ctr->info.id24->pass, 516);
3004 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3005 return NT_STATUS_ACCESS_DENIED;
3006 break;
3008 case 25:
3009 #if 0
3011 * Currently we don't really know how to unmarshall
3012 * the level 25 struct, and the password encryption
3013 * is different. This is a placeholder for when we
3014 * do understand it. In the meantime just return INVALID
3015 * info level and W2K SP2 drops down to level 23... JRA.
3018 if (!p->session_key.length) {
3019 return NT_STATUS_NO_USER_SESSION_KEY;
3021 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3023 dump_data(100, (char *)ctr->info.id25->pass, 532);
3025 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3026 return NT_STATUS_ACCESS_DENIED;
3027 break;
3028 #endif
3029 return NT_STATUS_INVALID_INFO_CLASS;
3031 case 23:
3032 if (!p->session_key.length) {
3033 return NT_STATUS_NO_USER_SESSION_KEY;
3035 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3037 dump_data(100, (char *)ctr->info.id23->pass, 516);
3039 if (!set_user_info_23(ctr->info.id23, &sid))
3040 return NT_STATUS_ACCESS_DENIED;
3041 break;
3043 default:
3044 return NT_STATUS_INVALID_INFO_CLASS;
3047 return r_u->status;
3050 /*******************************************************************
3051 samr_reply_set_userinfo2
3052 ********************************************************************/
3054 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3056 DOM_SID sid;
3057 SAM_USERINFO_CTR *ctr = q_u->ctr;
3058 POLICY_HND *pol = &q_u->pol;
3059 uint16 switch_value = q_u->switch_value;
3060 uint32 acc_granted;
3061 uint32 acc_required;
3063 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3065 r_u->status = NT_STATUS_OK;
3067 /* find the policy handle. open a policy on it. */
3068 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3069 return NT_STATUS_INVALID_HANDLE;
3071 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3072 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3073 return r_u->status;
3076 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3078 if (ctr == NULL) {
3079 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3080 return NT_STATUS_INVALID_INFO_CLASS;
3083 switch_value=ctr->switch_value;
3085 /* ok! user info levels (lots: see MSDEV help), off we go... */
3086 switch (switch_value) {
3087 case 21:
3088 if (!set_user_info_21(ctr->info.id21, &sid))
3089 return NT_STATUS_ACCESS_DENIED;
3090 break;
3091 case 20:
3092 if (!set_user_info_20(ctr->info.id20, &sid))
3093 return NT_STATUS_ACCESS_DENIED;
3094 break;
3095 case 16:
3096 if (!set_user_info_10(ctr->info.id10, &sid))
3097 return NT_STATUS_ACCESS_DENIED;
3098 break;
3099 case 18:
3100 /* Used by AS/U JRA. */
3101 if (!set_user_info_12(ctr->info.id12, &sid))
3102 return NT_STATUS_ACCESS_DENIED;
3103 break;
3104 default:
3105 return NT_STATUS_INVALID_INFO_CLASS;
3108 return r_u->status;
3111 /*********************************************************************
3112 _samr_query_aliasmem
3113 *********************************************************************/
3115 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3117 int num_groups = 0, tmp_num_groups=0;
3118 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3119 struct samr_info *info = NULL;
3120 int i,j;
3122 NTSTATUS ntstatus1;
3123 NTSTATUS ntstatus2;
3125 /* until i see a real useraliases query, we fack one up */
3127 /* I have seen one, JFM 2/12/2001 */
3129 * Explanation of what this call does:
3130 * for all the SID given in the request:
3131 * return a list of alias (local groups)
3132 * that have those SID as members.
3134 * and that's the alias in the domain specified
3135 * in the policy_handle
3137 * if the policy handle is on an incorrect sid
3138 * for example a user's sid
3139 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3142 r_u->status = NT_STATUS_OK;
3144 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3146 /* find the policy handle. open a policy on it. */
3147 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3148 return NT_STATUS_INVALID_HANDLE;
3150 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3151 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3153 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3154 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3155 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3156 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3160 if (!sid_check_is_domain(&info->sid) &&
3161 !sid_check_is_builtin(&info->sid))
3162 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3165 for (i=0; i<q_u->num_sids1; i++) {
3167 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3170 * if there is an error, we just continue as
3171 * it can be an unfound user or group
3173 if (!NT_STATUS_IS_OK(r_u->status)) {
3174 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3175 continue;
3178 if (tmp_num_groups==0) {
3179 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3180 continue;
3183 new_rids=TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+tmp_num_groups);
3184 if (new_rids==NULL) {
3185 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3186 return NT_STATUS_NO_MEMORY;
3188 rids=new_rids;
3190 for (j=0; j<tmp_num_groups; j++)
3191 rids[j+num_groups]=tmp_rids[j];
3193 safe_free(tmp_rids);
3195 num_groups+=tmp_num_groups;
3198 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3199 return NT_STATUS_OK;
3202 /*********************************************************************
3203 _samr_query_aliasmem
3204 *********************************************************************/
3206 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3208 int i;
3210 int num_sids = 0;
3211 DOM_SID2 *sid;
3212 DOM_SID *sids=NULL;
3214 DOM_SID alias_sid;
3216 uint32 acc_granted;
3218 /* find the policy handle. open a policy on it. */
3219 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3220 return NT_STATUS_INVALID_HANDLE;
3222 if (!NT_STATUS_IS_OK(r_u->status =
3223 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3224 return r_u->status;
3227 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3229 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3230 return NT_STATUS_NO_SUCH_ALIAS;
3232 sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);
3233 if (num_sids!=0 && sid == NULL) {
3234 SAFE_FREE(sids);
3235 return NT_STATUS_NO_MEMORY;
3238 for (i = 0; i < num_sids; i++) {
3239 init_dom_sid2(&sid[i], &sids[i]);
3242 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3244 SAFE_FREE(sids);
3246 return NT_STATUS_OK;
3249 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3251 int i;
3253 for (i=0; i<*num; i++) {
3254 if ((*uids)[i] == uid)
3255 return;
3258 *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3260 if (*uids == NULL)
3261 return;
3263 (*uids)[*num] = uid;
3264 *num += 1;
3268 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3270 struct group *grp;
3271 char **gr;
3272 struct sys_pwent *userlist, *user;
3274 *uids = NULL;
3275 *num = 0;
3277 /* We only look at our own sam, so don't care about imported stuff */
3279 winbind_off();
3281 if ((grp = getgrgid(gid)) == NULL) {
3282 winbind_on();
3283 return False;
3286 /* Primary group members */
3288 userlist = getpwent_list();
3290 for (user = userlist; user != NULL; user = user->next) {
3291 if (user->pw_gid != gid)
3292 continue;
3293 add_uid_to_array_unique(user->pw_uid, uids, num);
3296 pwent_free(userlist);
3298 /* Secondary group members */
3300 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3301 struct passwd *pw = getpwnam(*gr);
3303 if (pw == NULL)
3304 continue;
3305 add_uid_to_array_unique(pw->pw_uid, uids, num);
3308 winbind_on();
3310 return True;
3313 /*********************************************************************
3314 _samr_query_groupmem
3315 *********************************************************************/
3317 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3319 int final_num_rids, i;
3320 DOM_SID group_sid;
3321 fstring group_sid_str;
3322 uid_t *uids;
3323 int num;
3324 gid_t gid;
3326 uint32 *rid=NULL;
3327 uint32 *attr=NULL;
3329 uint32 acc_granted;
3331 /* find the policy handle. open a policy on it. */
3332 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3333 return NT_STATUS_INVALID_HANDLE;
3335 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3336 return r_u->status;
3339 sid_to_string(group_sid_str, &group_sid);
3340 DEBUG(10, ("sid is %s\n", group_sid_str));
3342 if (!sid_check_is_in_our_domain(&group_sid)) {
3343 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3344 return NT_STATUS_NO_SUCH_GROUP;
3347 DEBUG(10, ("lookup on Domain SID\n"));
3349 if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3350 return NT_STATUS_NO_SUCH_GROUP;
3352 if(!get_memberuids(gid, &uids, &num))
3353 return NT_STATUS_NO_SUCH_GROUP;
3355 rid=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3356 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3358 if (num!=0 && (rid==NULL || attr==NULL))
3359 return NT_STATUS_NO_MEMORY;
3361 final_num_rids = 0;
3363 for (i=0; i<num; i++) {
3364 DOM_SID sid;
3366 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3367 DEBUG(1, ("Could not map member uid to SID\n"));
3368 continue;
3371 if (!sid_check_is_in_our_domain(&sid)) {
3372 DEBUG(1, ("Inconsistent SAM -- group member uid not "
3373 "in our domain\n"));
3374 continue;
3377 sid_peek_rid(&sid, &rid[final_num_rids]);
3379 /* Hmm. In a trace I got the constant 7 here from NT. */
3380 attr[final_num_rids] = SID_NAME_USER;
3382 final_num_rids += 1;
3385 SAFE_FREE(uids);
3387 init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3388 NT_STATUS_OK);
3390 return NT_STATUS_OK;
3393 /*********************************************************************
3394 _samr_add_aliasmem
3395 *********************************************************************/
3397 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3399 DOM_SID alias_sid;
3400 uint32 acc_granted;
3402 /* Find the policy handle. Open a policy on it. */
3403 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3404 return NT_STATUS_INVALID_HANDLE;
3406 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3407 return r_u->status;
3410 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3412 if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
3413 return NT_STATUS_ACCESS_DENIED;
3415 return NT_STATUS_OK;
3418 /*********************************************************************
3419 _samr_del_aliasmem
3420 *********************************************************************/
3422 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3424 DOM_SID alias_sid;
3425 uint32 acc_granted;
3427 /* Find the policy handle. Open a policy on it. */
3428 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3429 return NT_STATUS_INVALID_HANDLE;
3431 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3432 return r_u->status;
3435 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3436 sid_string_static(&alias_sid)));
3438 if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
3439 return NT_STATUS_ACCESS_DENIED;
3441 return NT_STATUS_OK;
3444 /*********************************************************************
3445 _samr_add_groupmem
3446 *********************************************************************/
3448 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3450 DOM_SID group_sid;
3451 DOM_SID user_sid;
3452 fstring group_sid_str;
3453 uid_t uid;
3454 struct passwd *pwd;
3455 struct group *grp;
3456 fstring grp_name;
3457 GROUP_MAP map;
3458 NTSTATUS ret;
3459 SAM_ACCOUNT *sam_user=NULL;
3460 BOOL check;
3461 uint32 acc_granted;
3463 /* Find the policy handle. Open a policy on it. */
3464 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3465 return NT_STATUS_INVALID_HANDLE;
3467 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3468 return r_u->status;
3471 sid_to_string(group_sid_str, &group_sid);
3472 DEBUG(10, ("sid is %s\n", group_sid_str));
3474 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3475 return NT_STATUS_NO_SUCH_GROUP;
3477 DEBUG(10, ("lookup on Domain SID\n"));
3479 if(!get_domain_group_from_sid(group_sid, &map))
3480 return NT_STATUS_NO_SUCH_GROUP;
3482 sid_copy(&user_sid, get_global_sam_sid());
3483 sid_append_rid(&user_sid, q_u->rid);
3485 ret = pdb_init_sam(&sam_user);
3486 if (!NT_STATUS_IS_OK(ret))
3487 return ret;
3489 check = pdb_getsampwsid(sam_user, &user_sid);
3491 if (check != True) {
3492 pdb_free_sam(&sam_user);
3493 return NT_STATUS_NO_SUCH_USER;
3496 /* check a real user exist before we run the script to add a user to a group */
3497 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3498 pdb_free_sam(&sam_user);
3499 return NT_STATUS_NO_SUCH_USER;
3502 pdb_free_sam(&sam_user);
3504 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3505 return NT_STATUS_NO_SUCH_USER;
3508 if ((grp=getgrgid(map.gid)) == NULL) {
3509 passwd_free(&pwd);
3510 return NT_STATUS_NO_SUCH_GROUP;
3513 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3514 fstrcpy(grp_name, grp->gr_name);
3516 /* if the user is already in the group */
3517 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3518 passwd_free(&pwd);
3519 return NT_STATUS_MEMBER_IN_GROUP;
3523 * ok, the group exist, the user exist, the user is not in the group,
3525 * we can (finally) add it to the group !
3528 smb_add_user_group(grp_name, pwd->pw_name);
3530 /* check if the user has been added then ... */
3531 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3532 passwd_free(&pwd);
3533 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3536 passwd_free(&pwd);
3537 return NT_STATUS_OK;
3540 /*********************************************************************
3541 _samr_del_groupmem
3542 *********************************************************************/
3544 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3546 DOM_SID group_sid;
3547 DOM_SID user_sid;
3548 SAM_ACCOUNT *sam_pass=NULL;
3549 GROUP_MAP map;
3550 fstring grp_name;
3551 struct group *grp;
3552 uint32 acc_granted;
3555 * delete the group member named q_u->rid
3556 * who is a member of the sid associated with the handle
3557 * the rid is a user's rid as the group is a domain group.
3560 /* Find the policy handle. Open a policy on it. */
3561 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3562 return NT_STATUS_INVALID_HANDLE;
3564 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3565 return r_u->status;
3568 if (!sid_check_is_in_our_domain(&group_sid))
3569 return NT_STATUS_NO_SUCH_GROUP;
3571 sid_copy(&user_sid, get_global_sam_sid());
3572 sid_append_rid(&user_sid, q_u->rid);
3574 if (!get_domain_group_from_sid(group_sid, &map))
3575 return NT_STATUS_NO_SUCH_GROUP;
3577 if ((grp=getgrgid(map.gid)) == NULL)
3578 return NT_STATUS_NO_SUCH_GROUP;
3580 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3581 fstrcpy(grp_name, grp->gr_name);
3583 /* check if the user exists before trying to remove it from the group */
3584 pdb_init_sam(&sam_pass);
3585 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3586 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3587 pdb_free_sam(&sam_pass);
3588 return NT_STATUS_NO_SUCH_USER;
3591 /* if the user is not in the group */
3592 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3593 pdb_free_sam(&sam_pass);
3594 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3597 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3599 /* check if the user has been removed then ... */
3600 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3601 pdb_free_sam(&sam_pass);
3602 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3605 pdb_free_sam(&sam_pass);
3606 return NT_STATUS_OK;
3610 /****************************************************************************
3611 Delete a UNIX user on demand.
3612 ****************************************************************************/
3614 static int smb_delete_user(const char *unix_user)
3616 pstring del_script;
3617 int ret;
3619 /* try winbindd first since it is impossible to determine where
3620 a user came from via NSS. Try the delete user script if this fails
3621 meaning the user did not exist in winbindd's list of accounts */
3623 if ( winbind_delete_user( unix_user ) ) {
3624 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3625 return 0;
3629 /* fall back to 'delete user script' */
3631 pstrcpy(del_script, lp_deluser_script());
3632 if (! *del_script)
3633 return -1;
3634 all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3635 ret = smbrun(del_script,NULL);
3636 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3638 return ret;
3641 /*********************************************************************
3642 _samr_delete_dom_user
3643 *********************************************************************/
3645 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3647 DOM_SID user_sid;
3648 SAM_ACCOUNT *sam_pass=NULL;
3649 uint32 acc_granted;
3651 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3653 /* Find the policy handle. Open a policy on it. */
3654 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3655 return NT_STATUS_INVALID_HANDLE;
3657 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3658 return r_u->status;
3661 if (!sid_check_is_in_our_domain(&user_sid))
3662 return NT_STATUS_CANNOT_DELETE;
3664 /* check if the user exists before trying to delete */
3665 pdb_init_sam(&sam_pass);
3666 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3667 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3668 sid_string_static(&user_sid)));
3669 pdb_free_sam(&sam_pass);
3670 return NT_STATUS_NO_SUCH_USER;
3673 /* First delete the samba side */
3674 if (!pdb_delete_sam_account(sam_pass)) {
3675 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3676 pdb_free_sam(&sam_pass);
3677 return NT_STATUS_CANNOT_DELETE;
3680 /* Now delete the unix side */
3682 * note: we don't check if the delete really happened
3683 * as the script is not necessary present
3684 * and maybe the sysadmin doesn't want to delete the unix side
3686 smb_delete_user(pdb_get_username(sam_pass));
3689 pdb_free_sam(&sam_pass);
3691 if (!close_policy_hnd(p, &q_u->user_pol))
3692 return NT_STATUS_OBJECT_NAME_INVALID;
3694 return NT_STATUS_OK;
3697 /*********************************************************************
3698 _samr_delete_dom_group
3699 *********************************************************************/
3701 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3703 DOM_SID group_sid;
3704 DOM_SID dom_sid;
3705 uint32 group_rid;
3706 fstring group_sid_str;
3707 gid_t gid;
3708 struct group *grp;
3709 GROUP_MAP map;
3710 uint32 acc_granted;
3712 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3714 /* Find the policy handle. Open a policy on it. */
3715 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3716 return NT_STATUS_INVALID_HANDLE;
3718 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3719 return r_u->status;
3722 sid_copy(&dom_sid, &group_sid);
3723 sid_to_string(group_sid_str, &dom_sid);
3724 sid_split_rid(&dom_sid, &group_rid);
3726 DEBUG(10, ("sid is %s\n", group_sid_str));
3728 /* we check if it's our SID before deleting */
3729 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3730 return NT_STATUS_NO_SUCH_GROUP;
3732 DEBUG(10, ("lookup on Domain SID\n"));
3734 if(!get_domain_group_from_sid(group_sid, &map))
3735 return NT_STATUS_NO_SUCH_GROUP;
3737 gid=map.gid;
3739 /* check if group really exists */
3740 if ( (grp=getgrgid(gid)) == NULL)
3741 return NT_STATUS_NO_SUCH_GROUP;
3743 /* delete mapping first */
3744 if(!pdb_delete_group_mapping_entry(group_sid))
3745 return NT_STATUS_ACCESS_DENIED;
3747 /* we can delete the UNIX group */
3748 smb_delete_group(grp->gr_name);
3750 /* check if the group has been successfully deleted */
3751 if ( (grp=getgrgid(gid)) != NULL)
3752 return NT_STATUS_ACCESS_DENIED;
3755 if (!close_policy_hnd(p, &q_u->group_pol))
3756 return NT_STATUS_OBJECT_NAME_INVALID;
3758 return NT_STATUS_OK;
3761 /*********************************************************************
3762 _samr_delete_dom_alias
3763 *********************************************************************/
3765 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3767 DOM_SID alias_sid;
3768 uint32 acc_granted;
3770 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3772 /* Find the policy handle. Open a policy on it. */
3773 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3774 return NT_STATUS_INVALID_HANDLE;
3776 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3777 return r_u->status;
3780 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3782 if (!sid_check_is_in_our_domain(&alias_sid))
3783 return NT_STATUS_NO_SUCH_ALIAS;
3785 DEBUG(10, ("lookup on Local SID\n"));
3787 /* Have passdb delete the alias */
3788 if (!pdb_delete_alias(&alias_sid))
3789 return NT_STATUS_ACCESS_DENIED;
3791 if (!close_policy_hnd(p, &q_u->alias_pol))
3792 return NT_STATUS_OBJECT_NAME_INVALID;
3794 return NT_STATUS_OK;
3797 /*********************************************************************
3798 _samr_create_dom_group
3799 *********************************************************************/
3801 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3803 DOM_SID dom_sid;
3804 DOM_SID info_sid;
3805 fstring name;
3806 fstring sid_string;
3807 struct group *grp;
3808 struct samr_info *info;
3809 uint32 acc_granted;
3810 gid_t gid;
3812 /* Find the policy handle. Open a policy on it. */
3813 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3814 return NT_STATUS_INVALID_HANDLE;
3816 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3817 return r_u->status;
3820 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3821 return NT_STATUS_ACCESS_DENIED;
3823 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3825 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3827 /* check if group already exist */
3828 if ((grp=getgrnam(name)) != NULL)
3829 return NT_STATUS_GROUP_EXISTS;
3831 /* we can create the UNIX group */
3832 if (smb_create_group(name, &gid) != 0)
3833 return NT_STATUS_ACCESS_DENIED;
3835 /* check if the group has been successfully created */
3836 if ((grp=getgrgid(gid)) == NULL)
3837 return NT_STATUS_ACCESS_DENIED;
3839 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3841 /* add the group to the mapping table */
3842 sid_copy(&info_sid, get_global_sam_sid());
3843 sid_append_rid(&info_sid, r_u->rid);
3844 sid_to_string(sid_string, &info_sid);
3846 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3847 return NT_STATUS_ACCESS_DENIED;
3849 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3850 return NT_STATUS_NO_MEMORY;
3852 /* get a (unique) handle. open a policy on it. */
3853 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3854 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3856 return NT_STATUS_OK;
3859 /*********************************************************************
3860 _samr_create_dom_alias
3861 *********************************************************************/
3863 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3865 DOM_SID dom_sid;
3866 DOM_SID info_sid;
3867 fstring name;
3868 struct group *grp;
3869 struct samr_info *info;
3870 uint32 acc_granted;
3871 gid_t gid;
3872 NTSTATUS result;
3874 /* Find the policy handle. Open a policy on it. */
3875 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3876 return NT_STATUS_INVALID_HANDLE;
3878 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3879 return r_u->status;
3882 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3883 return NT_STATUS_ACCESS_DENIED;
3885 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3887 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3889 /* Have passdb create the alias */
3890 result = pdb_create_alias(name, &r_u->rid);
3892 if (!NT_STATUS_IS_OK(result))
3893 return result;
3895 sid_copy(&info_sid, get_global_sam_sid());
3896 sid_append_rid(&info_sid, r_u->rid);
3898 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
3899 return NT_STATUS_ACCESS_DENIED;
3901 /* check if the group has been successfully created */
3902 if ((grp=getgrgid(gid)) == NULL)
3903 return NT_STATUS_ACCESS_DENIED;
3905 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3906 return NT_STATUS_NO_MEMORY;
3908 /* get a (unique) handle. open a policy on it. */
3909 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3910 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3912 return NT_STATUS_OK;
3915 /*********************************************************************
3916 _samr_query_groupinfo
3918 sends the name/comment pair of a domain group
3919 level 1 send also the number of users of that group
3920 *********************************************************************/
3922 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3924 DOM_SID group_sid;
3925 GROUP_MAP map;
3926 DOM_SID *sids=NULL;
3927 uid_t *uids;
3928 int num=0;
3929 GROUP_INFO_CTR *ctr;
3930 uint32 acc_granted;
3931 BOOL ret;
3933 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3934 return NT_STATUS_INVALID_HANDLE;
3936 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
3937 return r_u->status;
3940 become_root();
3941 ret = get_domain_group_from_sid(group_sid, &map);
3942 unbecome_root();
3943 if (!ret)
3944 return NT_STATUS_INVALID_HANDLE;
3946 ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
3947 if (ctr==NULL)
3948 return NT_STATUS_NO_MEMORY;
3950 switch (q_u->switch_level) {
3951 case 1:
3952 ctr->switch_value1 = 1;
3953 if(!get_memberuids(map.gid, &uids, &num))
3954 return NT_STATUS_NO_SUCH_GROUP;
3955 SAFE_FREE(uids);
3956 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
3957 SAFE_FREE(sids);
3958 break;
3959 case 3:
3960 ctr->switch_value1 = 3;
3961 init_samr_group_info3(&ctr->group.info3);
3962 break;
3963 case 4:
3964 ctr->switch_value1 = 4;
3965 init_samr_group_info4(&ctr->group.info4, map.comment);
3966 break;
3967 default:
3968 return NT_STATUS_INVALID_INFO_CLASS;
3971 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
3973 return NT_STATUS_OK;
3976 /*********************************************************************
3977 _samr_set_groupinfo
3979 update a domain group's comment.
3980 *********************************************************************/
3982 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
3984 DOM_SID group_sid;
3985 GROUP_MAP map;
3986 GROUP_INFO_CTR *ctr;
3987 uint32 acc_granted;
3989 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3990 return NT_STATUS_INVALID_HANDLE;
3992 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
3993 return r_u->status;
3996 if (!get_domain_group_from_sid(group_sid, &map))
3997 return NT_STATUS_NO_SUCH_GROUP;
3999 ctr=q_u->ctr;
4001 switch (ctr->switch_value1) {
4002 case 1:
4003 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4004 break;
4005 case 4:
4006 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4007 break;
4008 default:
4009 return NT_STATUS_INVALID_INFO_CLASS;
4012 if(!pdb_update_group_mapping_entry(&map)) {
4013 return NT_STATUS_NO_SUCH_GROUP;
4016 return NT_STATUS_OK;
4019 /*********************************************************************
4020 _samr_set_aliasinfo
4022 update an alias's comment.
4023 *********************************************************************/
4025 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4027 DOM_SID group_sid;
4028 struct acct_info info;
4029 ALIAS_INFO_CTR *ctr;
4030 uint32 acc_granted;
4032 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4033 return NT_STATUS_INVALID_HANDLE;
4035 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4036 return r_u->status;
4039 ctr=&q_u->ctr;
4041 switch (ctr->switch_value1) {
4042 case 3:
4043 unistr2_to_ascii(info.acct_desc,
4044 &(ctr->alias.info3.uni_acct_desc),
4045 sizeof(info.acct_desc)-1);
4046 break;
4047 default:
4048 return NT_STATUS_INVALID_INFO_CLASS;
4051 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4052 return NT_STATUS_ACCESS_DENIED;
4055 return NT_STATUS_OK;
4058 /*********************************************************************
4059 _samr_get_dom_pwinfo
4060 *********************************************************************/
4062 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4064 /* Perform access check. Since this rpc does not require a
4065 policy handle it will not be caught by the access checks on
4066 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4068 if (!pipe_access_check(p)) {
4069 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4070 r_u->status = NT_STATUS_ACCESS_DENIED;
4071 return r_u->status;
4074 /* Actually, returning zeros here works quite well :-). */
4076 return NT_STATUS_OK;
4079 /*********************************************************************
4080 _samr_open_group
4081 *********************************************************************/
4083 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4085 DOM_SID sid;
4086 DOM_SID info_sid;
4087 GROUP_MAP map;
4088 struct samr_info *info;
4089 SEC_DESC *psd = NULL;
4090 uint32 acc_granted;
4091 uint32 des_access = q_u->access_mask;
4092 size_t sd_size;
4093 NTSTATUS status;
4094 fstring sid_string;
4095 BOOL ret;
4097 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4098 return NT_STATUS_INVALID_HANDLE;
4100 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4101 return status;
4104 /*check if access can be granted as requested by client. */
4105 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4106 se_map_generic(&des_access,&grp_generic_mapping);
4107 if (!NT_STATUS_IS_OK(status =
4108 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4109 des_access, &acc_granted, "_samr_open_group"))) {
4110 return status;
4114 /* this should not be hard-coded like this */
4115 if (!sid_equal(&sid, get_global_sam_sid()))
4116 return NT_STATUS_ACCESS_DENIED;
4118 sid_copy(&info_sid, get_global_sam_sid());
4119 sid_append_rid(&info_sid, q_u->rid_group);
4120 sid_to_string(sid_string, &info_sid);
4122 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4123 return NT_STATUS_NO_MEMORY;
4125 info->acc_granted = acc_granted;
4127 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4129 /* check if that group really exists */
4130 become_root();
4131 ret = get_domain_group_from_sid(info->sid, &map);
4132 unbecome_root();
4133 if (!ret)
4134 return NT_STATUS_NO_SUCH_GROUP;
4136 /* get a (unique) handle. open a policy on it. */
4137 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4138 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4140 return NT_STATUS_OK;
4143 /*********************************************************************
4144 _samr_remove_sid_foreign_domain
4145 *********************************************************************/
4147 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4148 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4149 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4151 DOM_SID delete_sid, alias_sid;
4152 SAM_ACCOUNT *sam_pass=NULL;
4153 uint32 acc_granted;
4154 GROUP_MAP map;
4155 BOOL is_user = False;
4156 NTSTATUS result;
4157 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4159 sid_copy( &delete_sid, &q_u->sid.sid );
4161 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4162 sid_string_static(&delete_sid)));
4164 /* Find the policy handle. Open a policy on it. */
4166 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4167 return NT_STATUS_INVALID_HANDLE;
4169 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4170 "_samr_remove_sid_foreign_domain");
4172 if (!NT_STATUS_IS_OK(result))
4173 return result;
4175 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4176 sid_string_static(&alias_sid)));
4178 /* make sure we can handle this */
4180 if ( sid_check_is_domain(&alias_sid) )
4181 type = SID_NAME_DOM_GRP;
4182 else if ( sid_check_is_builtin(&alias_sid) )
4183 type = SID_NAME_ALIAS;
4185 if ( type == SID_NAME_UNKNOWN ) {
4186 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4187 return NT_STATUS_OK;
4190 /* check if the user exists before trying to delete */
4192 pdb_init_sam(&sam_pass);
4194 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4195 is_user = True;
4196 } else {
4197 /* maybe it is a group */
4198 if( !pdb_getgrsid(&map, delete_sid) ) {
4199 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4200 sid_string_static(&delete_sid)));
4201 result = NT_STATUS_INVALID_SID;
4202 goto done;
4206 /* we can only delete a user from a group since we don't have
4207 nested groups anyways. So in the latter case, just say OK */
4209 if ( is_user ) {
4210 GROUP_MAP *mappings = NULL;
4211 int num_groups, i;
4212 struct group *grp2;
4214 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4216 /* interate over the groups */
4217 for ( i=0; i<num_groups; i++ ) {
4219 grp2 = getgrgid(mappings[i].gid);
4221 if ( !grp2 ) {
4222 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4223 continue;
4226 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4227 continue;
4229 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4231 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4232 /* should we fail here ? */
4233 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4234 pdb_get_username(sam_pass), grp2->gr_name ));
4235 continue;
4238 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4239 pdb_get_username(sam_pass), grp2->gr_name ));
4242 SAFE_FREE(mappings);
4246 result = NT_STATUS_OK;
4247 done:
4249 pdb_free_sam(&sam_pass);
4251 return result;
4254 /*******************************************************************
4255 _samr_unknown_2e
4256 ********************************************************************/
4258 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4260 struct samr_info *info = NULL;
4261 SAM_UNK_CTR *ctr;
4262 uint32 min_pass_len,pass_hist,flag;
4263 time_t u_expire, u_min_age;
4264 NTTIME nt_expire, nt_min_age;
4266 time_t u_lock_duration, u_reset_time;
4267 NTTIME nt_lock_duration, nt_reset_time;
4268 uint32 lockout;
4270 time_t u_logout;
4271 NTTIME nt_logout;
4273 uint32 num_users=0, num_groups=0, num_aliases=0;
4275 uint32 account_policy_temp;
4277 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4278 return NT_STATUS_NO_MEMORY;
4280 ZERO_STRUCTP(ctr);
4282 r_u->status = NT_STATUS_OK;
4284 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4286 /* find the policy handle. open a policy on it. */
4287 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4288 return NT_STATUS_INVALID_HANDLE;
4290 switch (q_u->switch_value) {
4291 case 0x01:
4292 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4293 min_pass_len = account_policy_temp;
4295 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4296 pass_hist = account_policy_temp;
4298 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4299 flag = account_policy_temp;
4301 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4302 u_expire = account_policy_temp;
4304 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4305 u_min_age = account_policy_temp;
4307 unix_to_nt_time_abs(&nt_expire, u_expire);
4308 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4310 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4311 flag, nt_expire, nt_min_age);
4312 break;
4313 case 0x02:
4314 become_root();
4315 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4316 unbecome_root();
4317 if (!NT_STATUS_IS_OK(r_u->status)) {
4318 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4319 return r_u->status;
4321 num_users=info->disp_info.num_user_account;
4322 free_samr_db(info);
4324 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4325 if (NT_STATUS_IS_ERR(r_u->status)) {
4326 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4327 return r_u->status;
4329 num_groups=info->disp_info.num_group_account;
4330 free_samr_db(info);
4332 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4333 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4334 num_users, num_groups, num_aliases);
4335 break;
4336 case 0x03:
4337 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4338 u_logout = account_policy_temp;
4340 unix_to_nt_time_abs(&nt_logout, u_logout);
4342 init_unk_info3(&ctr->info.inf3, nt_logout);
4343 break;
4344 case 0x05:
4345 init_unk_info5(&ctr->info.inf5, global_myname());
4346 break;
4347 case 0x06:
4348 init_unk_info6(&ctr->info.inf6);
4349 break;
4350 case 0x07:
4351 init_unk_info7(&ctr->info.inf7);
4352 break;
4353 case 0x0c:
4354 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4355 u_lock_duration = account_policy_temp * 60;
4357 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4358 u_reset_time = account_policy_temp * 60;
4360 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4361 lockout = account_policy_temp;
4363 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4364 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4366 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4367 break;
4368 default:
4369 return NT_STATUS_INVALID_INFO_CLASS;
4372 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4374 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4376 return r_u->status;
4379 /*******************************************************************
4380 _samr_
4381 ********************************************************************/
4383 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4385 time_t u_expire, u_min_age;
4386 time_t u_logout;
4387 time_t u_lock_duration, u_reset_time;
4389 r_u->status = NT_STATUS_OK;
4391 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4393 /* find the policy handle. open a policy on it. */
4394 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4395 return NT_STATUS_INVALID_HANDLE;
4397 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4399 switch (q_u->switch_value) {
4400 case 0x01:
4401 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4402 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4404 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4405 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4406 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4407 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4408 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4409 break;
4410 case 0x02:
4411 break;
4412 case 0x03:
4413 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4414 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4415 break;
4416 case 0x05:
4417 break;
4418 case 0x06:
4419 break;
4420 case 0x07:
4421 break;
4422 case 0x0c:
4423 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
4424 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4426 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4427 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4428 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4429 break;
4430 default:
4431 return NT_STATUS_INVALID_INFO_CLASS;
4434 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4436 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4438 return r_u->status;