r2565: syncing up for 3.0.8pre1
[Samba.git] / source / rpc_server / srv_samr_nt.c
blob37617db5e8fc2c5a58bf38ef079b2ba1565a2b1d
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
11 * Copyright (C) Gerald (Jerry) Carter 2003,
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
32 #include "includes.h"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
44 typedef struct _disp_info {
45 BOOL user_dbloaded;
46 uint32 num_user_account;
47 SAM_ACCOUNT *disp_user_info;
48 BOOL group_dbloaded;
49 uint32 num_group_account;
50 DOMAIN_GRP *disp_group_info;
51 } DISP_INFO;
53 struct samr_info {
54 /* for use by the \PIPE\samr policy */
55 DOM_SID sid;
56 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
57 uint32 acc_granted;
58 uint16 acb_mask;
59 BOOL all_machines;
60 DISP_INFO disp_info;
62 TALLOC_CTX *mem_ctx;
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
79 uint32 *acc_granted, const char *debug)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
83 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84 *acc_granted = des_access;
85 if (geteuid() == sec_initial_uid()) {
86 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
87 debug, des_access));
88 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89 status = NT_STATUS_OK;
91 else {
92 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
93 debug, des_access));
96 return status;
99 /*******************************************************************
100 Checks if access to a function can be granted
101 ********************************************************************/
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
105 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
106 debug, acc_granted, acc_required));
107 if ((acc_granted & acc_required) != acc_required) {
108 if (geteuid() == sec_initial_uid()) {
109 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
110 debug, acc_granted, acc_required));
111 DEBUGADD(4,("but overwritten by euid == 0\n"));
112 return NT_STATUS_OK;
114 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
115 debug, acc_granted, acc_required));
116 return NT_STATUS_ACCESS_DENIED;
118 return NT_STATUS_OK;
122 /*******************************************************************
123 Create a samr_info struct.
124 ********************************************************************/
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
128 struct samr_info *info;
129 fstring sid_str;
130 TALLOC_CTX *mem_ctx;
132 if (psid) {
133 sid_to_string(sid_str, psid);
134 } else {
135 fstrcpy(sid_str,"(NULL)");
138 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
140 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
141 return NULL;
143 ZERO_STRUCTP(info);
144 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
145 if (psid) {
146 sid_copy( &info->sid, psid);
147 } else {
148 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
150 info->mem_ctx = mem_ctx;
151 return info;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
158 static void free_samr_users(struct samr_info *info)
160 int i;
162 if (info->disp_info.user_dbloaded){
163 for (i=0; i<info->disp_info.num_user_account; i++) {
164 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165 /* Not really a free, actually a 'clear' */
166 pdb_free_sam(&sam);
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
187 static void free_samr_info(void *ptr)
189 struct samr_info *info=(struct samr_info *) ptr;
191 free_samr_db(info);
192 talloc_destroy(info->mem_ctx);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
202 if (!sam_pass)
203 return;
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
214 SAM_ACCOUNT *pwd = NULL;
215 SAM_ACCOUNT *pwd_array = NULL;
216 NTSTATUS nt_status = NT_STATUS_OK;
217 TALLOC_CTX *mem_ctx = info->mem_ctx;
219 DEBUG(10,("load_sampwd_entries\n"));
221 /* if the snapshoot is already loaded, return */
222 if ((info->disp_info.user_dbloaded==True)
223 && (info->acb_mask == acb_mask)
224 && (info->all_machines == all_machines)) {
225 DEBUG(10,("load_sampwd_entries: already in memory\n"));
226 return NT_STATUS_OK;
229 free_samr_users(info);
231 if (!pdb_setsampwent(False)) {
232 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233 return NT_STATUS_ACCESS_DENIED;
236 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
237 && pdb_getsampwent(pwd) == True; pwd=NULL) {
239 if (all_machines) {
240 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
241 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
243 pdb_free_sam(&pwd);
244 continue;
246 } else {
247 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
248 pdb_free_sam(&pwd);
249 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
250 continue;
254 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
257 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258 pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
259 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
261 if (pwd_array==NULL)
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* Copy the SAM_ACCOUNT into the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
270 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
272 info->disp_info.num_user_account++;
275 pdb_endsampwent();
277 /* the snapshoot is in memory, we're ready to enumerate fast */
279 info->acb_mask = acb_mask;
280 info->all_machines = all_machines;
281 info->disp_info.user_dbloaded=True;
283 DEBUG(10,("load_sampwd_entries: done\n"));
285 return nt_status;
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
290 GROUP_MAP *map=NULL;
291 DOMAIN_GRP *grp_array = NULL;
292 uint32 group_entries = 0;
293 uint32 i;
294 TALLOC_CTX *mem_ctx = info->mem_ctx;
295 BOOL ret;
297 DEBUG(10,("load_group_domain_entries\n"));
299 /* if the snapshoot is already loaded, return */
300 if (info->disp_info.group_dbloaded==True) {
301 DEBUG(10,("load_group_domain_entries: already in memory\n"));
302 return NT_STATUS_OK;
305 if (sid_equal(sid, &global_sid_Builtin)) {
306 /* No domain groups for now in the BUILTIN domain */
307 info->disp_info.num_group_account=0;
308 info->disp_info.disp_group_info=NULL;
309 info->disp_info.group_dbloaded=True;
310 return NT_STATUS_OK;
313 become_root();
314 ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
315 unbecome_root();
317 if ( !ret ) {
318 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
319 return NT_STATUS_NO_MEMORY;
323 info->disp_info.num_group_account=group_entries;
325 grp_array=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
326 if (group_entries!=0 && grp_array==NULL) {
327 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
328 SAFE_FREE(map);
329 return NT_STATUS_NO_MEMORY;
332 info->disp_info.disp_group_info=grp_array;
334 for (i=0; i<group_entries; i++) {
335 fstrcpy(grp_array[i].name, map[i].nt_name);
336 fstrcpy(grp_array[i].comment, map[i].comment);
337 sid_split_rid(&map[i].sid, &grp_array[i].rid);
338 grp_array[i].attr=SID_NAME_DOM_GRP;
341 SAFE_FREE(map);
343 /* the snapshoot is in memory, we're ready to enumerate fast */
345 info->disp_info.group_dbloaded=True;
347 DEBUG(10,("load_group_domain_entries: done\n"));
349 return NT_STATUS_OK;
353 /*******************************************************************
354 _samr_close_hnd
355 ********************************************************************/
357 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
359 r_u->status = NT_STATUS_OK;
361 /* close the policy handle */
362 if (!close_policy_hnd(p, &q_u->pol))
363 return NT_STATUS_OBJECT_NAME_INVALID;
365 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
367 return r_u->status;
370 /*******************************************************************
371 samr_reply_open_domain
372 ********************************************************************/
374 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
376 struct samr_info *info;
377 SEC_DESC *psd = NULL;
378 uint32 acc_granted;
379 uint32 des_access = q_u->flags;
380 size_t sd_size;
381 NTSTATUS status;
383 r_u->status = NT_STATUS_OK;
385 /* find the connection policy handle. */
386 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
387 return NT_STATUS_INVALID_HANDLE;
389 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
390 return status;
393 /*check if access can be granted as requested by client. */
394 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
395 se_map_generic(&des_access,&dom_generic_mapping);
397 if (!NT_STATUS_IS_OK(status =
398 access_check_samr_object(psd, p->pipe_user.nt_user_token,
399 des_access, &acc_granted, "_samr_open_domain"))) {
400 return status;
403 /* associate the domain SID with the (unique) handle. */
404 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
405 return NT_STATUS_NO_MEMORY;
406 info->acc_granted = acc_granted;
408 /* get a (unique) handle. open a policy on it. */
409 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
410 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
412 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
414 return r_u->status;
417 /*******************************************************************
418 _samr_get_usrdom_pwinfo
419 ********************************************************************/
421 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
423 struct samr_info *info = NULL;
425 r_u->status = NT_STATUS_OK;
427 /* find the policy handle. open a policy on it. */
428 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
429 return NT_STATUS_INVALID_HANDLE;
431 if (!sid_check_is_in_our_domain(&info->sid))
432 return NT_STATUS_OBJECT_TYPE_MISMATCH;
434 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
436 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
439 * NT sometimes return NT_STATUS_ACCESS_DENIED
440 * I don't know yet why.
443 return r_u->status;
446 /*******************************************************************
447 samr_make_dom_obj_sd
448 ********************************************************************/
450 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
452 extern DOM_SID global_sid_World;
453 DOM_SID adm_sid;
454 DOM_SID act_sid;
456 SEC_ACE ace[3];
457 SEC_ACCESS mask;
459 SEC_ACL *psa = NULL;
461 sid_copy(&adm_sid, &global_sid_Builtin);
462 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
464 sid_copy(&act_sid, &global_sid_Builtin);
465 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
467 /*basic access for every one*/
468 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
469 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
471 /*full access for builtin aliases Administrators and Account Operators*/
472 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
473 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
474 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
476 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
477 return NT_STATUS_NO_MEMORY;
479 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
480 return NT_STATUS_NO_MEMORY;
482 return NT_STATUS_OK;
485 /*******************************************************************
486 samr_make_usr_obj_sd
487 ********************************************************************/
489 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
491 extern DOM_SID global_sid_World;
492 DOM_SID adm_sid;
493 DOM_SID act_sid;
495 SEC_ACE ace[4];
496 SEC_ACCESS mask;
498 SEC_ACL *psa = NULL;
500 sid_copy(&adm_sid, &global_sid_Builtin);
501 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
503 sid_copy(&act_sid, &global_sid_Builtin);
504 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
506 /*basic access for every one*/
507 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
508 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 /*full access for builtin aliases Administrators and Account Operators*/
511 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
512 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
513 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
515 /*extended access for the user*/
516 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
517 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
519 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
520 return NT_STATUS_NO_MEMORY;
522 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
523 return NT_STATUS_NO_MEMORY;
525 return NT_STATUS_OK;
528 /*******************************************************************
529 samr_make_grp_obj_sd
530 ********************************************************************/
532 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
534 extern DOM_SID global_sid_World;
535 DOM_SID adm_sid;
536 DOM_SID act_sid;
538 SEC_ACE ace[3];
539 SEC_ACCESS mask;
541 SEC_ACL *psa = NULL;
543 sid_copy(&adm_sid, &global_sid_Builtin);
544 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
546 sid_copy(&act_sid, &global_sid_Builtin);
547 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
549 /*basic access for every one*/
550 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
551 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
553 /*full access for builtin aliases Administrators and Account Operators*/
554 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
555 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
556 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
558 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
559 return NT_STATUS_NO_MEMORY;
561 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
562 return NT_STATUS_NO_MEMORY;
564 return NT_STATUS_OK;
567 /*******************************************************************
568 samr_make_ali_obj_sd
569 ********************************************************************/
571 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
573 extern DOM_SID global_sid_World;
574 DOM_SID adm_sid;
575 DOM_SID act_sid;
577 SEC_ACE ace[3];
578 SEC_ACCESS mask;
580 SEC_ACL *psa = NULL;
582 sid_copy(&adm_sid, &global_sid_Builtin);
583 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
585 sid_copy(&act_sid, &global_sid_Builtin);
586 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
588 /*basic access for every one*/
589 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
590 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
592 /*full access for builtin aliases Administrators and Account Operators*/
593 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
594 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
595 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
597 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
598 return NT_STATUS_NO_MEMORY;
600 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
601 return NT_STATUS_NO_MEMORY;
603 return NT_STATUS_OK;
606 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
608 struct samr_info *info = NULL;
610 /* find the policy handle. open a policy on it. */
611 if (!find_policy_by_hnd(p, pol, (void **)&info))
612 return False;
614 if (!info)
615 return False;
617 *sid = info->sid;
618 *acc_granted = info->acc_granted;
619 return True;
622 /*******************************************************************
623 _samr_set_sec_obj
624 ********************************************************************/
626 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
628 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
629 return NT_STATUS_NOT_IMPLEMENTED;
633 /*******************************************************************
634 _samr_query_sec_obj
635 ********************************************************************/
637 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
639 DOM_SID pol_sid;
640 fstring str_sid;
641 SEC_DESC * psd = NULL;
642 size_t sd_size;
643 uint32 acc_granted;
645 r_u->status = NT_STATUS_OK;
647 /* Get the SID. */
648 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
649 return NT_STATUS_INVALID_HANDLE;
653 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
655 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
657 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
658 if (pol_sid.sid_rev_num == 0)
660 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
661 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
663 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
666 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
667 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
669 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
671 /* TODO: Builtin probably needs a different SD with restricted write access*/
672 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
673 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
675 else if (sid_check_is_in_our_domain(&pol_sid) ||
676 sid_check_is_in_builtin(&pol_sid))
678 /* TODO: different SDs have to be generated for aliases groups and users.
679 Currently all three get a default user SD */
680 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
681 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
683 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
685 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
686 return NT_STATUS_NO_MEMORY;
688 if (NT_STATUS_IS_OK(r_u->status))
689 r_u->ptr = 1;
691 return r_u->status;
694 /*******************************************************************
695 makes a SAM_ENTRY / UNISTR2* structure from a user list.
696 ********************************************************************/
698 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
699 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
700 DOM_SID *domain_sid)
702 uint32 i;
703 SAM_ENTRY *sam;
704 UNISTR2 *uni_name;
705 SAM_ACCOUNT *pwd = NULL;
706 UNISTR2 uni_temp_name;
707 const char *temp_name;
708 const DOM_SID *user_sid;
709 uint32 user_rid;
710 fstring user_sid_string;
711 fstring domain_sid_string;
713 *sam_pp = NULL;
714 *uni_name_pp = NULL;
716 if (num_entries == 0)
717 return NT_STATUS_OK;
719 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
721 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
723 if (sam == NULL || uni_name == NULL) {
724 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
725 return NT_STATUS_NO_MEMORY;
728 for (i = 0; i < num_entries; i++) {
729 pwd = &disp_user_info[i+start_idx];
730 temp_name = pdb_get_username(pwd);
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 = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
876 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
878 if (sam == NULL || uni_name == NULL) {
879 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
880 return;
883 for (i = 0; i < num_sam_entries; i++) {
885 * JRA. I think this should include the null. TNG does not.
887 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
888 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
891 *sam_pp = sam;
892 *uni_name_pp = uni_name;
895 /*******************************************************************
896 Get the group entries - similar to get_sampwd_entries().
897 ******************************************************************/
899 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
900 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
901 uint32 *p_num_entries, uint32 max_entries )
903 GROUP_MAP *map=NULL;
904 int i;
905 uint32 group_entries = 0;
906 uint32 num_entries = 0;
908 *p_num_entries = 0;
910 /* access checks for the users were performed higher up. become/unbecome_root()
911 needed for some passdb backends to enumerate groups */
913 become_root();
914 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
915 ENUM_ONLY_MAPPED);
916 unbecome_root();
918 num_entries=group_entries-start_idx;
920 /* limit the number of entries */
921 if (num_entries>max_entries) {
922 DEBUG(5,("Limiting to %d entries\n", max_entries));
923 num_entries=max_entries;
926 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
927 if (num_entries!=0 && *d_grp==NULL){
928 SAFE_FREE(map);
929 return NT_STATUS_NO_MEMORY;
932 for (i=0; i<num_entries; i++) {
933 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
934 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
935 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
936 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
939 SAFE_FREE(map);
941 *p_num_entries = num_entries;
943 DEBUG(10,("get_group_domain_entries: returning %d entries\n",
944 *p_num_entries));
946 return NT_STATUS_OK;
949 /*******************************************************************
950 Wrapper for enumerating local groups
951 ******************************************************************/
953 static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
954 const DOM_SID *sid, uint32 start_idx,
955 uint32 *p_num_entries, uint32 max_entries )
957 struct acct_info *info;
958 int i;
959 BOOL res;
961 become_root();
962 res = pdb_enum_aliases(sid, start_idx, max_entries,
963 p_num_entries, &info);
964 unbecome_root();
966 if (!res)
967 return NT_STATUS_ACCESS_DENIED;
969 if (*p_num_entries == 0)
970 return NT_STATUS_OK;
972 *d_grp = talloc(ctx, sizeof(DOMAIN_GRP) * (*p_num_entries));
974 if (*d_grp == NULL) {
975 SAFE_FREE(info);
976 return NT_STATUS_NO_MEMORY;
979 for (i=0; i<*p_num_entries; i++) {
980 fstrcpy((*d_grp)[i].name, info[i].acct_name);
981 fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
982 (*d_grp)[i].rid = info[i].rid;
983 (*d_grp)[i].attr = SID_NAME_ALIAS;
986 SAFE_FREE(info);
987 return NT_STATUS_OK;
990 /*******************************************************************
991 samr_reply_enum_dom_groups
992 ********************************************************************/
994 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
996 DOMAIN_GRP *grp=NULL;
997 uint32 num_entries;
998 DOM_SID sid;
999 uint32 acc_granted;
1001 r_u->status = NT_STATUS_OK;
1003 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1004 return NT_STATUS_INVALID_HANDLE;
1006 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1007 return r_u->status;
1010 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1012 /* the domain group array is being allocated in the function below */
1013 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))) {
1014 return r_u->status;
1017 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1019 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1021 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1023 return r_u->status;
1027 /*******************************************************************
1028 samr_reply_enum_dom_aliases
1029 ********************************************************************/
1031 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1033 DOMAIN_GRP *grp=NULL;
1034 uint32 num_entries = 0;
1035 fstring sid_str;
1036 DOM_SID sid;
1037 NTSTATUS status;
1038 uint32 acc_granted;
1040 r_u->status = NT_STATUS_OK;
1042 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1043 return NT_STATUS_INVALID_HANDLE;
1045 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1046 return r_u->status;
1049 sid_to_string(sid_str, &sid);
1050 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1052 status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1053 &num_entries, MAX_SAM_ENTRIES);
1054 if (!NT_STATUS_IS_OK(status)) return status;
1056 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1058 /*safe_free(grp);*/
1060 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1062 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1064 return r_u->status;
1067 /*******************************************************************
1068 samr_reply_query_dispinfo
1069 ********************************************************************/
1071 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1072 SAMR_R_QUERY_DISPINFO *r_u)
1074 struct samr_info *info = NULL;
1075 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1077 uint32 max_entries=q_u->max_entries;
1078 uint32 enum_context=q_u->start_idx;
1079 uint32 max_size=q_u->max_size;
1081 SAM_DISPINFO_CTR *ctr;
1082 uint32 temp_size=0, total_data_size=0;
1083 NTSTATUS disp_ret;
1084 uint32 num_account = 0;
1085 enum remote_arch_types ra_type = get_remote_arch();
1086 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1087 DOM_SID domain_sid;
1089 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1090 r_u->status = NT_STATUS_OK;
1092 /* find the policy handle. open a policy on it. */
1093 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1094 return NT_STATUS_INVALID_HANDLE;
1096 domain_sid = info->sid;
1099 * calculate how many entries we will return.
1100 * based on
1101 * - the number of entries the client asked
1102 * - our limit on that
1103 * - the starting point (enumeration context)
1104 * - the buffer size the client will accept
1108 * We are a lot more like W2K. Instead of reading the SAM
1109 * each time to find the records we need to send back,
1110 * we read it once and link that copy to the sam handle.
1111 * For large user list (over the MAX_SAM_ENTRIES)
1112 * it's a definitive win.
1113 * second point to notice: between enumerations
1114 * our sam is now the same as it's a snapshoot.
1115 * third point: got rid of the static SAM_USER_21 struct
1116 * no more intermediate.
1117 * con: it uses much more memory, as a full copy is stored
1118 * in memory.
1120 * If you want to change it, think twice and think
1121 * of the second point , that's really important.
1123 * JFM, 12/20/2001
1126 /* Get what we need from the password database */
1127 switch (q_u->switch_level) {
1128 case 0x1:
1129 /* When playing with usrmgr, this is necessary
1130 if you want immediate refresh after editing
1131 a user. I would like to do this after the
1132 setuserinfo2, but we do not have access to
1133 the domain handle in that call, only to the
1134 user handle. Where else does this hurt?
1135 -- Volker
1137 #if 0
1138 /* We cannot do this here - it kills performace. JRA. */
1139 free_samr_users(info);
1140 #endif
1141 case 0x2:
1142 case 0x4:
1143 become_root();
1144 /* Level 2 is for all machines, otherwise only 'normal' users */
1145 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1146 unbecome_root();
1147 if (!NT_STATUS_IS_OK(r_u->status)) {
1148 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1149 return r_u->status;
1151 num_account = info->disp_info.num_user_account;
1152 break;
1153 case 0x3:
1154 case 0x5:
1155 r_u->status = load_group_domain_entries(info, &info->sid);
1156 if (!NT_STATUS_IS_OK(r_u->status))
1157 return r_u->status;
1158 num_account = info->disp_info.num_group_account;
1159 break;
1160 default:
1161 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1162 return NT_STATUS_INVALID_INFO_CLASS;
1165 /* first limit the number of entries we will return */
1166 if(max_entries > max_sam_entries) {
1167 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1168 max_entries = max_sam_entries;
1171 if (enum_context > num_account) {
1172 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1173 return NT_STATUS_NO_MORE_ENTRIES;
1176 /* verify we won't overflow */
1177 if (max_entries > num_account-enum_context) {
1178 max_entries = num_account-enum_context;
1179 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1182 /* calculate the size and limit on the number of entries we will return */
1183 temp_size=max_entries*struct_size;
1185 if (temp_size>max_size) {
1186 max_entries=MIN((max_size/struct_size),max_entries);;
1187 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1190 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1191 return NT_STATUS_NO_MEMORY;
1193 ZERO_STRUCTP(ctr);
1195 /* Now create reply structure */
1196 switch (q_u->switch_level) {
1197 case 0x1:
1198 if (max_entries) {
1199 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1200 return NT_STATUS_NO_MEMORY;
1202 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1203 info->disp_info.disp_user_info, &domain_sid);
1204 if (!NT_STATUS_IS_OK(disp_ret))
1205 return disp_ret;
1206 break;
1207 case 0x2:
1208 if (max_entries) {
1209 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1210 return NT_STATUS_NO_MEMORY;
1212 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1213 info->disp_info.disp_user_info, &domain_sid);
1214 if (!NT_STATUS_IS_OK(disp_ret))
1215 return disp_ret;
1216 break;
1217 case 0x3:
1218 if (max_entries) {
1219 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1220 return NT_STATUS_NO_MEMORY;
1222 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1223 if (!NT_STATUS_IS_OK(disp_ret))
1224 return disp_ret;
1225 break;
1226 case 0x4:
1227 if (max_entries) {
1228 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1229 return NT_STATUS_NO_MEMORY;
1231 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1232 if (!NT_STATUS_IS_OK(disp_ret))
1233 return disp_ret;
1234 break;
1235 case 0x5:
1236 if (max_entries) {
1237 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1238 return NT_STATUS_NO_MEMORY;
1240 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1241 if (!NT_STATUS_IS_OK(disp_ret))
1242 return disp_ret;
1243 break;
1245 default:
1246 ctr->sam.info = NULL;
1247 return NT_STATUS_INVALID_INFO_CLASS;
1250 /* calculate the total size */
1251 total_data_size=num_account*struct_size;
1253 if (enum_context+max_entries < num_account)
1254 r_u->status = STATUS_MORE_ENTRIES;
1256 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1258 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1260 return r_u->status;
1264 /*******************************************************************
1265 samr_reply_query_aliasinfo
1266 ********************************************************************/
1268 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1270 DOM_SID sid;
1271 struct acct_info info;
1272 uint32 acc_granted;
1273 BOOL ret;
1275 r_u->status = NT_STATUS_OK;
1277 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1279 /* find the policy handle. open a policy on it. */
1280 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1281 return NT_STATUS_INVALID_HANDLE;
1282 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1283 return r_u->status;
1286 become_root();
1287 ret = pdb_get_aliasinfo(&sid, &info);
1288 unbecome_root();
1290 if ( !ret )
1291 return NT_STATUS_NO_SUCH_ALIAS;
1293 switch (q_u->switch_level) {
1294 case 1:
1295 r_u->ptr = 1;
1296 r_u->ctr.switch_value1 = 1;
1297 init_samr_alias_info1(&r_u->ctr.alias.info1,
1298 info.acct_name, 1, info.acct_desc);
1299 break;
1300 case 3:
1301 r_u->ptr = 1;
1302 r_u->ctr.switch_value1 = 3;
1303 init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1304 break;
1305 default:
1306 return NT_STATUS_INVALID_INFO_CLASS;
1309 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1311 return r_u->status;
1314 #if 0
1315 /*******************************************************************
1316 samr_reply_lookup_ids
1317 ********************************************************************/
1319 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1321 uint32 rid[MAX_SAM_ENTRIES];
1322 int num_rids = q_u->num_sids1;
1324 r_u->status = NT_STATUS_OK;
1326 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1328 if (num_rids > MAX_SAM_ENTRIES) {
1329 num_rids = MAX_SAM_ENTRIES;
1330 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1333 #if 0
1334 int i;
1335 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1337 for (i = 0; i < num_rids && status == 0; i++)
1339 struct sam_passwd *sam_pass;
1340 fstring user_name;
1343 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1344 q_u->uni_user_name[i].uni_str_len));
1346 /* find the user account */
1347 become_root();
1348 sam_pass = get_smb21pwd_entry(user_name, 0);
1349 unbecome_root();
1351 if (sam_pass == NULL)
1353 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1354 rid[i] = 0;
1356 else
1358 rid[i] = sam_pass->user_rid;
1361 #endif
1363 num_rids = 1;
1364 rid[0] = BUILTIN_ALIAS_RID_USERS;
1366 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1368 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1370 return r_u->status;
1372 #endif
1374 /*******************************************************************
1375 _samr_lookup_names
1376 ********************************************************************/
1378 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1380 uint32 rid[MAX_SAM_ENTRIES];
1381 uint32 local_rid;
1382 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1383 enum SID_NAME_USE local_type;
1384 int i;
1385 int num_rids = q_u->num_names2;
1386 DOM_SID pol_sid;
1387 fstring sid_str;
1388 uint32 acc_granted;
1390 r_u->status = NT_STATUS_OK;
1392 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1394 ZERO_ARRAY(rid);
1395 ZERO_ARRAY(type);
1397 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1398 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1399 return r_u->status;
1402 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 */
1403 return r_u->status;
1406 if (num_rids > MAX_SAM_ENTRIES) {
1407 num_rids = MAX_SAM_ENTRIES;
1408 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1411 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1413 for (i = 0; i < num_rids; i++) {
1414 fstring name;
1415 DOM_SID sid;
1416 int ret;
1418 r_u->status = NT_STATUS_NONE_MAPPED;
1420 rid [i] = 0xffffffff;
1421 type[i] = SID_NAME_UNKNOWN;
1423 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1426 * we are only looking for a name
1427 * the SID we get back can be outside
1428 * the scope of the pol_sid
1430 * in clear: it prevents to reply to domain\group: yes
1431 * when only builtin\group exists.
1433 * a cleaner code is to add the sid of the domain we're looking in
1434 * to the local_lookup_name function.
1437 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1438 sid_split_rid(&sid, &local_rid);
1440 if (sid_equal(&sid, &pol_sid)) {
1441 rid[i]=local_rid;
1443 /* Windows does not return WKN_GRP here, even
1444 * on lookups in builtin */
1445 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1446 SID_NAME_ALIAS : local_type;
1448 r_u->status = NT_STATUS_OK;
1453 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1455 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1457 return r_u->status;
1460 /*******************************************************************
1461 _samr_chgpasswd_user
1462 ********************************************************************/
1464 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1466 fstring user_name;
1467 fstring wks;
1469 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1471 r_u->status = NT_STATUS_OK;
1473 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1474 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1476 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1479 * Pass the user through the NT -> unix user mapping
1480 * function.
1483 (void)map_username(user_name);
1486 * UNIX username case mangling not required, pass_oem_change
1487 * is case insensitive.
1490 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1491 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1493 init_samr_r_chgpasswd_user(r_u, r_u->status);
1495 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1497 return r_u->status;
1500 /*******************************************************************
1501 makes a SAMR_R_LOOKUP_RIDS structure.
1502 ********************************************************************/
1504 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1505 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1507 uint32 i;
1508 UNIHDR *hdr_name=NULL;
1509 UNISTR2 *uni_name=NULL;
1511 *pp_uni_name = NULL;
1512 *pp_hdr_name = NULL;
1514 if (num_names != 0) {
1515 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1516 if (hdr_name == NULL)
1517 return False;
1519 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1520 if (uni_name == NULL)
1521 return False;
1524 for (i = 0; i < num_names; i++) {
1525 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1526 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1527 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1530 *pp_uni_name = uni_name;
1531 *pp_hdr_name = hdr_name;
1533 return True;
1536 /*******************************************************************
1537 _samr_lookup_rids
1538 ********************************************************************/
1540 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1542 fstring group_names[MAX_SAM_ENTRIES];
1543 uint32 *group_attrs = NULL;
1544 UNIHDR *hdr_name = NULL;
1545 UNISTR2 *uni_name = NULL;
1546 DOM_SID pol_sid;
1547 int num_rids = q_u->num_rids1;
1548 int i;
1549 uint32 acc_granted;
1551 r_u->status = NT_STATUS_OK;
1553 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1555 /* find the policy handle. open a policy on it. */
1556 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1557 return NT_STATUS_INVALID_HANDLE;
1559 if (num_rids > MAX_SAM_ENTRIES) {
1560 num_rids = MAX_SAM_ENTRIES;
1561 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1564 if (num_rids) {
1565 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1566 return NT_STATUS_NO_MEMORY;
1569 r_u->status = NT_STATUS_NONE_MAPPED;
1571 become_root(); /* lookup_sid can require root privs */
1573 for (i = 0; i < num_rids; i++) {
1574 fstring tmpname;
1575 fstring domname;
1576 DOM_SID sid;
1577 enum SID_NAME_USE type;
1579 group_attrs[i] = SID_NAME_UNKNOWN;
1580 *group_names[i] = '\0';
1582 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1583 sid_copy(&sid, &pol_sid);
1584 sid_append_rid(&sid, q_u->rid[i]);
1586 if (lookup_sid(&sid, domname, tmpname, &type)) {
1587 r_u->status = NT_STATUS_OK;
1588 group_attrs[i] = (uint32)type;
1589 fstrcpy(group_names[i],tmpname);
1590 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1595 unbecome_root();
1597 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1598 return NT_STATUS_NO_MEMORY;
1600 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1602 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1604 return r_u->status;
1607 /*******************************************************************
1608 _samr_open_user. Safe - gives out no passwd info.
1609 ********************************************************************/
1611 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1613 SAM_ACCOUNT *sampass=NULL;
1614 DOM_SID sid;
1615 POLICY_HND domain_pol = q_u->domain_pol;
1616 POLICY_HND *user_pol = &r_u->user_pol;
1617 struct samr_info *info = NULL;
1618 SEC_DESC *psd = NULL;
1619 uint32 acc_granted;
1620 uint32 des_access = q_u->access_mask;
1621 size_t sd_size;
1622 BOOL ret;
1623 NTSTATUS nt_status;
1625 r_u->status = NT_STATUS_OK;
1627 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1628 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1629 return NT_STATUS_INVALID_HANDLE;
1631 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1632 return nt_status;
1635 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1636 if (!NT_STATUS_IS_OK(nt_status)) {
1637 return nt_status;
1640 /* append the user's RID to it */
1641 if (!sid_append_rid(&sid, q_u->user_rid))
1642 return NT_STATUS_NO_SUCH_USER;
1644 /* check if access can be granted as requested by client. */
1645 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1646 se_map_generic(&des_access, &usr_generic_mapping);
1647 if (!NT_STATUS_IS_OK(nt_status =
1648 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1649 des_access, &acc_granted, "_samr_open_user"))) {
1650 return nt_status;
1653 become_root();
1654 ret=pdb_getsampwsid(sampass, &sid);
1655 unbecome_root();
1657 /* check that the SID exists in our domain. */
1658 if (ret == False) {
1659 return NT_STATUS_NO_SUCH_USER;
1662 pdb_free_sam(&sampass);
1664 /* associate the user's SID and access bits with the new handle. */
1665 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1666 return NT_STATUS_NO_MEMORY;
1667 info->acc_granted = acc_granted;
1669 /* get a (unique) handle. open a policy on it. */
1670 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1671 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1673 return r_u->status;
1676 /*************************************************************************
1677 get_user_info_10. Safe. Only gives out acb bits.
1678 *************************************************************************/
1680 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1682 SAM_ACCOUNT *smbpass=NULL;
1683 BOOL ret;
1684 NTSTATUS nt_status;
1686 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1688 if (!NT_STATUS_IS_OK(nt_status)) {
1689 return nt_status;
1692 become_root();
1693 ret = pdb_getsampwsid(smbpass, user_sid);
1694 unbecome_root();
1696 if (ret==False) {
1697 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1698 return NT_STATUS_NO_SUCH_USER;
1701 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1703 ZERO_STRUCTP(id10);
1704 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1706 pdb_free_sam(&smbpass);
1708 return NT_STATUS_OK;
1711 /*************************************************************************
1712 get_user_info_12. OK - this is the killer as it gives out password info.
1713 Ensure that this is only allowed on an encrypted connection with a root
1714 user. JRA.
1715 *************************************************************************/
1717 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1719 SAM_ACCOUNT *smbpass=NULL;
1720 BOOL ret;
1721 NTSTATUS nt_status;
1723 if (!p->ntlmssp_auth_validated)
1724 return NT_STATUS_ACCESS_DENIED;
1726 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1727 return NT_STATUS_ACCESS_DENIED;
1730 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1733 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1735 if (!NT_STATUS_IS_OK(nt_status)) {
1736 return nt_status;
1739 ret = pdb_getsampwsid(smbpass, user_sid);
1741 if (ret == False) {
1742 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1743 pdb_free_sam(&smbpass);
1744 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1747 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1749 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1750 pdb_free_sam(&smbpass);
1751 return NT_STATUS_ACCOUNT_DISABLED;
1754 ZERO_STRUCTP(id12);
1755 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1757 pdb_free_sam(&smbpass);
1759 return NT_STATUS_OK;
1762 /*************************************************************************
1763 get_user_info_20
1764 *************************************************************************/
1766 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1768 SAM_ACCOUNT *sampass=NULL;
1769 BOOL ret;
1771 pdb_init_sam_talloc(mem_ctx, &sampass);
1773 become_root();
1774 ret = pdb_getsampwsid(sampass, user_sid);
1775 unbecome_root();
1777 if (ret == False) {
1778 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1779 return NT_STATUS_NO_SUCH_USER;
1782 samr_clear_sam_passwd(sampass);
1784 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1786 ZERO_STRUCTP(id20);
1787 init_sam_user_info20A(id20, sampass);
1789 pdb_free_sam(&sampass);
1791 return NT_STATUS_OK;
1794 /*************************************************************************
1795 get_user_info_21
1796 *************************************************************************/
1798 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1799 DOM_SID *user_sid, DOM_SID *domain_sid)
1801 SAM_ACCOUNT *sampass=NULL;
1802 BOOL ret;
1803 NTSTATUS nt_status;
1805 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1806 if (!NT_STATUS_IS_OK(nt_status)) {
1807 return nt_status;
1810 become_root();
1811 ret = pdb_getsampwsid(sampass, user_sid);
1812 unbecome_root();
1814 if (ret == False) {
1815 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1816 return NT_STATUS_NO_SUCH_USER;
1819 samr_clear_sam_passwd(sampass);
1821 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1823 ZERO_STRUCTP(id21);
1824 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1826 pdb_free_sam(&sampass);
1828 return NT_STATUS_OK;
1831 /*******************************************************************
1832 _samr_query_userinfo
1833 ********************************************************************/
1835 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1837 SAM_USERINFO_CTR *ctr;
1838 struct samr_info *info = NULL;
1839 DOM_SID domain_sid;
1840 uint32 rid;
1842 r_u->status=NT_STATUS_OK;
1844 /* search for the handle */
1845 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1846 return NT_STATUS_INVALID_HANDLE;
1848 domain_sid = info->sid;
1850 sid_split_rid(&domain_sid, &rid);
1852 if (!sid_check_is_in_our_domain(&info->sid))
1853 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1855 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1857 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1858 if (!ctr)
1859 return NT_STATUS_NO_MEMORY;
1861 ZERO_STRUCTP(ctr);
1863 /* ok! user info levels (lots: see MSDEV help), off we go... */
1864 ctr->switch_value = q_u->switch_value;
1866 switch (q_u->switch_value) {
1867 case 0x10:
1868 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1869 if (ctr->info.id10 == NULL)
1870 return NT_STATUS_NO_MEMORY;
1872 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1873 return r_u->status;
1874 break;
1876 #if 0
1877 /* whoops - got this wrong. i think. or don't understand what's happening. */
1878 case 0x11:
1880 NTTIME expire;
1881 info = (void *)&id11;
1883 expire.low = 0xffffffff;
1884 expire.high = 0x7fffffff;
1886 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1887 sizeof
1888 (*ctr->
1889 info.
1890 id11));
1891 ZERO_STRUCTP(ctr->info.id11);
1892 init_sam_user_info11(ctr->info.id11, &expire,
1893 "BROOKFIELDS$", /* name */
1894 0x03ef, /* user rid */
1895 0x201, /* group rid */
1896 0x0080); /* acb info */
1898 break;
1900 #endif
1902 case 0x12:
1903 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1904 if (ctr->info.id12 == NULL)
1905 return NT_STATUS_NO_MEMORY;
1907 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1908 return r_u->status;
1909 break;
1911 case 20:
1912 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1913 if (ctr->info.id20 == NULL)
1914 return NT_STATUS_NO_MEMORY;
1915 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1916 return r_u->status;
1917 break;
1919 case 21:
1920 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1921 if (ctr->info.id21 == NULL)
1922 return NT_STATUS_NO_MEMORY;
1923 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1924 &info->sid, &domain_sid)))
1925 return r_u->status;
1926 break;
1928 default:
1929 return NT_STATUS_INVALID_INFO_CLASS;
1932 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1934 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1936 return r_u->status;
1939 /*******************************************************************
1940 samr_reply_query_usergroups
1941 ********************************************************************/
1943 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1945 SAM_ACCOUNT *sam_pass=NULL;
1946 DOM_SID sid;
1947 DOM_GID *gids = NULL;
1948 int num_groups = 0;
1949 uint32 acc_granted;
1950 BOOL ret;
1953 * from the SID in the request:
1954 * we should send back the list of DOMAIN GROUPS
1955 * the user is a member of
1957 * and only the DOMAIN GROUPS
1958 * no ALIASES !!! neither aliases of the domain
1959 * nor aliases of the builtin SID
1961 * JFM, 12/2/2001
1964 r_u->status = NT_STATUS_OK;
1966 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1968 /* find the policy handle. open a policy on it. */
1969 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1970 return NT_STATUS_INVALID_HANDLE;
1972 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1973 return r_u->status;
1976 if (!sid_check_is_in_our_domain(&sid))
1977 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1979 pdb_init_sam(&sam_pass);
1981 become_root();
1982 ret = pdb_getsampwsid(sam_pass, &sid);
1983 unbecome_root();
1985 if (ret == False) {
1986 pdb_free_sam(&sam_pass);
1987 return NT_STATUS_NO_SUCH_USER;
1990 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
1991 pdb_free_sam(&sam_pass);
1992 return NT_STATUS_NO_SUCH_GROUP;
1995 /* construct the response. lkclXXXX: gids are not copied! */
1996 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1998 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2000 pdb_free_sam(&sam_pass);
2002 return r_u->status;
2005 /*******************************************************************
2006 _samr_query_dom_info
2007 ********************************************************************/
2009 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2011 struct samr_info *info = NULL;
2012 SAM_UNK_CTR *ctr;
2013 uint32 min_pass_len,pass_hist,flag;
2014 time_t u_expire, u_min_age;
2015 NTTIME nt_expire, nt_min_age;
2017 time_t u_lock_duration, u_reset_time;
2018 NTTIME nt_lock_duration, nt_reset_time;
2019 uint32 lockout;
2021 time_t u_logout;
2022 NTTIME nt_logout;
2024 uint32 account_policy_temp;
2026 uint32 num_users=0, num_groups=0, num_aliases=0;
2028 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2029 return NT_STATUS_NO_MEMORY;
2031 ZERO_STRUCTP(ctr);
2033 r_u->status = NT_STATUS_OK;
2035 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2037 /* find the policy handle. open a policy on it. */
2038 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2039 return NT_STATUS_INVALID_HANDLE;
2041 switch (q_u->switch_value) {
2042 case 0x01:
2044 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2045 min_pass_len = account_policy_temp;
2047 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2048 pass_hist = account_policy_temp;
2050 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2051 flag = account_policy_temp;
2053 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2054 u_expire = account_policy_temp;
2056 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2057 u_min_age = account_policy_temp;
2059 unix_to_nt_time_abs(&nt_expire, u_expire);
2060 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2062 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2063 flag, nt_expire, nt_min_age);
2064 break;
2065 case 0x02:
2066 become_root();
2067 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2068 unbecome_root();
2069 if (!NT_STATUS_IS_OK(r_u->status)) {
2070 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2071 return r_u->status;
2073 num_users=info->disp_info.num_user_account;
2074 free_samr_db(info);
2076 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2077 if (!NT_STATUS_IS_OK(r_u->status)) {
2078 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2079 return r_u->status;
2081 num_groups=info->disp_info.num_group_account;
2082 free_samr_db(info);
2084 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2085 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2086 num_users, num_groups, num_aliases);
2087 break;
2088 case 0x03:
2089 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2090 unix_to_nt_time_abs(&nt_logout, u_logout);
2092 init_unk_info3(&ctr->info.inf3, nt_logout);
2093 break;
2094 case 0x05:
2095 init_unk_info5(&ctr->info.inf5, global_myname());
2096 break;
2097 case 0x06:
2098 init_unk_info6(&ctr->info.inf6);
2099 break;
2100 case 0x07:
2101 init_unk_info7(&ctr->info.inf7);
2102 break;
2103 case 0x0c:
2104 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2105 u_lock_duration = account_policy_temp * 60;
2107 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2108 u_reset_time = account_policy_temp * 60;
2110 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2111 lockout = account_policy_temp;
2113 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2114 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2116 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2117 break;
2118 default:
2119 return NT_STATUS_INVALID_INFO_CLASS;
2122 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2124 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2126 return r_u->status;
2129 /*******************************************************************
2130 _samr_create_user
2131 Create an account, can be either a normal user or a machine.
2132 This funcion will need to be updated for bdc/domain trusts.
2133 ********************************************************************/
2135 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2137 SAM_ACCOUNT *sam_pass=NULL;
2138 fstring account;
2139 DOM_SID sid;
2140 pstring add_script;
2141 POLICY_HND dom_pol = q_u->domain_pol;
2142 UNISTR2 user_account = q_u->uni_name;
2143 uint16 acb_info = q_u->acb_info;
2144 POLICY_HND *user_pol = &r_u->user_pol;
2145 struct samr_info *info = NULL;
2146 BOOL ret;
2147 NTSTATUS nt_status;
2148 struct passwd *pw;
2149 uint32 acc_granted;
2150 SEC_DESC *psd;
2151 size_t sd_size;
2152 uint32 new_rid = 0;
2153 /* check this, when giving away 'add computer to domain' privs */
2154 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2156 /* Get the domain SID stored in the domain policy */
2157 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2158 return NT_STATUS_INVALID_HANDLE;
2160 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2161 return nt_status;
2164 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2165 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2166 this parameter is not an account type */
2167 return NT_STATUS_INVALID_PARAMETER;
2170 /* find the account: tell the caller if it exists.
2171 lkclXXXX i have *no* idea if this is a problem or not
2172 or even if you are supposed to construct a different
2173 reply if the account already exists...
2176 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2177 strlower_m(account);
2179 pdb_init_sam(&sam_pass);
2181 become_root();
2182 ret = pdb_getsampwnam(sam_pass, account);
2183 unbecome_root();
2184 if (ret == True) {
2185 /* this account exists: say so */
2186 pdb_free_sam(&sam_pass);
2187 return NT_STATUS_USER_EXISTS;
2190 pdb_free_sam(&sam_pass);
2193 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2194 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2195 * that only people with write access to the smbpasswd file will be able
2196 * to create a user. JRA.
2200 * add the user in the /etc/passwd file or the unix authority system.
2201 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2202 * a) local_password_change() checks for us if the /etc/passwd account really exists
2203 * b) smb_create_user() would return an error if the account already exists
2204 * and as it could return an error also if it can't create the account, it would be tricky.
2206 * So we go the easy way, only check after if the account exists.
2207 * JFM (2/3/2001), to clear any possible bad understanding (-:
2209 * We now have seperate script paramaters for adding users/machines so we
2210 * now have some sainity-checking to match.
2213 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2216 * we used to have code here that made sure the acb_info flags
2217 * matched with the users named (e.g. an account flags as a machine
2218 * trust account ended in '$'). It has been ifdef'd out for a long
2219 * time, so I replaced it with this comment. --jerry
2222 /* the passdb lookup has failed; check to see if we need to run the
2223 add user/machine script */
2225 pw = Get_Pwnam(account);
2227 /*********************************************************************
2228 * HEADS UP! If we have to create a new user account, we have to get
2229 * a new RID from somewhere. This used to be done by the passdb
2230 * backend. It has been moved into idmap now. Since idmap is now
2231 * wrapped up behind winbind, this means you have to run winbindd if you
2232 * want new accounts to get a new RID when "enable rid algorithm = no".
2233 * Tough. We now have a uniform way of allocating RIDs regardless
2234 * of what ever passdb backend people may use.
2235 * --jerry (2003-07-10)
2236 *********************************************************************/
2238 if ( !pw ) {
2240 * we can't check both the ending $ and the acb_info.
2242 * UserManager creates trust accounts (ending in $,
2243 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2244 * JFM, 11/29/2001
2246 if (account[strlen(account)-1] == '$')
2247 pstrcpy(add_script, lp_addmachine_script());
2248 else
2249 pstrcpy(add_script, lp_adduser_script());
2251 if (*add_script) {
2252 int add_ret;
2253 all_string_sub(add_script, "%u", account, sizeof(add_script));
2254 add_ret = smbrun(add_script,NULL);
2255 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2257 else /* no add user script -- ask winbindd to do it */
2259 if ( !winbind_create_user( account, &new_rid ) ) {
2260 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2261 account));
2267 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2269 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2270 return nt_status;
2272 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2274 if (!pdb_add_sam_account(sam_pass)) {
2275 pdb_free_sam(&sam_pass);
2276 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2277 account));
2278 return NT_STATUS_ACCESS_DENIED;
2281 /* Get the user's SID */
2282 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2284 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2285 se_map_generic(&des_access, &usr_generic_mapping);
2286 if (!NT_STATUS_IS_OK(nt_status =
2287 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2288 des_access, &acc_granted, "_samr_create_user"))) {
2289 return nt_status;
2292 /* associate the user's SID with the new handle. */
2293 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2294 pdb_free_sam(&sam_pass);
2295 return NT_STATUS_NO_MEMORY;
2298 ZERO_STRUCTP(info);
2299 info->sid = sid;
2300 info->acc_granted = acc_granted;
2302 /* get a (unique) handle. open a policy on it. */
2303 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2304 pdb_free_sam(&sam_pass);
2305 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2308 r_u->user_rid=pdb_get_user_rid(sam_pass);
2310 r_u->access_granted = acc_granted;
2312 pdb_free_sam(&sam_pass);
2314 return NT_STATUS_OK;
2317 /*******************************************************************
2318 samr_reply_connect_anon
2319 ********************************************************************/
2321 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2323 struct samr_info *info = NULL;
2324 uint32 des_access = q_u->access_mask;
2326 /* Access check */
2328 if (!pipe_access_check(p)) {
2329 DEBUG(3, ("access denied to samr_connect_anon\n"));
2330 r_u->status = NT_STATUS_ACCESS_DENIED;
2331 return r_u->status;
2334 /* set up the SAMR connect_anon response */
2336 r_u->status = NT_STATUS_OK;
2338 /* associate the user's SID with the new handle. */
2339 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2340 return NT_STATUS_NO_MEMORY;
2342 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2343 was observed from a win98 client trying to enumerate users (when configured
2344 user level access control on shares) --jerry */
2346 se_map_generic( &des_access, &sam_generic_mapping );
2347 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2349 info->status = q_u->unknown_0;
2351 /* get a (unique) handle. open a policy on it. */
2352 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2353 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2355 return r_u->status;
2358 /*******************************************************************
2359 samr_reply_connect
2360 ********************************************************************/
2362 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2364 struct samr_info *info = NULL;
2365 SEC_DESC *psd = NULL;
2366 uint32 acc_granted;
2367 uint32 des_access = q_u->access_mask;
2368 size_t sd_size;
2369 NTSTATUS nt_status;
2372 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2374 /* Access check */
2376 if (!pipe_access_check(p)) {
2377 DEBUG(3, ("access denied to samr_connect\n"));
2378 r_u->status = NT_STATUS_ACCESS_DENIED;
2379 return r_u->status;
2382 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2383 se_map_generic(&des_access, &sam_generic_mapping);
2384 if (!NT_STATUS_IS_OK(nt_status =
2385 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2386 des_access, &acc_granted, "_samr_connect"))) {
2387 return nt_status;
2390 r_u->status = NT_STATUS_OK;
2392 /* associate the user's SID and access granted with the new handle. */
2393 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2394 return NT_STATUS_NO_MEMORY;
2396 info->acc_granted = acc_granted;
2397 info->status = q_u->access_mask;
2399 /* get a (unique) handle. open a policy on it. */
2400 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2401 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2403 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2405 return r_u->status;
2408 /*******************************************************************
2409 samr_connect4
2410 ********************************************************************/
2412 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2414 struct samr_info *info = NULL;
2415 SEC_DESC *psd = NULL;
2416 uint32 acc_granted;
2417 uint32 des_access = q_u->access_mask;
2418 size_t sd_size;
2419 NTSTATUS nt_status;
2422 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2424 /* Access check */
2426 if (!pipe_access_check(p)) {
2427 DEBUG(3, ("access denied to samr_connect4\n"));
2428 r_u->status = NT_STATUS_ACCESS_DENIED;
2429 return r_u->status;
2432 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2433 se_map_generic(&des_access, &sam_generic_mapping);
2434 if (!NT_STATUS_IS_OK(nt_status =
2435 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2436 des_access, &acc_granted, "_samr_connect"))) {
2437 return nt_status;
2440 r_u->status = NT_STATUS_OK;
2442 /* associate the user's SID and access granted with the new handle. */
2443 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2444 return NT_STATUS_NO_MEMORY;
2446 info->acc_granted = acc_granted;
2447 info->status = q_u->access_mask;
2449 /* get a (unique) handle. open a policy on it. */
2450 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2451 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2453 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2455 return r_u->status;
2458 /**********************************************************************
2459 api_samr_lookup_domain
2460 **********************************************************************/
2462 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2464 struct samr_info *info;
2465 fstring domain_name;
2466 DOM_SID sid;
2468 r_u->status = NT_STATUS_OK;
2470 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2471 return NT_STATUS_INVALID_HANDLE;
2473 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2474 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2476 return r_u->status;
2479 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2481 ZERO_STRUCT(sid);
2483 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2484 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2487 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2489 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2491 return r_u->status;
2494 /******************************************************************
2495 makes a SAMR_R_ENUM_DOMAINS structure.
2496 ********************************************************************/
2498 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2499 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2501 uint32 i;
2502 SAM_ENTRY *sam;
2503 UNISTR2 *uni_name;
2505 DEBUG(5, ("make_enum_domains\n"));
2507 *pp_sam = NULL;
2508 *pp_uni_name = NULL;
2510 if (num_sam_entries == 0)
2511 return True;
2513 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2514 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2516 if (sam == NULL || uni_name == NULL)
2517 return False;
2519 for (i = 0; i < num_sam_entries; i++) {
2520 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2521 init_sam_entry(&sam[i], &uni_name[i], 0);
2524 *pp_sam = sam;
2525 *pp_uni_name = uni_name;
2527 return True;
2530 /**********************************************************************
2531 api_samr_enum_domains
2532 **********************************************************************/
2534 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2536 struct samr_info *info;
2537 uint32 num_entries = 2;
2538 fstring dom[2];
2539 const char *name;
2541 r_u->status = NT_STATUS_OK;
2543 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2544 return NT_STATUS_INVALID_HANDLE;
2546 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2547 return r_u->status;
2550 name = get_global_sam_name();
2552 fstrcpy(dom[0],name);
2553 strupper_m(dom[0]);
2554 fstrcpy(dom[1],"Builtin");
2556 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2557 return NT_STATUS_NO_MEMORY;
2559 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2561 return r_u->status;
2564 /*******************************************************************
2565 api_samr_open_alias
2566 ********************************************************************/
2568 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2570 DOM_SID sid;
2571 POLICY_HND domain_pol = q_u->dom_pol;
2572 uint32 alias_rid = q_u->rid_alias;
2573 POLICY_HND *alias_pol = &r_u->pol;
2574 struct samr_info *info = NULL;
2575 SEC_DESC *psd = NULL;
2576 uint32 acc_granted;
2577 uint32 des_access = q_u->access_mask;
2578 size_t sd_size;
2579 NTSTATUS status;
2581 r_u->status = NT_STATUS_OK;
2583 /* find the domain policy and get the SID / access bits stored in the domain policy */
2584 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2585 return NT_STATUS_INVALID_HANDLE;
2587 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2588 return status;
2591 /* append the alias' RID to it */
2592 if (!sid_append_rid(&sid, alias_rid))
2593 return NT_STATUS_NO_SUCH_USER;
2595 /*check if access can be granted as requested by client. */
2596 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2597 se_map_generic(&des_access,&ali_generic_mapping);
2598 if (!NT_STATUS_IS_OK(status =
2599 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2600 des_access, &acc_granted, "_samr_open_alias"))) {
2601 return status;
2605 * we should check if the rid really exist !!!
2606 * JFM.
2609 /* associate the user's SID with the new handle. */
2610 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2611 return NT_STATUS_NO_MEMORY;
2613 info->acc_granted = acc_granted;
2615 /* get a (unique) handle. open a policy on it. */
2616 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2617 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2619 return r_u->status;
2622 /*******************************************************************
2623 set_user_info_10
2624 ********************************************************************/
2626 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2628 SAM_ACCOUNT *pwd =NULL;
2629 BOOL ret;
2631 pdb_init_sam(&pwd);
2633 ret = pdb_getsampwsid(pwd, sid);
2635 if(ret==False) {
2636 pdb_free_sam(&pwd);
2637 return False;
2640 if (id10 == NULL) {
2641 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2642 pdb_free_sam(&pwd);
2643 return False;
2646 /* FIX ME: check if the value is really changed --metze */
2647 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2648 pdb_free_sam(&pwd);
2649 return False;
2652 if(!pdb_update_sam_account(pwd)) {
2653 pdb_free_sam(&pwd);
2654 return False;
2657 pdb_free_sam(&pwd);
2659 return True;
2662 /*******************************************************************
2663 set_user_info_12
2664 ********************************************************************/
2666 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2668 SAM_ACCOUNT *pwd = NULL;
2670 pdb_init_sam(&pwd);
2672 if(!pdb_getsampwsid(pwd, sid)) {
2673 pdb_free_sam(&pwd);
2674 return False;
2677 if (id12 == NULL) {
2678 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2679 pdb_free_sam(&pwd);
2680 return False;
2683 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2684 pdb_free_sam(&pwd);
2685 return False;
2687 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2688 pdb_free_sam(&pwd);
2689 return False;
2691 if (!pdb_set_pass_changed_now (pwd)) {
2692 pdb_free_sam(&pwd);
2693 return False;
2696 if(!pdb_update_sam_account(pwd)) {
2697 pdb_free_sam(&pwd);
2698 return False;
2701 pdb_free_sam(&pwd);
2702 return True;
2705 /*******************************************************************
2706 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2707 ********************************************************************/
2708 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2710 struct group *grp;
2711 gid_t gid;
2713 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2714 &gid))) {
2715 DEBUG(2,("Could not get gid for primary group of "
2716 "user %s\n", pdb_get_username(sampass)));
2717 return False;
2720 grp = getgrgid(gid);
2722 if (grp == NULL) {
2723 DEBUG(2,("Could not find primary group %lu for "
2724 "user %s\n", (unsigned long)gid,
2725 pdb_get_username(sampass)));
2726 return False;
2729 if (smb_set_primary_group(grp->gr_name,
2730 pdb_get_username(sampass)) != 0) {
2731 DEBUG(2,("Could not set primary group for user %s to "
2732 "%s\n",
2733 pdb_get_username(sampass), grp->gr_name));
2734 return False;
2737 return True;
2741 /*******************************************************************
2742 set_user_info_20
2743 ********************************************************************/
2745 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2747 SAM_ACCOUNT *pwd = NULL;
2749 if (id20 == NULL) {
2750 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2751 return False;
2754 pdb_init_sam(&pwd);
2756 if (!pdb_getsampwsid(pwd, sid)) {
2757 pdb_free_sam(&pwd);
2758 return False;
2761 copy_id20_to_sam_passwd(pwd, id20);
2763 /* write the change out */
2764 if(!pdb_update_sam_account(pwd)) {
2765 pdb_free_sam(&pwd);
2766 return False;
2769 pdb_free_sam(&pwd);
2771 return True;
2773 /*******************************************************************
2774 set_user_info_21
2775 ********************************************************************/
2777 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2779 SAM_ACCOUNT *pwd = NULL;
2781 if (id21 == NULL) {
2782 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2783 return False;
2786 pdb_init_sam(&pwd);
2788 if (!pdb_getsampwsid(pwd, sid)) {
2789 pdb_free_sam(&pwd);
2790 return False;
2793 copy_id21_to_sam_passwd(pwd, id21);
2796 * The funny part about the previous two calls is
2797 * that pwd still has the password hashes from the
2798 * passdb entry. These have not been updated from
2799 * id21. I don't know if they need to be set. --jerry
2802 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2803 set_unix_primary_group(pwd);
2805 /* write the change out */
2806 if(!pdb_update_sam_account(pwd)) {
2807 pdb_free_sam(&pwd);
2808 return False;
2811 pdb_free_sam(&pwd);
2813 return True;
2816 /*******************************************************************
2817 set_user_info_23
2818 ********************************************************************/
2820 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2822 SAM_ACCOUNT *pwd = NULL;
2823 pstring plaintext_buf;
2824 uint32 len;
2825 uint16 acct_ctrl;
2827 if (id23 == NULL) {
2828 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2829 return False;
2832 pdb_init_sam(&pwd);
2834 if (!pdb_getsampwsid(pwd, sid)) {
2835 pdb_free_sam(&pwd);
2836 return False;
2839 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2840 pdb_get_username(pwd)));
2842 acct_ctrl = pdb_get_acct_ctrl(pwd);
2844 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2845 pdb_free_sam(&pwd);
2846 return False;
2849 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2850 pdb_free_sam(&pwd);
2851 return False;
2854 copy_id23_to_sam_passwd(pwd, id23);
2856 /* if it's a trust account, don't update /etc/passwd */
2857 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2858 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2859 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2860 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2861 } else {
2862 /* update the UNIX password */
2863 if (lp_unix_password_sync() ) {
2864 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2865 if (!passwd) {
2866 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2869 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2870 pdb_free_sam(&pwd);
2871 return False;
2876 ZERO_STRUCT(plaintext_buf);
2878 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2879 set_unix_primary_group(pwd);
2881 if(!pdb_update_sam_account(pwd)) {
2882 pdb_free_sam(&pwd);
2883 return False;
2886 pdb_free_sam(&pwd);
2888 return True;
2891 /*******************************************************************
2892 set_user_info_pw
2893 ********************************************************************/
2895 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2897 SAM_ACCOUNT *pwd = NULL;
2898 uint32 len;
2899 pstring plaintext_buf;
2900 uint16 acct_ctrl;
2902 pdb_init_sam(&pwd);
2904 if (!pdb_getsampwsid(pwd, sid)) {
2905 pdb_free_sam(&pwd);
2906 return False;
2909 DEBUG(5, ("Attempting administrator password change for user %s\n",
2910 pdb_get_username(pwd)));
2912 acct_ctrl = pdb_get_acct_ctrl(pwd);
2914 ZERO_STRUCT(plaintext_buf);
2916 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2917 pdb_free_sam(&pwd);
2918 return False;
2921 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2922 pdb_free_sam(&pwd);
2923 return False;
2926 /* if it's a trust account, don't update /etc/passwd */
2927 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2928 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2929 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2930 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2931 } else {
2932 /* update the UNIX password */
2933 if (lp_unix_password_sync()) {
2934 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2935 if (!passwd) {
2936 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2939 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2940 pdb_free_sam(&pwd);
2941 return False;
2946 ZERO_STRUCT(plaintext_buf);
2948 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2950 /* update the SAMBA password */
2951 if(!pdb_update_sam_account(pwd)) {
2952 pdb_free_sam(&pwd);
2953 return False;
2956 pdb_free_sam(&pwd);
2958 return True;
2961 /*******************************************************************
2962 samr_reply_set_userinfo
2963 ********************************************************************/
2965 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2967 DOM_SID sid;
2968 POLICY_HND *pol = &q_u->pol;
2969 uint16 switch_value = q_u->switch_value;
2970 SAM_USERINFO_CTR *ctr = q_u->ctr;
2971 uint32 acc_granted;
2972 uint32 acc_required;
2974 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2976 r_u->status = NT_STATUS_OK;
2978 /* find the policy handle. open a policy on it. */
2979 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2980 return NT_STATUS_INVALID_HANDLE;
2982 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2983 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2984 return r_u->status;
2987 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2989 if (ctr == NULL) {
2990 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2991 return NT_STATUS_INVALID_INFO_CLASS;
2994 /* ok! user info levels (lots: see MSDEV help), off we go... */
2995 switch (switch_value) {
2996 case 0x12:
2997 if (!set_user_info_12(ctr->info.id12, &sid))
2998 return NT_STATUS_ACCESS_DENIED;
2999 break;
3001 case 24:
3002 if (!p->session_key.length) {
3003 return NT_STATUS_NO_USER_SESSION_KEY;
3005 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3007 dump_data(100, (char *)ctr->info.id24->pass, 516);
3009 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3010 return NT_STATUS_ACCESS_DENIED;
3011 break;
3013 case 25:
3014 #if 0
3016 * Currently we don't really know how to unmarshall
3017 * the level 25 struct, and the password encryption
3018 * is different. This is a placeholder for when we
3019 * do understand it. In the meantime just return INVALID
3020 * info level and W2K SP2 drops down to level 23... JRA.
3023 if (!p->session_key.length) {
3024 return NT_STATUS_NO_USER_SESSION_KEY;
3026 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3028 dump_data(100, (char *)ctr->info.id25->pass, 532);
3030 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3031 return NT_STATUS_ACCESS_DENIED;
3032 break;
3033 #endif
3034 return NT_STATUS_INVALID_INFO_CLASS;
3036 case 23:
3037 if (!p->session_key.length) {
3038 return NT_STATUS_NO_USER_SESSION_KEY;
3040 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3042 dump_data(100, (char *)ctr->info.id23->pass, 516);
3044 if (!set_user_info_23(ctr->info.id23, &sid))
3045 return NT_STATUS_ACCESS_DENIED;
3046 break;
3048 default:
3049 return NT_STATUS_INVALID_INFO_CLASS;
3052 return r_u->status;
3055 /*******************************************************************
3056 samr_reply_set_userinfo2
3057 ********************************************************************/
3059 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3061 DOM_SID sid;
3062 SAM_USERINFO_CTR *ctr = q_u->ctr;
3063 POLICY_HND *pol = &q_u->pol;
3064 uint16 switch_value = q_u->switch_value;
3065 uint32 acc_granted;
3066 uint32 acc_required;
3068 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3070 r_u->status = NT_STATUS_OK;
3072 /* find the policy handle. open a policy on it. */
3073 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3074 return NT_STATUS_INVALID_HANDLE;
3076 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3077 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3078 return r_u->status;
3081 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3083 if (ctr == NULL) {
3084 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3085 return NT_STATUS_INVALID_INFO_CLASS;
3088 switch_value=ctr->switch_value;
3090 /* ok! user info levels (lots: see MSDEV help), off we go... */
3091 switch (switch_value) {
3092 case 21:
3093 if (!set_user_info_21(ctr->info.id21, &sid))
3094 return NT_STATUS_ACCESS_DENIED;
3095 break;
3096 case 20:
3097 if (!set_user_info_20(ctr->info.id20, &sid))
3098 return NT_STATUS_ACCESS_DENIED;
3099 break;
3100 case 16:
3101 if (!set_user_info_10(ctr->info.id10, &sid))
3102 return NT_STATUS_ACCESS_DENIED;
3103 break;
3104 case 18:
3105 /* Used by AS/U JRA. */
3106 if (!set_user_info_12(ctr->info.id12, &sid))
3107 return NT_STATUS_ACCESS_DENIED;
3108 break;
3109 default:
3110 return NT_STATUS_INVALID_INFO_CLASS;
3113 return r_u->status;
3116 /*********************************************************************
3117 _samr_query_aliasmem
3118 *********************************************************************/
3120 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3122 int num_groups = 0, tmp_num_groups=0;
3123 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3124 struct samr_info *info = NULL;
3125 int i,j;
3127 NTSTATUS ntstatus1;
3128 NTSTATUS ntstatus2;
3130 /* until i see a real useraliases query, we fack one up */
3132 /* I have seen one, JFM 2/12/2001 */
3134 * Explanation of what this call does:
3135 * for all the SID given in the request:
3136 * return a list of alias (local groups)
3137 * that have those SID as members.
3139 * and that's the alias in the domain specified
3140 * in the policy_handle
3142 * if the policy handle is on an incorrect sid
3143 * for example a user's sid
3144 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3147 r_u->status = NT_STATUS_OK;
3149 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3151 /* find the policy handle. open a policy on it. */
3152 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3153 return NT_STATUS_INVALID_HANDLE;
3155 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3156 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3158 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3159 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3160 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3161 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3165 if (!sid_check_is_domain(&info->sid) &&
3166 !sid_check_is_builtin(&info->sid))
3167 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3170 for (i=0; i<q_u->num_sids1; i++) {
3172 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3175 * if there is an error, we just continue as
3176 * it can be an unfound user or group
3178 if (!NT_STATUS_IS_OK(r_u->status)) {
3179 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3180 continue;
3183 if (tmp_num_groups==0) {
3184 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3185 continue;
3188 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3189 if (new_rids==NULL) {
3190 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3191 return NT_STATUS_NO_MEMORY;
3193 rids=new_rids;
3195 for (j=0; j<tmp_num_groups; j++)
3196 rids[j+num_groups]=tmp_rids[j];
3198 safe_free(tmp_rids);
3200 num_groups+=tmp_num_groups;
3203 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3204 return NT_STATUS_OK;
3207 /*********************************************************************
3208 _samr_query_aliasmem
3209 *********************************************************************/
3211 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3213 int i;
3215 int num_sids = 0;
3216 DOM_SID2 *sid;
3217 DOM_SID *sids=NULL;
3219 DOM_SID alias_sid;
3221 uint32 acc_granted;
3223 /* find the policy handle. open a policy on it. */
3224 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3225 return NT_STATUS_INVALID_HANDLE;
3227 if (!NT_STATUS_IS_OK(r_u->status =
3228 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3229 return r_u->status;
3232 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3234 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3235 return NT_STATUS_NO_SUCH_ALIAS;
3237 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_sids);
3238 if (num_sids!=0 && sid == NULL) {
3239 SAFE_FREE(sids);
3240 return NT_STATUS_NO_MEMORY;
3243 for (i = 0; i < num_sids; i++) {
3244 init_dom_sid2(&sid[i], &sids[i]);
3247 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3249 SAFE_FREE(sids);
3251 return NT_STATUS_OK;
3254 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3256 int i;
3258 for (i=0; i<*num; i++) {
3259 if ((*uids)[i] == uid)
3260 return;
3263 *uids = Realloc(*uids, (*num+1) * sizeof(uid_t));
3265 if (*uids == NULL)
3266 return;
3268 (*uids)[*num] = uid;
3269 *num += 1;
3273 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3275 struct group *grp;
3276 char **gr;
3277 struct sys_pwent *userlist, *user;
3279 *uids = NULL;
3280 *num = 0;
3282 /* We only look at our own sam, so don't care about imported stuff */
3284 winbind_off();
3286 if ((grp = getgrgid(gid)) == NULL) {
3287 winbind_on();
3288 return False;
3291 /* Primary group members */
3293 userlist = getpwent_list();
3295 for (user = userlist; user != NULL; user = user->next) {
3296 if (user->pw_gid != gid)
3297 continue;
3298 add_uid_to_array_unique(user->pw_uid, uids, num);
3301 pwent_free(userlist);
3303 /* Secondary group members */
3305 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3306 struct passwd *pw = getpwnam(*gr);
3308 if (pw == NULL)
3309 continue;
3310 add_uid_to_array_unique(pw->pw_uid, uids, num);
3313 winbind_on();
3315 return True;
3318 /*********************************************************************
3319 _samr_query_groupmem
3320 *********************************************************************/
3322 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3324 int final_num_rids, i;
3325 DOM_SID group_sid;
3326 fstring group_sid_str;
3327 uid_t *uids;
3328 int num;
3329 gid_t gid;
3331 uint32 *rid=NULL;
3332 uint32 *attr=NULL;
3334 uint32 acc_granted;
3336 /* find the policy handle. open a policy on it. */
3337 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3338 return NT_STATUS_INVALID_HANDLE;
3340 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3341 return r_u->status;
3344 sid_to_string(group_sid_str, &group_sid);
3345 DEBUG(10, ("sid is %s\n", group_sid_str));
3347 if (!sid_check_is_in_our_domain(&group_sid)) {
3348 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3349 return NT_STATUS_NO_SUCH_GROUP;
3352 DEBUG(10, ("lookup on Domain SID\n"));
3354 if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3355 return NT_STATUS_NO_SUCH_GROUP;
3357 if(!get_memberuids(gid, &uids, &num))
3358 return NT_STATUS_NO_SUCH_GROUP;
3360 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
3361 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
3363 if (num!=0 && (rid==NULL || attr==NULL))
3364 return NT_STATUS_NO_MEMORY;
3366 final_num_rids = 0;
3368 for (i=0; i<num; i++) {
3369 DOM_SID sid;
3371 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3372 DEBUG(1, ("Could not map member uid to SID\n"));
3373 continue;
3376 if (!sid_check_is_in_our_domain(&sid)) {
3377 DEBUG(1, ("Inconsistent SAM -- group member uid not "
3378 "in our domain\n"));
3379 continue;
3382 sid_peek_rid(&sid, &rid[final_num_rids]);
3384 /* Hmm. In a trace I got the constant 7 here from NT. */
3385 attr[final_num_rids] = SID_NAME_USER;
3387 final_num_rids += 1;
3390 SAFE_FREE(uids);
3392 init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3393 NT_STATUS_OK);
3395 return NT_STATUS_OK;
3398 /*********************************************************************
3399 _samr_add_aliasmem
3400 *********************************************************************/
3402 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3404 DOM_SID alias_sid;
3405 uint32 acc_granted;
3407 /* Find the policy handle. Open a policy on it. */
3408 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3409 return NT_STATUS_INVALID_HANDLE;
3411 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3412 return r_u->status;
3415 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3417 if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
3418 return NT_STATUS_ACCESS_DENIED;
3420 return NT_STATUS_OK;
3423 /*********************************************************************
3424 _samr_del_aliasmem
3425 *********************************************************************/
3427 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3429 DOM_SID alias_sid;
3430 uint32 acc_granted;
3432 /* Find the policy handle. Open a policy on it. */
3433 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3434 return NT_STATUS_INVALID_HANDLE;
3436 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3437 return r_u->status;
3440 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3441 sid_string_static(&alias_sid)));
3443 if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
3444 return NT_STATUS_ACCESS_DENIED;
3446 return NT_STATUS_OK;
3449 /*********************************************************************
3450 _samr_add_groupmem
3451 *********************************************************************/
3453 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3455 DOM_SID group_sid;
3456 DOM_SID user_sid;
3457 fstring group_sid_str;
3458 uid_t uid;
3459 struct passwd *pwd;
3460 struct group *grp;
3461 fstring grp_name;
3462 GROUP_MAP map;
3463 NTSTATUS ret;
3464 SAM_ACCOUNT *sam_user=NULL;
3465 BOOL check;
3466 uint32 acc_granted;
3468 /* Find the policy handle. Open a policy on it. */
3469 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3470 return NT_STATUS_INVALID_HANDLE;
3472 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3473 return r_u->status;
3476 sid_to_string(group_sid_str, &group_sid);
3477 DEBUG(10, ("sid is %s\n", group_sid_str));
3479 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3480 return NT_STATUS_NO_SUCH_GROUP;
3482 DEBUG(10, ("lookup on Domain SID\n"));
3484 if(!get_domain_group_from_sid(group_sid, &map))
3485 return NT_STATUS_NO_SUCH_GROUP;
3487 sid_copy(&user_sid, get_global_sam_sid());
3488 sid_append_rid(&user_sid, q_u->rid);
3490 ret = pdb_init_sam(&sam_user);
3491 if (!NT_STATUS_IS_OK(ret))
3492 return ret;
3494 check = pdb_getsampwsid(sam_user, &user_sid);
3496 if (check != True) {
3497 pdb_free_sam(&sam_user);
3498 return NT_STATUS_NO_SUCH_USER;
3501 /* check a real user exist before we run the script to add a user to a group */
3502 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3503 pdb_free_sam(&sam_user);
3504 return NT_STATUS_NO_SUCH_USER;
3507 pdb_free_sam(&sam_user);
3509 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3510 return NT_STATUS_NO_SUCH_USER;
3513 if ((grp=getgrgid(map.gid)) == NULL) {
3514 passwd_free(&pwd);
3515 return NT_STATUS_NO_SUCH_GROUP;
3518 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3519 fstrcpy(grp_name, grp->gr_name);
3521 /* if the user is already in the group */
3522 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3523 passwd_free(&pwd);
3524 return NT_STATUS_MEMBER_IN_GROUP;
3528 * ok, the group exist, the user exist, the user is not in the group,
3530 * we can (finally) add it to the group !
3533 smb_add_user_group(grp_name, pwd->pw_name);
3535 /* check if the user has been added then ... */
3536 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3537 passwd_free(&pwd);
3538 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3541 passwd_free(&pwd);
3542 return NT_STATUS_OK;
3545 /*********************************************************************
3546 _samr_del_groupmem
3547 *********************************************************************/
3549 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3551 DOM_SID group_sid;
3552 DOM_SID user_sid;
3553 SAM_ACCOUNT *sam_pass=NULL;
3554 GROUP_MAP map;
3555 fstring grp_name;
3556 struct group *grp;
3557 uint32 acc_granted;
3560 * delete the group member named q_u->rid
3561 * who is a member of the sid associated with the handle
3562 * the rid is a user's rid as the group is a domain group.
3565 /* Find the policy handle. Open a policy on it. */
3566 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3567 return NT_STATUS_INVALID_HANDLE;
3569 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3570 return r_u->status;
3573 if (!sid_check_is_in_our_domain(&group_sid))
3574 return NT_STATUS_NO_SUCH_GROUP;
3576 sid_copy(&user_sid, get_global_sam_sid());
3577 sid_append_rid(&user_sid, q_u->rid);
3579 if (!get_domain_group_from_sid(group_sid, &map))
3580 return NT_STATUS_NO_SUCH_GROUP;
3582 if ((grp=getgrgid(map.gid)) == NULL)
3583 return NT_STATUS_NO_SUCH_GROUP;
3585 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3586 fstrcpy(grp_name, grp->gr_name);
3588 /* check if the user exists before trying to remove it from the group */
3589 pdb_init_sam(&sam_pass);
3590 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3591 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3592 pdb_free_sam(&sam_pass);
3593 return NT_STATUS_NO_SUCH_USER;
3596 /* if the user is not in the group */
3597 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3598 pdb_free_sam(&sam_pass);
3599 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3602 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3604 /* check if the user has been removed then ... */
3605 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3606 pdb_free_sam(&sam_pass);
3607 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3610 pdb_free_sam(&sam_pass);
3611 return NT_STATUS_OK;
3615 /****************************************************************************
3616 Delete a UNIX user on demand.
3617 ****************************************************************************/
3619 static int smb_delete_user(const char *unix_user)
3621 pstring del_script;
3622 int ret;
3624 /* try winbindd first since it is impossible to determine where
3625 a user came from via NSS. Try the delete user script if this fails
3626 meaning the user did not exist in winbindd's list of accounts */
3628 if ( winbind_delete_user( unix_user ) ) {
3629 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3630 return 0;
3634 /* fall back to 'delete user script' */
3636 pstrcpy(del_script, lp_deluser_script());
3637 if (! *del_script)
3638 return -1;
3639 all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3640 ret = smbrun(del_script,NULL);
3641 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3643 return ret;
3646 /*********************************************************************
3647 _samr_delete_dom_user
3648 *********************************************************************/
3650 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3652 DOM_SID user_sid;
3653 SAM_ACCOUNT *sam_pass=NULL;
3654 uint32 acc_granted;
3656 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3658 /* Find the policy handle. Open a policy on it. */
3659 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3660 return NT_STATUS_INVALID_HANDLE;
3662 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3663 return r_u->status;
3666 if (!sid_check_is_in_our_domain(&user_sid))
3667 return NT_STATUS_CANNOT_DELETE;
3669 /* check if the user exists before trying to delete */
3670 pdb_init_sam(&sam_pass);
3671 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3672 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3673 sid_string_static(&user_sid)));
3674 pdb_free_sam(&sam_pass);
3675 return NT_STATUS_NO_SUCH_USER;
3678 /* First delete the samba side */
3679 if (!pdb_delete_sam_account(sam_pass)) {
3680 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3681 pdb_free_sam(&sam_pass);
3682 return NT_STATUS_CANNOT_DELETE;
3685 /* Now delete the unix side */
3687 * note: we don't check if the delete really happened
3688 * as the script is not necessary present
3689 * and maybe the sysadmin doesn't want to delete the unix side
3691 smb_delete_user(pdb_get_username(sam_pass));
3694 pdb_free_sam(&sam_pass);
3696 if (!close_policy_hnd(p, &q_u->user_pol))
3697 return NT_STATUS_OBJECT_NAME_INVALID;
3699 return NT_STATUS_OK;
3702 /*********************************************************************
3703 _samr_delete_dom_group
3704 *********************************************************************/
3706 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3708 DOM_SID group_sid;
3709 DOM_SID dom_sid;
3710 uint32 group_rid;
3711 fstring group_sid_str;
3712 gid_t gid;
3713 struct group *grp;
3714 GROUP_MAP map;
3715 uint32 acc_granted;
3717 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3719 /* Find the policy handle. Open a policy on it. */
3720 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3721 return NT_STATUS_INVALID_HANDLE;
3723 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3724 return r_u->status;
3727 sid_copy(&dom_sid, &group_sid);
3728 sid_to_string(group_sid_str, &dom_sid);
3729 sid_split_rid(&dom_sid, &group_rid);
3731 DEBUG(10, ("sid is %s\n", group_sid_str));
3733 /* we check if it's our SID before deleting */
3734 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3735 return NT_STATUS_NO_SUCH_GROUP;
3737 DEBUG(10, ("lookup on Domain SID\n"));
3739 if(!get_domain_group_from_sid(group_sid, &map))
3740 return NT_STATUS_NO_SUCH_GROUP;
3742 gid=map.gid;
3744 /* check if group really exists */
3745 if ( (grp=getgrgid(gid)) == NULL)
3746 return NT_STATUS_NO_SUCH_GROUP;
3748 /* delete mapping first */
3749 if(!pdb_delete_group_mapping_entry(group_sid))
3750 return NT_STATUS_ACCESS_DENIED;
3752 /* we can delete the UNIX group */
3753 smb_delete_group(grp->gr_name);
3755 /* check if the group has been successfully deleted */
3756 if ( (grp=getgrgid(gid)) != NULL)
3757 return NT_STATUS_ACCESS_DENIED;
3760 if (!close_policy_hnd(p, &q_u->group_pol))
3761 return NT_STATUS_OBJECT_NAME_INVALID;
3763 return NT_STATUS_OK;
3766 /*********************************************************************
3767 _samr_delete_dom_alias
3768 *********************************************************************/
3770 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3772 DOM_SID alias_sid;
3773 uint32 acc_granted;
3775 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3777 /* Find the policy handle. Open a policy on it. */
3778 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3779 return NT_STATUS_INVALID_HANDLE;
3781 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3782 return r_u->status;
3785 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3787 if (!sid_check_is_in_our_domain(&alias_sid))
3788 return NT_STATUS_NO_SUCH_ALIAS;
3790 DEBUG(10, ("lookup on Local SID\n"));
3792 /* Have passdb delete the alias */
3793 if (!pdb_delete_alias(&alias_sid))
3794 return NT_STATUS_ACCESS_DENIED;
3796 if (!close_policy_hnd(p, &q_u->alias_pol))
3797 return NT_STATUS_OBJECT_NAME_INVALID;
3799 return NT_STATUS_OK;
3802 /*********************************************************************
3803 _samr_create_dom_group
3804 *********************************************************************/
3806 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3808 DOM_SID dom_sid;
3809 DOM_SID info_sid;
3810 fstring name;
3811 fstring sid_string;
3812 struct group *grp;
3813 struct samr_info *info;
3814 uint32 acc_granted;
3815 gid_t gid;
3817 /* Find the policy handle. Open a policy on it. */
3818 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3819 return NT_STATUS_INVALID_HANDLE;
3821 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3822 return r_u->status;
3825 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3826 return NT_STATUS_ACCESS_DENIED;
3828 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3830 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3832 /* check if group already exist */
3833 if ((grp=getgrnam(name)) != NULL)
3834 return NT_STATUS_GROUP_EXISTS;
3836 /* we can create the UNIX group */
3837 if (smb_create_group(name, &gid) != 0)
3838 return NT_STATUS_ACCESS_DENIED;
3840 /* check if the group has been successfully created */
3841 if ((grp=getgrgid(gid)) == NULL)
3842 return NT_STATUS_ACCESS_DENIED;
3844 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3846 /* add the group to the mapping table */
3847 sid_copy(&info_sid, get_global_sam_sid());
3848 sid_append_rid(&info_sid, r_u->rid);
3849 sid_to_string(sid_string, &info_sid);
3851 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3852 return NT_STATUS_ACCESS_DENIED;
3854 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3855 return NT_STATUS_NO_MEMORY;
3857 /* get a (unique) handle. open a policy on it. */
3858 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3859 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3861 return NT_STATUS_OK;
3864 /*********************************************************************
3865 _samr_create_dom_alias
3866 *********************************************************************/
3868 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3870 DOM_SID dom_sid;
3871 DOM_SID info_sid;
3872 fstring name;
3873 struct group *grp;
3874 struct samr_info *info;
3875 uint32 acc_granted;
3876 gid_t gid;
3877 NTSTATUS result;
3879 /* Find the policy handle. Open a policy on it. */
3880 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3881 return NT_STATUS_INVALID_HANDLE;
3883 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3884 return r_u->status;
3887 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3888 return NT_STATUS_ACCESS_DENIED;
3890 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3892 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3894 /* Have passdb create the alias */
3895 result = pdb_create_alias(name, &r_u->rid);
3897 if (!NT_STATUS_IS_OK(result))
3898 return result;
3900 sid_copy(&info_sid, get_global_sam_sid());
3901 sid_append_rid(&info_sid, r_u->rid);
3903 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
3904 return NT_STATUS_ACCESS_DENIED;
3906 /* check if the group has been successfully created */
3907 if ((grp=getgrgid(gid)) == NULL)
3908 return NT_STATUS_ACCESS_DENIED;
3910 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3911 return NT_STATUS_NO_MEMORY;
3913 /* get a (unique) handle. open a policy on it. */
3914 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3915 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3917 return NT_STATUS_OK;
3920 /*********************************************************************
3921 _samr_query_groupinfo
3923 sends the name/comment pair of a domain group
3924 level 1 send also the number of users of that group
3925 *********************************************************************/
3927 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3929 DOM_SID group_sid;
3930 GROUP_MAP map;
3931 DOM_SID *sids=NULL;
3932 uid_t *uids;
3933 int num=0;
3934 GROUP_INFO_CTR *ctr;
3935 uint32 acc_granted;
3936 BOOL ret;
3938 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3939 return NT_STATUS_INVALID_HANDLE;
3941 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
3942 return r_u->status;
3945 become_root();
3946 ret = get_domain_group_from_sid(group_sid, &map);
3947 unbecome_root();
3948 if (!ret)
3949 return NT_STATUS_INVALID_HANDLE;
3951 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
3952 if (ctr==NULL)
3953 return NT_STATUS_NO_MEMORY;
3955 switch (q_u->switch_level) {
3956 case 1:
3957 ctr->switch_value1 = 1;
3958 if(!get_memberuids(map.gid, &uids, &num))
3959 return NT_STATUS_NO_SUCH_GROUP;
3960 SAFE_FREE(uids);
3961 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
3962 SAFE_FREE(sids);
3963 break;
3964 case 3:
3965 ctr->switch_value1 = 3;
3966 init_samr_group_info3(&ctr->group.info3);
3967 break;
3968 case 4:
3969 ctr->switch_value1 = 4;
3970 init_samr_group_info4(&ctr->group.info4, map.comment);
3971 break;
3972 default:
3973 return NT_STATUS_INVALID_INFO_CLASS;
3976 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
3978 return NT_STATUS_OK;
3981 /*********************************************************************
3982 _samr_set_groupinfo
3984 update a domain group's comment.
3985 *********************************************************************/
3987 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
3989 DOM_SID group_sid;
3990 GROUP_MAP map;
3991 GROUP_INFO_CTR *ctr;
3992 uint32 acc_granted;
3994 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3995 return NT_STATUS_INVALID_HANDLE;
3997 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
3998 return r_u->status;
4001 if (!get_domain_group_from_sid(group_sid, &map))
4002 return NT_STATUS_NO_SUCH_GROUP;
4004 ctr=q_u->ctr;
4006 switch (ctr->switch_value1) {
4007 case 1:
4008 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4009 break;
4010 case 4:
4011 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4012 break;
4013 default:
4014 return NT_STATUS_INVALID_INFO_CLASS;
4017 if(!pdb_update_group_mapping_entry(&map)) {
4018 return NT_STATUS_NO_SUCH_GROUP;
4021 return NT_STATUS_OK;
4024 /*********************************************************************
4025 _samr_set_aliasinfo
4027 update an alias's comment.
4028 *********************************************************************/
4030 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4032 DOM_SID group_sid;
4033 struct acct_info info;
4034 ALIAS_INFO_CTR *ctr;
4035 uint32 acc_granted;
4037 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4038 return NT_STATUS_INVALID_HANDLE;
4040 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4041 return r_u->status;
4044 ctr=&q_u->ctr;
4046 switch (ctr->switch_value1) {
4047 case 3:
4048 unistr2_to_ascii(info.acct_desc,
4049 &(ctr->alias.info3.uni_acct_desc),
4050 sizeof(info.acct_desc)-1);
4051 break;
4052 default:
4053 return NT_STATUS_INVALID_INFO_CLASS;
4056 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4057 return NT_STATUS_ACCESS_DENIED;
4060 return NT_STATUS_OK;
4063 /*********************************************************************
4064 _samr_get_dom_pwinfo
4065 *********************************************************************/
4067 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4069 /* Perform access check. Since this rpc does not require a
4070 policy handle it will not be caught by the access checks on
4071 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4073 if (!pipe_access_check(p)) {
4074 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4075 r_u->status = NT_STATUS_ACCESS_DENIED;
4076 return r_u->status;
4079 /* Actually, returning zeros here works quite well :-). */
4081 return NT_STATUS_OK;
4084 /*********************************************************************
4085 _samr_open_group
4086 *********************************************************************/
4088 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4090 DOM_SID sid;
4091 DOM_SID info_sid;
4092 GROUP_MAP map;
4093 struct samr_info *info;
4094 SEC_DESC *psd = NULL;
4095 uint32 acc_granted;
4096 uint32 des_access = q_u->access_mask;
4097 size_t sd_size;
4098 NTSTATUS status;
4099 fstring sid_string;
4100 BOOL ret;
4102 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4103 return NT_STATUS_INVALID_HANDLE;
4105 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4106 return status;
4109 /*check if access can be granted as requested by client. */
4110 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4111 se_map_generic(&des_access,&grp_generic_mapping);
4112 if (!NT_STATUS_IS_OK(status =
4113 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4114 des_access, &acc_granted, "_samr_open_group"))) {
4115 return status;
4119 /* this should not be hard-coded like this */
4120 if (!sid_equal(&sid, get_global_sam_sid()))
4121 return NT_STATUS_ACCESS_DENIED;
4123 sid_copy(&info_sid, get_global_sam_sid());
4124 sid_append_rid(&info_sid, q_u->rid_group);
4125 sid_to_string(sid_string, &info_sid);
4127 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4128 return NT_STATUS_NO_MEMORY;
4130 info->acc_granted = acc_granted;
4132 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4134 /* check if that group really exists */
4135 become_root();
4136 ret = get_domain_group_from_sid(info->sid, &map);
4137 unbecome_root();
4138 if (!ret)
4139 return NT_STATUS_NO_SUCH_GROUP;
4141 /* get a (unique) handle. open a policy on it. */
4142 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4143 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4145 return NT_STATUS_OK;
4148 /*********************************************************************
4149 _samr_remove_sid_foreign_domain
4150 *********************************************************************/
4152 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4153 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4154 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4156 DOM_SID delete_sid, alias_sid;
4157 SAM_ACCOUNT *sam_pass=NULL;
4158 uint32 acc_granted;
4159 GROUP_MAP map;
4160 BOOL is_user = False;
4161 NTSTATUS result;
4162 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4164 sid_copy( &delete_sid, &q_u->sid.sid );
4166 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4167 sid_string_static(&delete_sid)));
4169 /* Find the policy handle. Open a policy on it. */
4171 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4172 return NT_STATUS_INVALID_HANDLE;
4174 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4175 "_samr_remove_sid_foreign_domain");
4177 if (!NT_STATUS_IS_OK(result))
4178 return result;
4180 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4181 sid_string_static(&alias_sid)));
4183 /* make sure we can handle this */
4185 if ( sid_check_is_domain(&alias_sid) )
4186 type = SID_NAME_DOM_GRP;
4187 else if ( sid_check_is_builtin(&alias_sid) )
4188 type = SID_NAME_ALIAS;
4190 if ( type == SID_NAME_UNKNOWN ) {
4191 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4192 return NT_STATUS_OK;
4195 /* check if the user exists before trying to delete */
4197 pdb_init_sam(&sam_pass);
4199 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4200 is_user = True;
4201 } else {
4202 /* maybe it is a group */
4203 if( !pdb_getgrsid(&map, delete_sid) ) {
4204 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4205 sid_string_static(&delete_sid)));
4206 result = NT_STATUS_INVALID_SID;
4207 goto done;
4211 /* we can only delete a user from a group since we don't have
4212 nested groups anyways. So in the latter case, just say OK */
4214 if ( is_user ) {
4215 GROUP_MAP *mappings = NULL;
4216 int num_groups, i;
4217 struct group *grp2;
4219 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4221 /* interate over the groups */
4222 for ( i=0; i<num_groups; i++ ) {
4224 grp2 = getgrgid(mappings[i].gid);
4226 if ( !grp2 ) {
4227 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4228 continue;
4231 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4232 continue;
4234 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4236 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4237 /* should we fail here ? */
4238 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4239 pdb_get_username(sam_pass), grp2->gr_name ));
4240 continue;
4243 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4244 pdb_get_username(sam_pass), grp2->gr_name ));
4247 SAFE_FREE(mappings);
4251 result = NT_STATUS_OK;
4252 done:
4254 pdb_free_sam(&sam_pass);
4256 return result;
4259 /*******************************************************************
4260 _samr_unknown_2e
4261 ********************************************************************/
4263 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4265 struct samr_info *info = NULL;
4266 SAM_UNK_CTR *ctr;
4267 uint32 min_pass_len,pass_hist,flag;
4268 time_t u_expire, u_min_age;
4269 NTTIME nt_expire, nt_min_age;
4271 time_t u_lock_duration, u_reset_time;
4272 NTTIME nt_lock_duration, nt_reset_time;
4273 uint32 lockout;
4275 time_t u_logout;
4276 NTTIME nt_logout;
4278 uint32 num_users=0, num_groups=0, num_aliases=0;
4280 uint32 account_policy_temp;
4282 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4283 return NT_STATUS_NO_MEMORY;
4285 ZERO_STRUCTP(ctr);
4287 r_u->status = NT_STATUS_OK;
4289 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4291 /* find the policy handle. open a policy on it. */
4292 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4293 return NT_STATUS_INVALID_HANDLE;
4295 switch (q_u->switch_value) {
4296 case 0x01:
4297 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4298 min_pass_len = account_policy_temp;
4300 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4301 pass_hist = account_policy_temp;
4303 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4304 flag = account_policy_temp;
4306 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4307 u_expire = account_policy_temp;
4309 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4310 u_min_age = account_policy_temp;
4312 unix_to_nt_time_abs(&nt_expire, u_expire);
4313 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4315 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4316 flag, nt_expire, nt_min_age);
4317 break;
4318 case 0x02:
4319 become_root();
4320 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4321 unbecome_root();
4322 if (!NT_STATUS_IS_OK(r_u->status)) {
4323 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4324 return r_u->status;
4326 num_users=info->disp_info.num_user_account;
4327 free_samr_db(info);
4329 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4330 if (NT_STATUS_IS_ERR(r_u->status)) {
4331 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4332 return r_u->status;
4334 num_groups=info->disp_info.num_group_account;
4335 free_samr_db(info);
4337 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4338 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4339 num_users, num_groups, num_aliases);
4340 break;
4341 case 0x03:
4342 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4343 u_logout = account_policy_temp;
4345 unix_to_nt_time_abs(&nt_logout, u_logout);
4347 init_unk_info3(&ctr->info.inf3, nt_logout);
4348 break;
4349 case 0x05:
4350 init_unk_info5(&ctr->info.inf5, global_myname());
4351 break;
4352 case 0x06:
4353 init_unk_info6(&ctr->info.inf6);
4354 break;
4355 case 0x07:
4356 init_unk_info7(&ctr->info.inf7);
4357 break;
4358 case 0x0c:
4359 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4360 u_lock_duration = account_policy_temp * 60;
4362 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4363 u_reset_time = account_policy_temp * 60;
4365 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4366 lockout = account_policy_temp;
4368 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4369 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4371 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4372 break;
4373 default:
4374 return NT_STATUS_INVALID_INFO_CLASS;
4377 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4379 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4381 return r_u->status;
4384 /*******************************************************************
4385 _samr_
4386 ********************************************************************/
4388 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4390 time_t u_expire, u_min_age;
4391 time_t u_logout;
4392 time_t u_lock_duration, u_reset_time;
4394 r_u->status = NT_STATUS_OK;
4396 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4398 /* find the policy handle. open a policy on it. */
4399 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4400 return NT_STATUS_INVALID_HANDLE;
4402 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4404 switch (q_u->switch_value) {
4405 case 0x01:
4406 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4407 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4409 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4410 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4411 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4412 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4413 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4414 break;
4415 case 0x02:
4416 break;
4417 case 0x03:
4418 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4419 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4420 break;
4421 case 0x05:
4422 break;
4423 case 0x06:
4424 break;
4425 case 0x07:
4426 break;
4427 case 0x0c:
4428 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
4429 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4431 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4432 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4433 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4434 break;
4435 default:
4436 return NT_STATUS_INVALID_INFO_CLASS;
4439 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4441 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4443 return r_u->status;