Handle munged dial string. Patch from Aur?lien Degr?mont <adegremont@idealx.com>with...
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_samr_nt.c
blob446eff9045e3108dd3aa5f7dfe9e23c077223cc5
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002.
11 * Copyright (C) Gerald (Jerry) Carter 2003.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
32 #include "includes.h"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
44 typedef struct _disp_info {
45 BOOL user_dbloaded;
46 uint32 num_user_account;
47 SAM_ACCOUNT *disp_user_info;
48 BOOL group_dbloaded;
49 uint32 num_group_account;
50 DOMAIN_GRP *disp_group_info;
51 } DISP_INFO;
53 struct samr_info {
54 /* for use by the \PIPE\samr policy */
55 DOM_SID sid;
56 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
57 uint32 acc_granted;
58 uint16 acb_mask;
59 BOOL all_machines;
60 DISP_INFO disp_info;
62 TALLOC_CTX *mem_ctx;
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
79 uint32 *acc_granted, const char *debug)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
83 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84 *acc_granted = des_access;
85 if (geteuid() == sec_initial_uid()) {
86 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
87 debug, des_access));
88 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89 status = NT_STATUS_OK;
91 else {
92 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
93 debug, des_access));
96 return status;
99 /*******************************************************************
100 Checks if access to a function can be granted
101 ********************************************************************/
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
105 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
106 debug, acc_granted, acc_required));
107 if ((acc_granted & acc_required) != acc_required) {
108 if (geteuid() == sec_initial_uid()) {
109 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
110 debug, acc_granted, acc_required));
111 DEBUGADD(4,("but overwritten by euid == 0\n"));
112 return NT_STATUS_OK;
114 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
115 debug, acc_granted, acc_required));
116 return NT_STATUS_ACCESS_DENIED;
118 return NT_STATUS_OK;
122 /*******************************************************************
123 Create a samr_info struct.
124 ********************************************************************/
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
128 struct samr_info *info;
129 fstring sid_str;
130 TALLOC_CTX *mem_ctx;
132 if (psid) {
133 sid_to_string(sid_str, psid);
134 } else {
135 fstrcpy(sid_str,"(NULL)");
138 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
140 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
141 return NULL;
143 ZERO_STRUCTP(info);
144 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
145 if (psid) {
146 sid_copy( &info->sid, psid);
147 } else {
148 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
150 info->mem_ctx = mem_ctx;
151 return info;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
158 static void free_samr_users(struct samr_info *info)
160 int i;
162 if (info->disp_info.user_dbloaded){
163 for (i=0; i<info->disp_info.num_user_account; i++) {
164 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165 /* Not really a free, actually a 'clear' */
166 pdb_free_sam(&sam);
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
187 static void free_samr_info(void *ptr)
189 struct samr_info *info=(struct samr_info *) ptr;
191 free_samr_db(info);
192 talloc_destroy(info->mem_ctx);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
202 if (!sam_pass)
203 return;
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
214 SAM_ACCOUNT *pwd = NULL;
215 SAM_ACCOUNT *pwd_array = NULL;
216 NTSTATUS nt_status = NT_STATUS_OK;
217 TALLOC_CTX *mem_ctx = info->mem_ctx;
219 DEBUG(10,("load_sampwd_entries\n"));
221 /* if the snapshoot is already loaded, return */
222 if ((info->disp_info.user_dbloaded==True)
223 && (info->acb_mask == acb_mask)
224 && (info->all_machines == all_machines)) {
225 DEBUG(10,("load_sampwd_entries: already in memory\n"));
226 return NT_STATUS_OK;
229 free_samr_users(info);
231 if (!pdb_setsampwent(False)) {
232 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233 return NT_STATUS_ACCESS_DENIED;
236 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
237 && pdb_getsampwent(pwd) == True; pwd=NULL) {
239 if (all_machines) {
240 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
241 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
243 pdb_free_sam(&pwd);
244 continue;
246 } else {
247 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
248 pdb_free_sam(&pwd);
249 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
250 continue;
254 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
257 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258 pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
259 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
261 if (pwd_array==NULL)
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* Copy the SAM_ACCOUNT into the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
270 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
272 info->disp_info.num_user_account++;
275 pdb_endsampwent();
277 /* the snapshoot is in memory, we're ready to enumerate fast */
279 info->acb_mask = acb_mask;
280 info->all_machines = all_machines;
281 info->disp_info.user_dbloaded=True;
283 DEBUG(10,("load_sampwd_entries: done\n"));
285 return nt_status;
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
290 GROUP_MAP *map=NULL;
291 DOMAIN_GRP *grp_array = NULL;
292 uint32 group_entries = 0;
293 uint32 i;
294 TALLOC_CTX *mem_ctx = info->mem_ctx;
296 DEBUG(10,("load_group_domain_entries\n"));
298 /* if the snapshoot is already loaded, return */
299 if (info->disp_info.group_dbloaded==True) {
300 DEBUG(10,("load_group_domain_entries: already in memory\n"));
301 return NT_STATUS_OK;
305 become_root();
307 if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED)) {
308 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
309 return NT_STATUS_NO_MEMORY;
312 unbecome_root();
314 info->disp_info.num_group_account=group_entries;
316 grp_array=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
317 if (group_entries!=0 && grp_array==NULL) {
318 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
319 SAFE_FREE(map);
320 return NT_STATUS_NO_MEMORY;
323 info->disp_info.disp_group_info=grp_array;
325 for (i=0; i<group_entries; i++) {
326 fstrcpy(grp_array[i].name, map[i].nt_name);
327 fstrcpy(grp_array[i].comment, map[i].comment);
328 sid_split_rid(&map[i].sid, &grp_array[i].rid);
329 grp_array[i].attr=SID_NAME_DOM_GRP;
332 SAFE_FREE(map);
334 /* the snapshoot is in memory, we're ready to enumerate fast */
336 info->disp_info.group_dbloaded=True;
338 DEBUG(10,("load_group_domain_entries: done\n"));
340 return NT_STATUS_OK;
344 /*******************************************************************
345 _samr_close_hnd
346 ********************************************************************/
348 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
350 r_u->status = NT_STATUS_OK;
352 /* close the policy handle */
353 if (!close_policy_hnd(p, &q_u->pol))
354 return NT_STATUS_OBJECT_NAME_INVALID;
356 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
358 return r_u->status;
361 /*******************************************************************
362 samr_reply_open_domain
363 ********************************************************************/
365 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
367 struct samr_info *info;
368 SEC_DESC *psd = NULL;
369 uint32 acc_granted;
370 uint32 des_access = q_u->flags;
371 size_t sd_size;
372 NTSTATUS status;
374 r_u->status = NT_STATUS_OK;
376 /* find the connection policy handle. */
377 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
378 return NT_STATUS_INVALID_HANDLE;
380 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
381 return status;
384 /*check if access can be granted as requested by client. */
385 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
386 se_map_generic(&des_access,&dom_generic_mapping);
388 if (!NT_STATUS_IS_OK(status =
389 access_check_samr_object(psd, p->pipe_user.nt_user_token,
390 des_access, &acc_granted, "_samr_open_domain"))) {
391 return status;
394 /* associate the domain SID with the (unique) handle. */
395 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
396 return NT_STATUS_NO_MEMORY;
397 info->acc_granted = acc_granted;
399 /* get a (unique) handle. open a policy on it. */
400 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
401 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
403 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
405 return r_u->status;
408 /*******************************************************************
409 _samr_get_usrdom_pwinfo
410 ********************************************************************/
412 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
414 struct samr_info *info = NULL;
416 r_u->status = NT_STATUS_OK;
418 /* find the policy handle. open a policy on it. */
419 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
420 return NT_STATUS_INVALID_HANDLE;
422 if (!sid_check_is_in_our_domain(&info->sid))
423 return NT_STATUS_OBJECT_TYPE_MISMATCH;
425 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
427 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
430 * NT sometimes return NT_STATUS_ACCESS_DENIED
431 * I don't know yet why.
434 return r_u->status;
437 /*******************************************************************
438 samr_make_dom_obj_sd
439 ********************************************************************/
441 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
443 extern DOM_SID global_sid_World;
444 DOM_SID adm_sid;
445 DOM_SID act_sid;
447 SEC_ACE ace[3];
448 SEC_ACCESS mask;
450 SEC_ACL *psa = NULL;
452 sid_copy(&adm_sid, &global_sid_Builtin);
453 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
455 sid_copy(&act_sid, &global_sid_Builtin);
456 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
458 /*basic access for every one*/
459 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
460 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
462 /*full access for builtin aliases Administrators and Account Operators*/
463 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
464 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
465 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
467 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
468 return NT_STATUS_NO_MEMORY;
470 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
471 return NT_STATUS_NO_MEMORY;
473 return NT_STATUS_OK;
476 /*******************************************************************
477 samr_make_usr_obj_sd
478 ********************************************************************/
480 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
482 extern DOM_SID global_sid_World;
483 DOM_SID adm_sid;
484 DOM_SID act_sid;
486 SEC_ACE ace[4];
487 SEC_ACCESS mask;
489 SEC_ACL *psa = NULL;
491 sid_copy(&adm_sid, &global_sid_Builtin);
492 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
494 sid_copy(&act_sid, &global_sid_Builtin);
495 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
497 /*basic access for every one*/
498 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
499 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
501 /*full access for builtin aliases Administrators and Account Operators*/
502 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
503 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
504 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
506 /*extended access for the user*/
507 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
508 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
511 return NT_STATUS_NO_MEMORY;
513 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
514 return NT_STATUS_NO_MEMORY;
516 return NT_STATUS_OK;
519 /*******************************************************************
520 samr_make_grp_obj_sd
521 ********************************************************************/
523 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
525 extern DOM_SID global_sid_World;
526 DOM_SID adm_sid;
527 DOM_SID act_sid;
529 SEC_ACE ace[3];
530 SEC_ACCESS mask;
532 SEC_ACL *psa = NULL;
534 sid_copy(&adm_sid, &global_sid_Builtin);
535 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
537 sid_copy(&act_sid, &global_sid_Builtin);
538 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
540 /*basic access for every one*/
541 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
542 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
544 /*full access for builtin aliases Administrators and Account Operators*/
545 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
546 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
547 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
549 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
550 return NT_STATUS_NO_MEMORY;
552 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
553 return NT_STATUS_NO_MEMORY;
555 return NT_STATUS_OK;
558 /*******************************************************************
559 samr_make_ali_obj_sd
560 ********************************************************************/
562 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
564 extern DOM_SID global_sid_World;
565 DOM_SID adm_sid;
566 DOM_SID act_sid;
568 SEC_ACE ace[3];
569 SEC_ACCESS mask;
571 SEC_ACL *psa = NULL;
573 sid_copy(&adm_sid, &global_sid_Builtin);
574 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
576 sid_copy(&act_sid, &global_sid_Builtin);
577 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
579 /*basic access for every one*/
580 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
581 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
583 /*full access for builtin aliases Administrators and Account Operators*/
584 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
585 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
588 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
589 return NT_STATUS_NO_MEMORY;
591 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
592 return NT_STATUS_NO_MEMORY;
594 return NT_STATUS_OK;
597 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
599 struct samr_info *info = NULL;
601 /* find the policy handle. open a policy on it. */
602 if (!find_policy_by_hnd(p, pol, (void **)&info))
603 return False;
605 if (!info)
606 return False;
608 *sid = info->sid;
609 *acc_granted = info->acc_granted;
610 return True;
613 /*******************************************************************
614 _samr_set_sec_obj
615 ********************************************************************/
617 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
619 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
620 return NT_STATUS_NOT_IMPLEMENTED;
624 /*******************************************************************
625 _samr_query_sec_obj
626 ********************************************************************/
628 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
630 DOM_SID pol_sid;
631 fstring str_sid;
632 SEC_DESC * psd = NULL;
633 size_t sd_size;
634 uint32 acc_granted;
636 r_u->status = NT_STATUS_OK;
638 /* Get the SID. */
639 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
640 return NT_STATUS_INVALID_HANDLE;
644 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
646 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
648 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
649 if (pol_sid.sid_rev_num == 0)
651 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
652 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
654 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
657 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
658 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
660 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
662 /* TODO: Builtin probably needs a different SD with restricted write access*/
663 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
664 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
666 else if (sid_check_is_in_our_domain(&pol_sid) ||
667 sid_check_is_in_builtin(&pol_sid))
669 /* TODO: different SDs have to be generated for aliases groups and users.
670 Currently all three get a default user SD */
671 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
672 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
674 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
676 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
677 return NT_STATUS_NO_MEMORY;
679 if (NT_STATUS_IS_OK(r_u->status))
680 r_u->ptr = 1;
682 return r_u->status;
685 /*******************************************************************
686 makes a SAM_ENTRY / UNISTR2* structure from a user list.
687 ********************************************************************/
689 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
690 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
691 DOM_SID *domain_sid)
693 uint32 i;
694 SAM_ENTRY *sam;
695 UNISTR2 *uni_name;
696 SAM_ACCOUNT *pwd = NULL;
697 UNISTR2 uni_temp_name;
698 const char *temp_name;
699 const DOM_SID *user_sid;
700 uint32 user_rid;
701 fstring user_sid_string;
702 fstring domain_sid_string;
704 *sam_pp = NULL;
705 *uni_name_pp = NULL;
707 if (num_entries == 0)
708 return NT_STATUS_OK;
710 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
712 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
714 if (sam == NULL || uni_name == NULL) {
715 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
716 return NT_STATUS_NO_MEMORY;
719 for (i = 0; i < num_entries; i++) {
720 pwd = &disp_user_info[i+start_idx];
721 temp_name = pdb_get_username(pwd);
722 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
723 user_sid = pdb_get_user_sid(pwd);
725 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
726 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
727 "the domain sid %s. Failing operation.\n",
728 temp_name,
729 sid_to_string(user_sid_string, user_sid),
730 sid_to_string(domain_sid_string, domain_sid)));
731 return NT_STATUS_UNSUCCESSFUL;
734 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
735 copy_unistr2(&uni_name[i], &uni_temp_name);
738 *sam_pp = sam;
739 *uni_name_pp = uni_name;
740 return NT_STATUS_OK;
743 /*******************************************************************
744 samr_reply_enum_dom_users
745 ********************************************************************/
747 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
748 SAMR_R_ENUM_DOM_USERS *r_u)
750 struct samr_info *info = NULL;
751 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
752 int num_account;
753 uint32 enum_context=q_u->start_idx;
754 uint32 max_size=q_u->max_size;
755 uint32 temp_size;
756 enum remote_arch_types ra_type = get_remote_arch();
757 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
758 uint32 max_entries = max_sam_entries;
759 DOM_SID domain_sid;
761 r_u->status = NT_STATUS_OK;
763 /* find the policy handle. open a policy on it. */
764 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
765 return NT_STATUS_INVALID_HANDLE;
767 domain_sid = info->sid;
769 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
770 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
771 "_samr_enum_dom_users"))) {
772 return r_u->status;
775 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
777 become_root();
778 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
779 unbecome_root();
781 if (!NT_STATUS_IS_OK(r_u->status))
782 return r_u->status;
784 num_account = info->disp_info.num_user_account;
786 if (enum_context > num_account) {
787 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
788 return NT_STATUS_OK;
791 /* verify we won't overflow */
792 if (max_entries > num_account-enum_context) {
793 max_entries = num_account-enum_context;
794 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
797 /* calculate the size and limit on the number of entries we will return */
798 temp_size=max_entries*struct_size;
800 if (temp_size>max_size) {
801 max_entries=MIN((max_size/struct_size),max_entries);;
802 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
806 * Note from JRA. total_entries is not being used here. Currently if there is a
807 * large user base then it looks like NT will enumerate until get_sampwd_entries
808 * returns False due to num_entries being zero. This will cause an access denied
809 * return. I don't think this is right and needs further investigation. Note that
810 * this is also the same in the TNG code (I don't think that has been tested with
811 * a very large user list as MAX_SAM_ENTRIES is set to 600).
813 * I also think that one of the 'num_entries' return parameters is probably
814 * the "max entries" parameter - but in the TNG code they're all currently set to the same
815 * value (again I think this is wrong).
818 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
819 max_entries, enum_context,
820 info->disp_info.disp_user_info,
821 &domain_sid);
823 if (!NT_STATUS_IS_OK(r_u->status))
824 return r_u->status;
826 if (enum_context+max_entries < num_account)
827 r_u->status = STATUS_MORE_ENTRIES;
829 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
831 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
833 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
835 return r_u->status;
838 /*******************************************************************
839 makes a SAM_ENTRY / UNISTR2* structure from a group list.
840 ********************************************************************/
842 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
843 uint32 num_sam_entries, DOMAIN_GRP *grp)
845 uint32 i;
846 SAM_ENTRY *sam;
847 UNISTR2 *uni_name;
849 *sam_pp = NULL;
850 *uni_name_pp = NULL;
852 if (num_sam_entries == 0)
853 return;
855 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
857 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
859 if (sam == NULL || uni_name == NULL) {
860 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
861 return;
864 for (i = 0; i < num_sam_entries; i++) {
866 * JRA. I think this should include the null. TNG does not.
868 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
869 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
872 *sam_pp = sam;
873 *uni_name_pp = uni_name;
876 /*******************************************************************
877 Get the group entries - similar to get_sampwd_entries().
878 ********************************************************************/
880 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
881 uint32 *p_num_entries, uint32 max_entries)
883 fstring sid_str;
884 uint32 num_entries = 0;
885 int i;
886 GROUP_MAP smap;
887 GROUP_MAP *map = NULL;
889 sid_to_string(sid_str, sid);
890 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
892 *p_num_entries = 0;
894 /* well-known aliases */
895 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
897 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED);
899 if (num_entries != 0) {
900 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
901 if (*d_grp==NULL)
902 return NT_STATUS_NO_MEMORY;
904 for(i=0; i<num_entries && i<max_entries; i++) {
905 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
906 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
910 SAFE_FREE(map);
912 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
913 struct sys_grent *glist;
914 struct sys_grent *grp;
915 gid_t winbind_gid_low, winbind_gid_high;
916 BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
918 /* local aliases */
919 /* we return the UNIX groups here. This seems to be the right */
920 /* thing to do, since NT member servers return their local */
921 /* groups in the same situation. */
923 /* use getgrent_list() to retrieve the list of groups to avoid
924 * problems with getgrent possible infinite loop by internal
925 * libc grent structures overwrites by called functions */
926 grp = glist = getgrent_list();
927 if (grp == NULL)
928 return NT_STATUS_NO_MEMORY;
930 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
931 uint32 trid;
933 if(!pdb_getgrgid(&smap, grp->gr_gid))
934 continue;
936 if (smap.sid_name_use!=SID_NAME_ALIAS) {
937 continue;
940 sid_split_rid(&smap.sid, &trid);
942 if (!sid_equal(sid, &smap.sid))
943 continue;
945 /* Don't return winbind groups as they are not local! */
946 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
947 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
948 continue;
951 /* Don't return user private groups... */
953 if (Get_Pwnam(smap.nt_name) != 0) {
954 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
955 continue;
958 for( i = 0; i < num_entries; i++)
959 if ( (*d_grp)[i].rid == trid )
960 break;
962 if ( i < num_entries ) {
963 continue; /* rid was there, dup! */
966 /* JRA - added this for large group db enumeration... */
968 if (start_idx > 0) {
969 /* skip the requested number of entries.
970 not very efficient, but hey...
972 start_idx--;
973 continue;
976 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
977 if (*d_grp==NULL) {
978 grent_free(glist);
979 return NT_STATUS_NO_MEMORY;
982 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
983 (*d_grp)[num_entries].rid = trid;
984 num_entries++;
985 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
988 grent_free(glist);
991 *p_num_entries = num_entries;
993 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
995 if (num_entries >= max_entries)
996 return STATUS_MORE_ENTRIES;
997 return NT_STATUS_OK;
1000 /*******************************************************************
1001 Get the group entries - similar to get_sampwd_entries().
1002 ********************************************************************/
1004 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1005 uint32 *p_num_entries, uint32 max_entries)
1007 GROUP_MAP *map=NULL;
1008 int i;
1009 uint32 group_entries = 0;
1010 uint32 num_entries = 0;
1012 *p_num_entries = 0;
1014 /* access checks for the users were performed higher up. become/unbecome_root()
1015 needed for some passdb backends to enumerate groups */
1017 become_root();
1018 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
1019 unbecome_root();
1021 num_entries=group_entries-start_idx;
1023 /* limit the number of entries */
1024 if (num_entries>max_entries) {
1025 DEBUG(5,("Limiting to %d entries\n", max_entries));
1026 num_entries=max_entries;
1029 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1030 if (num_entries!=0 && *d_grp==NULL){
1031 SAFE_FREE(map);
1032 return NT_STATUS_NO_MEMORY;
1035 for (i=0; i<num_entries; i++) {
1036 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1037 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1038 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1039 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1042 SAFE_FREE(map);
1044 *p_num_entries = num_entries;
1046 return NT_STATUS_OK;
1049 /*******************************************************************
1050 samr_reply_enum_dom_groups
1051 ********************************************************************/
1053 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1055 DOMAIN_GRP *grp=NULL;
1056 uint32 num_entries;
1057 DOM_SID sid;
1058 uint32 acc_granted;
1060 r_u->status = NT_STATUS_OK;
1062 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1063 return NT_STATUS_INVALID_HANDLE;
1065 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1066 return r_u->status;
1069 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1071 /* the domain group array is being allocated in the function below */
1072 if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
1073 return r_u->status;
1076 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1078 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1080 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1082 return r_u->status;
1086 /*******************************************************************
1087 samr_reply_enum_dom_aliases
1088 ********************************************************************/
1090 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1092 DOMAIN_GRP *grp=NULL;
1093 uint32 num_entries = 0;
1094 fstring sid_str;
1095 DOM_SID sid;
1096 NTSTATUS status;
1097 uint32 acc_granted;
1099 r_u->status = NT_STATUS_OK;
1101 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1102 return NT_STATUS_INVALID_HANDLE;
1104 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1105 return r_u->status;
1108 sid_to_string(sid_str, &sid);
1109 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1111 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1112 &num_entries, MAX_SAM_ENTRIES);
1113 if (NT_STATUS_IS_ERR(status)) return status;
1115 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1117 /*safe_free(grp);*/
1119 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1121 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1123 return r_u->status;
1126 /*******************************************************************
1127 samr_reply_query_dispinfo
1128 ********************************************************************/
1130 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1131 SAMR_R_QUERY_DISPINFO *r_u)
1133 struct samr_info *info = NULL;
1134 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1136 uint32 max_entries=q_u->max_entries;
1137 uint32 enum_context=q_u->start_idx;
1138 uint32 max_size=q_u->max_size;
1140 SAM_DISPINFO_CTR *ctr;
1141 uint32 temp_size=0, total_data_size=0;
1142 NTSTATUS disp_ret;
1143 uint32 num_account = 0;
1144 enum remote_arch_types ra_type = get_remote_arch();
1145 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1146 DOM_SID domain_sid;
1148 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1149 r_u->status = NT_STATUS_OK;
1151 /* find the policy handle. open a policy on it. */
1152 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1153 return NT_STATUS_INVALID_HANDLE;
1155 domain_sid = info->sid;
1158 * calculate how many entries we will return.
1159 * based on
1160 * - the number of entries the client asked
1161 * - our limit on that
1162 * - the starting point (enumeration context)
1163 * - the buffer size the client will accept
1167 * We are a lot more like W2K. Instead of reading the SAM
1168 * each time to find the records we need to send back,
1169 * we read it once and link that copy to the sam handle.
1170 * For large user list (over the MAX_SAM_ENTRIES)
1171 * it's a definitive win.
1172 * second point to notice: between enumerations
1173 * our sam is now the same as it's a snapshoot.
1174 * third point: got rid of the static SAM_USER_21 struct
1175 * no more intermediate.
1176 * con: it uses much more memory, as a full copy is stored
1177 * in memory.
1179 * If you want to change it, think twice and think
1180 * of the second point , that's really important.
1182 * JFM, 12/20/2001
1185 /* Get what we need from the password database */
1186 switch (q_u->switch_level) {
1187 case 0x1:
1188 /* When playing with usrmgr, this is necessary
1189 if you want immediate refresh after editing
1190 a user. I would like to do this after the
1191 setuserinfo2, but we do not have access to
1192 the domain handle in that call, only to the
1193 user handle. Where else does this hurt?
1194 -- Volker
1196 #if 0
1197 /* We cannot do this here - it kills performace. JRA. */
1198 free_samr_users(info);
1199 #endif
1200 case 0x2:
1201 case 0x4:
1202 become_root();
1203 /* Level 2 is for all machines, otherwise only 'normal' users */
1204 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1205 unbecome_root();
1206 if (!NT_STATUS_IS_OK(r_u->status)) {
1207 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1208 return r_u->status;
1210 num_account = info->disp_info.num_user_account;
1211 break;
1212 case 0x3:
1213 case 0x5:
1214 r_u->status = load_group_domain_entries(info, &info->sid);
1215 if (!NT_STATUS_IS_OK(r_u->status))
1216 return r_u->status;
1217 num_account = info->disp_info.num_group_account;
1218 break;
1219 default:
1220 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1221 return NT_STATUS_INVALID_INFO_CLASS;
1224 /* first limit the number of entries we will return */
1225 if(max_entries > max_sam_entries) {
1226 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1227 max_entries = max_sam_entries;
1230 if (enum_context > num_account) {
1231 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1232 return NT_STATUS_NO_MORE_ENTRIES;
1235 /* verify we won't overflow */
1236 if (max_entries > num_account-enum_context) {
1237 max_entries = num_account-enum_context;
1238 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1241 /* calculate the size and limit on the number of entries we will return */
1242 temp_size=max_entries*struct_size;
1244 if (temp_size>max_size) {
1245 max_entries=MIN((max_size/struct_size),max_entries);;
1246 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1249 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1250 return NT_STATUS_NO_MEMORY;
1252 ZERO_STRUCTP(ctr);
1254 /* Now create reply structure */
1255 switch (q_u->switch_level) {
1256 case 0x1:
1257 if (max_entries) {
1258 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1259 return NT_STATUS_NO_MEMORY;
1261 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1262 info->disp_info.disp_user_info, &domain_sid);
1263 if (!NT_STATUS_IS_OK(disp_ret))
1264 return disp_ret;
1265 break;
1266 case 0x2:
1267 if (max_entries) {
1268 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1269 return NT_STATUS_NO_MEMORY;
1271 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1272 info->disp_info.disp_user_info, &domain_sid);
1273 if (!NT_STATUS_IS_OK(disp_ret))
1274 return disp_ret;
1275 break;
1276 case 0x3:
1277 if (max_entries) {
1278 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1279 return NT_STATUS_NO_MEMORY;
1281 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1282 if (!NT_STATUS_IS_OK(disp_ret))
1283 return disp_ret;
1284 break;
1285 case 0x4:
1286 if (max_entries) {
1287 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1288 return NT_STATUS_NO_MEMORY;
1290 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1291 if (!NT_STATUS_IS_OK(disp_ret))
1292 return disp_ret;
1293 break;
1294 case 0x5:
1295 if (max_entries) {
1296 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1297 return NT_STATUS_NO_MEMORY;
1299 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1300 if (!NT_STATUS_IS_OK(disp_ret))
1301 return disp_ret;
1302 break;
1304 default:
1305 ctr->sam.info = NULL;
1306 return NT_STATUS_INVALID_INFO_CLASS;
1309 /* calculate the total size */
1310 total_data_size=num_account*struct_size;
1312 if (enum_context+max_entries < num_account)
1313 r_u->status = STATUS_MORE_ENTRIES;
1315 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1317 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1319 return r_u->status;
1323 /*******************************************************************
1324 samr_reply_query_aliasinfo
1325 ********************************************************************/
1327 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1329 DOM_SID sid;
1330 GROUP_MAP map;
1331 uint32 acc_granted;
1333 r_u->status = NT_STATUS_OK;
1335 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1337 /* find the policy handle. open a policy on it. */
1338 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1339 return NT_STATUS_INVALID_HANDLE;
1340 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1341 return r_u->status;
1344 if (!sid_check_is_in_our_domain(&sid) &&
1345 !sid_check_is_in_builtin(&sid))
1346 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1348 if (!pdb_getgrsid(&map, sid))
1349 return NT_STATUS_NO_SUCH_ALIAS;
1351 switch (q_u->switch_level) {
1352 case 1:
1353 r_u->ptr = 1;
1354 r_u->ctr.switch_value1 = 1;
1355 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1356 break;
1357 case 3:
1358 r_u->ptr = 1;
1359 r_u->ctr.switch_value1 = 3;
1360 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1361 break;
1362 default:
1363 return NT_STATUS_INVALID_INFO_CLASS;
1366 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1368 return r_u->status;
1371 #if 0
1372 /*******************************************************************
1373 samr_reply_lookup_ids
1374 ********************************************************************/
1376 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1378 uint32 rid[MAX_SAM_ENTRIES];
1379 int num_rids = q_u->num_sids1;
1381 r_u->status = NT_STATUS_OK;
1383 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1385 if (num_rids > MAX_SAM_ENTRIES) {
1386 num_rids = MAX_SAM_ENTRIES;
1387 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1390 #if 0
1391 int i;
1392 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1394 for (i = 0; i < num_rids && status == 0; i++)
1396 struct sam_passwd *sam_pass;
1397 fstring user_name;
1400 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1401 q_u->uni_user_name[i].uni_str_len));
1403 /* find the user account */
1404 become_root();
1405 sam_pass = get_smb21pwd_entry(user_name, 0);
1406 unbecome_root();
1408 if (sam_pass == NULL)
1410 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1411 rid[i] = 0;
1413 else
1415 rid[i] = sam_pass->user_rid;
1418 #endif
1420 num_rids = 1;
1421 rid[0] = BUILTIN_ALIAS_RID_USERS;
1423 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1425 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1427 return r_u->status;
1429 #endif
1431 /*******************************************************************
1432 _samr_lookup_names
1433 ********************************************************************/
1435 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1437 uint32 rid[MAX_SAM_ENTRIES];
1438 uint32 local_rid;
1439 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1440 enum SID_NAME_USE local_type;
1441 int i;
1442 int num_rids = q_u->num_names2;
1443 DOM_SID pol_sid;
1444 fstring sid_str;
1445 uint32 acc_granted;
1447 r_u->status = NT_STATUS_OK;
1449 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1451 ZERO_ARRAY(rid);
1452 ZERO_ARRAY(type);
1454 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1455 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1456 return r_u->status;
1459 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1460 return r_u->status;
1463 if (num_rids > MAX_SAM_ENTRIES) {
1464 num_rids = MAX_SAM_ENTRIES;
1465 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1468 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1470 become_root(); /* local_lookup_name can require root privs */
1472 for (i = 0; i < num_rids; i++) {
1473 fstring name;
1474 DOM_SID sid;
1475 int ret;
1477 r_u->status = NT_STATUS_NONE_MAPPED;
1479 rid [i] = 0xffffffff;
1480 type[i] = SID_NAME_UNKNOWN;
1482 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1485 * we are only looking for a name
1486 * the SID we get back can be outside
1487 * the scope of the pol_sid
1489 * in clear: it prevents to reply to domain\group: yes
1490 * when only builtin\group exists.
1492 * a cleaner code is to add the sid of the domain we're looking in
1493 * to the local_lookup_name function.
1496 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1497 sid_split_rid(&sid, &local_rid);
1499 if (sid_equal(&sid, &pol_sid)) {
1500 rid[i]=local_rid;
1501 type[i]=local_type;
1502 r_u->status = NT_STATUS_OK;
1507 unbecome_root();
1509 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1511 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1513 return r_u->status;
1516 /*******************************************************************
1517 _samr_chgpasswd_user
1518 ********************************************************************/
1520 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1522 fstring user_name;
1523 fstring wks;
1525 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1527 r_u->status = NT_STATUS_OK;
1529 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1530 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1532 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1535 * Pass the user through the NT -> unix user mapping
1536 * function.
1539 (void)map_username(user_name);
1542 * UNIX username case mangling not required, pass_oem_change
1543 * is case insensitive.
1546 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1547 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1549 init_samr_r_chgpasswd_user(r_u, r_u->status);
1551 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1553 return r_u->status;
1556 /*******************************************************************
1557 makes a SAMR_R_LOOKUP_RIDS structure.
1558 ********************************************************************/
1560 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1561 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1563 uint32 i;
1564 UNIHDR *hdr_name=NULL;
1565 UNISTR2 *uni_name=NULL;
1567 *pp_uni_name = NULL;
1568 *pp_hdr_name = NULL;
1570 if (num_names != 0) {
1571 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1572 if (hdr_name == NULL)
1573 return False;
1575 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1576 if (uni_name == NULL)
1577 return False;
1580 for (i = 0; i < num_names; i++) {
1581 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1582 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1583 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1586 *pp_uni_name = uni_name;
1587 *pp_hdr_name = hdr_name;
1589 return True;
1592 /*******************************************************************
1593 _samr_lookup_rids
1594 ********************************************************************/
1596 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1598 fstring group_names[MAX_SAM_ENTRIES];
1599 uint32 *group_attrs = NULL;
1600 UNIHDR *hdr_name = NULL;
1601 UNISTR2 *uni_name = NULL;
1602 DOM_SID pol_sid;
1603 int num_rids = q_u->num_rids1;
1604 int i;
1605 uint32 acc_granted;
1607 r_u->status = NT_STATUS_OK;
1609 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1611 /* find the policy handle. open a policy on it. */
1612 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1613 return NT_STATUS_INVALID_HANDLE;
1615 if (num_rids > MAX_SAM_ENTRIES) {
1616 num_rids = MAX_SAM_ENTRIES;
1617 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1620 if (num_rids) {
1621 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1622 return NT_STATUS_NO_MEMORY;
1625 r_u->status = NT_STATUS_NONE_MAPPED;
1627 become_root(); /* lookup_sid can require root privs */
1629 for (i = 0; i < num_rids; i++) {
1630 fstring tmpname;
1631 fstring domname;
1632 DOM_SID sid;
1633 enum SID_NAME_USE type;
1635 group_attrs[i] = SID_NAME_UNKNOWN;
1636 *group_names[i] = '\0';
1638 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1639 sid_copy(&sid, &pol_sid);
1640 sid_append_rid(&sid, q_u->rid[i]);
1642 if (lookup_sid(&sid, domname, tmpname, &type)) {
1643 r_u->status = NT_STATUS_OK;
1644 group_attrs[i] = (uint32)type;
1645 fstrcpy(group_names[i],tmpname);
1646 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1651 unbecome_root();
1653 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1654 return NT_STATUS_NO_MEMORY;
1656 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1658 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1660 return r_u->status;
1663 /*******************************************************************
1664 _samr_open_user. Safe - gives out no passwd info.
1665 ********************************************************************/
1667 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1669 SAM_ACCOUNT *sampass=NULL;
1670 DOM_SID sid;
1671 POLICY_HND domain_pol = q_u->domain_pol;
1672 POLICY_HND *user_pol = &r_u->user_pol;
1673 struct samr_info *info = NULL;
1674 SEC_DESC *psd = NULL;
1675 uint32 acc_granted;
1676 uint32 des_access = q_u->access_mask;
1677 size_t sd_size;
1678 BOOL ret;
1679 NTSTATUS nt_status;
1681 r_u->status = NT_STATUS_OK;
1683 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1684 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1685 return NT_STATUS_INVALID_HANDLE;
1687 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1688 return nt_status;
1691 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1692 if (!NT_STATUS_IS_OK(nt_status)) {
1693 return nt_status;
1696 /* append the user's RID to it */
1697 if (!sid_append_rid(&sid, q_u->user_rid))
1698 return NT_STATUS_NO_SUCH_USER;
1700 /* check if access can be granted as requested by client. */
1701 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1702 se_map_generic(&des_access, &usr_generic_mapping);
1703 if (!NT_STATUS_IS_OK(nt_status =
1704 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1705 des_access, &acc_granted, "_samr_open_user"))) {
1706 return nt_status;
1709 become_root();
1710 ret=pdb_getsampwsid(sampass, &sid);
1711 unbecome_root();
1713 /* check that the SID exists in our domain. */
1714 if (ret == False) {
1715 return NT_STATUS_NO_SUCH_USER;
1718 pdb_free_sam(&sampass);
1720 /* associate the user's SID and access bits with the new handle. */
1721 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1722 return NT_STATUS_NO_MEMORY;
1723 info->acc_granted = acc_granted;
1725 /* get a (unique) handle. open a policy on it. */
1726 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1727 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1729 return r_u->status;
1732 /*************************************************************************
1733 get_user_info_10. Safe. Only gives out acb bits.
1734 *************************************************************************/
1736 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1738 SAM_ACCOUNT *smbpass=NULL;
1739 BOOL ret;
1740 NTSTATUS nt_status;
1742 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1744 if (!NT_STATUS_IS_OK(nt_status)) {
1745 return nt_status;
1748 become_root();
1749 ret = pdb_getsampwsid(smbpass, user_sid);
1750 unbecome_root();
1752 if (ret==False) {
1753 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1754 return NT_STATUS_NO_SUCH_USER;
1757 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1759 ZERO_STRUCTP(id10);
1760 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1762 pdb_free_sam(&smbpass);
1764 return NT_STATUS_OK;
1767 /*************************************************************************
1768 get_user_info_12. OK - this is the killer as it gives out password info.
1769 Ensure that this is only allowed on an encrypted connection with a root
1770 user. JRA.
1771 *************************************************************************/
1773 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1775 SAM_ACCOUNT *smbpass=NULL;
1776 BOOL ret;
1777 NTSTATUS nt_status;
1779 if (!p->ntlmssp_auth_validated)
1780 return NT_STATUS_ACCESS_DENIED;
1782 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1783 return NT_STATUS_ACCESS_DENIED;
1786 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1789 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1791 if (!NT_STATUS_IS_OK(nt_status)) {
1792 return nt_status;
1795 ret = pdb_getsampwsid(smbpass, user_sid);
1797 if (ret == False) {
1798 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1799 pdb_free_sam(&smbpass);
1800 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1803 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1805 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1806 pdb_free_sam(&smbpass);
1807 return NT_STATUS_ACCOUNT_DISABLED;
1810 ZERO_STRUCTP(id12);
1811 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1813 pdb_free_sam(&smbpass);
1815 return NT_STATUS_OK;
1818 /*************************************************************************
1819 get_user_info_20
1820 *************************************************************************/
1822 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1824 SAM_ACCOUNT *sampass=NULL;
1825 BOOL ret;
1827 pdb_init_sam_talloc(mem_ctx, &sampass);
1829 become_root();
1830 ret = pdb_getsampwsid(sampass, user_sid);
1831 unbecome_root();
1833 if (ret == False) {
1834 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1835 return NT_STATUS_NO_SUCH_USER;
1838 samr_clear_sam_passwd(sampass);
1840 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1842 ZERO_STRUCTP(id20);
1843 init_sam_user_info20A(id20, sampass);
1845 pdb_free_sam(&sampass);
1847 return NT_STATUS_OK;
1850 /*************************************************************************
1851 get_user_info_21
1852 *************************************************************************/
1854 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1855 DOM_SID *user_sid, DOM_SID *domain_sid)
1857 SAM_ACCOUNT *sampass=NULL;
1858 BOOL ret;
1859 NTSTATUS nt_status;
1861 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1862 if (!NT_STATUS_IS_OK(nt_status)) {
1863 return nt_status;
1866 become_root();
1867 ret = pdb_getsampwsid(sampass, user_sid);
1868 unbecome_root();
1870 if (ret == False) {
1871 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1872 return NT_STATUS_NO_SUCH_USER;
1875 samr_clear_sam_passwd(sampass);
1877 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1879 ZERO_STRUCTP(id21);
1880 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1882 pdb_free_sam(&sampass);
1884 return NT_STATUS_OK;
1887 /*******************************************************************
1888 _samr_query_userinfo
1889 ********************************************************************/
1891 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1893 SAM_USERINFO_CTR *ctr;
1894 struct samr_info *info = NULL;
1895 DOM_SID domain_sid;
1896 uint32 rid;
1898 r_u->status=NT_STATUS_OK;
1900 /* search for the handle */
1901 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1902 return NT_STATUS_INVALID_HANDLE;
1904 domain_sid = info->sid;
1906 sid_split_rid(&domain_sid, &rid);
1908 if (!sid_check_is_in_our_domain(&info->sid))
1909 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1911 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1913 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1914 if (!ctr)
1915 return NT_STATUS_NO_MEMORY;
1917 ZERO_STRUCTP(ctr);
1919 /* ok! user info levels (lots: see MSDEV help), off we go... */
1920 ctr->switch_value = q_u->switch_value;
1922 switch (q_u->switch_value) {
1923 case 0x10:
1924 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1925 if (ctr->info.id10 == NULL)
1926 return NT_STATUS_NO_MEMORY;
1928 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1929 return r_u->status;
1930 break;
1932 #if 0
1933 /* whoops - got this wrong. i think. or don't understand what's happening. */
1934 case 0x11:
1936 NTTIME expire;
1937 info = (void *)&id11;
1939 expire.low = 0xffffffff;
1940 expire.high = 0x7fffffff;
1942 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1943 sizeof
1944 (*ctr->
1945 info.
1946 id11));
1947 ZERO_STRUCTP(ctr->info.id11);
1948 init_sam_user_info11(ctr->info.id11, &expire,
1949 "BROOKFIELDS$", /* name */
1950 0x03ef, /* user rid */
1951 0x201, /* group rid */
1952 0x0080); /* acb info */
1954 break;
1956 #endif
1958 case 0x12:
1959 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1960 if (ctr->info.id12 == NULL)
1961 return NT_STATUS_NO_MEMORY;
1963 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1964 return r_u->status;
1965 break;
1967 case 20:
1968 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1969 if (ctr->info.id20 == NULL)
1970 return NT_STATUS_NO_MEMORY;
1971 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1972 return r_u->status;
1973 break;
1975 case 21:
1976 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1977 if (ctr->info.id21 == NULL)
1978 return NT_STATUS_NO_MEMORY;
1979 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1980 &info->sid, &domain_sid)))
1981 return r_u->status;
1982 break;
1984 default:
1985 return NT_STATUS_INVALID_INFO_CLASS;
1988 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1990 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1992 return r_u->status;
1995 /*******************************************************************
1996 samr_reply_query_usergroups
1997 ********************************************************************/
1999 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
2001 SAM_ACCOUNT *sam_pass=NULL;
2002 DOM_SID sid;
2003 DOM_GID *gids = NULL;
2004 int num_groups = 0;
2005 uint32 acc_granted;
2006 BOOL ret;
2009 * from the SID in the request:
2010 * we should send back the list of DOMAIN GROUPS
2011 * the user is a member of
2013 * and only the DOMAIN GROUPS
2014 * no ALIASES !!! neither aliases of the domain
2015 * nor aliases of the builtin SID
2017 * JFM, 12/2/2001
2020 r_u->status = NT_STATUS_OK;
2022 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2024 /* find the policy handle. open a policy on it. */
2025 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2026 return NT_STATUS_INVALID_HANDLE;
2028 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2029 return r_u->status;
2032 if (!sid_check_is_in_our_domain(&sid))
2033 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2035 pdb_init_sam(&sam_pass);
2037 become_root();
2038 ret = pdb_getsampwsid(sam_pass, &sid);
2039 unbecome_root();
2041 if (ret == False) {
2042 pdb_free_sam(&sam_pass);
2043 return NT_STATUS_NO_SUCH_USER;
2046 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2047 pdb_free_sam(&sam_pass);
2048 return NT_STATUS_NO_SUCH_GROUP;
2051 /* construct the response. lkclXXXX: gids are not copied! */
2052 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2054 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2056 pdb_free_sam(&sam_pass);
2058 return r_u->status;
2061 /*******************************************************************
2062 _samr_query_dom_info
2063 ********************************************************************/
2065 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2067 struct samr_info *info = NULL;
2068 SAM_UNK_CTR *ctr;
2069 uint32 min_pass_len,pass_hist,flag;
2070 time_t u_expire, u_min_age;
2071 NTTIME nt_expire, nt_min_age;
2073 time_t u_lock_duration, u_reset_time;
2074 NTTIME nt_lock_duration, nt_reset_time;
2075 uint32 lockout;
2077 time_t u_logout;
2078 NTTIME nt_logout;
2080 uint32 account_policy_temp;
2082 uint32 num_users=0, num_groups=0, num_aliases=0;
2084 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2085 return NT_STATUS_NO_MEMORY;
2087 ZERO_STRUCTP(ctr);
2089 r_u->status = NT_STATUS_OK;
2091 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2093 /* find the policy handle. open a policy on it. */
2094 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2095 return NT_STATUS_INVALID_HANDLE;
2097 switch (q_u->switch_value) {
2098 case 0x01:
2100 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2101 min_pass_len = account_policy_temp;
2103 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2104 pass_hist = account_policy_temp;
2106 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2107 flag = account_policy_temp;
2109 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2110 u_expire = account_policy_temp;
2112 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2113 u_min_age = account_policy_temp;
2115 unix_to_nt_time_abs(&nt_expire, u_expire);
2116 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2118 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2119 flag, nt_expire, nt_min_age);
2120 break;
2121 case 0x02:
2122 become_root();
2123 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2124 unbecome_root();
2125 if (!NT_STATUS_IS_OK(r_u->status)) {
2126 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2127 return r_u->status;
2129 num_users=info->disp_info.num_user_account;
2130 free_samr_db(info);
2132 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2133 if (!NT_STATUS_IS_OK(r_u->status)) {
2134 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2135 return r_u->status;
2137 num_groups=info->disp_info.num_group_account;
2138 free_samr_db(info);
2140 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2141 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2142 num_users, num_groups, num_aliases);
2143 break;
2144 case 0x03:
2145 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2146 unix_to_nt_time_abs(&nt_logout, u_logout);
2148 init_unk_info3(&ctr->info.inf3, nt_logout);
2149 break;
2150 case 0x05:
2151 init_unk_info5(&ctr->info.inf5, global_myname());
2152 break;
2153 case 0x06:
2154 init_unk_info6(&ctr->info.inf6);
2155 break;
2156 case 0x07:
2157 init_unk_info7(&ctr->info.inf7);
2158 break;
2159 case 0x0c:
2160 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2161 u_lock_duration = account_policy_temp;
2163 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2164 u_reset_time = account_policy_temp;
2166 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2167 lockout = account_policy_temp;
2169 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2170 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2172 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2173 break;
2174 default:
2175 return NT_STATUS_INVALID_INFO_CLASS;
2178 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2180 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2182 return r_u->status;
2185 /*******************************************************************
2186 _samr_create_user
2187 Create an account, can be either a normal user or a machine.
2188 This funcion will need to be updated for bdc/domain trusts.
2189 ********************************************************************/
2191 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2193 SAM_ACCOUNT *sam_pass=NULL;
2194 fstring account;
2195 DOM_SID sid;
2196 pstring add_script;
2197 POLICY_HND dom_pol = q_u->domain_pol;
2198 UNISTR2 user_account = q_u->uni_name;
2199 uint16 acb_info = q_u->acb_info;
2200 POLICY_HND *user_pol = &r_u->user_pol;
2201 struct samr_info *info = NULL;
2202 BOOL ret;
2203 NTSTATUS nt_status;
2204 struct passwd *pw;
2205 uint32 acc_granted;
2206 SEC_DESC *psd;
2207 size_t sd_size;
2208 uint32 new_rid = 0;
2209 /* check this, when giving away 'add computer to domain' privs */
2210 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2212 /* Get the domain SID stored in the domain policy */
2213 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2214 return NT_STATUS_INVALID_HANDLE;
2216 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2217 return nt_status;
2220 /* find the account: tell the caller if it exists.
2221 lkclXXXX i have *no* idea if this is a problem or not
2222 or even if you are supposed to construct a different
2223 reply if the account already exists...
2226 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2227 strlower_m(account);
2229 pdb_init_sam(&sam_pass);
2231 become_root();
2232 ret = pdb_getsampwnam(sam_pass, account);
2233 unbecome_root();
2234 if (ret == True) {
2235 /* this account exists: say so */
2236 pdb_free_sam(&sam_pass);
2237 return NT_STATUS_USER_EXISTS;
2240 pdb_free_sam(&sam_pass);
2243 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2244 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2245 * that only people with write access to the smbpasswd file will be able
2246 * to create a user. JRA.
2250 * add the user in the /etc/passwd file or the unix authority system.
2251 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2252 * a) local_password_change() checks for us if the /etc/passwd account really exists
2253 * b) smb_create_user() would return an error if the account already exists
2254 * and as it could return an error also if it can't create the account, it would be tricky.
2256 * So we go the easy way, only check after if the account exists.
2257 * JFM (2/3/2001), to clear any possible bad understanding (-:
2259 * We now have seperate script paramaters for adding users/machines so we
2260 * now have some sainity-checking to match.
2263 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2266 * we used to have code here that made sure the acb_info flags
2267 * matched with the users named (e.g. an account flags as a machine
2268 * trust account ended in '$'). It has been ifdef'd out for a long
2269 * time, so I replaced it with this comment. --jerry
2272 /* the passdb lookup has failed; check to see if we need to run the
2273 add user/machine script */
2275 pw = Get_Pwnam(account);
2277 /*********************************************************************
2278 * HEADS UP! If we have to create a new user account, we have to get
2279 * a new RID from somewhere. This used to be done by the passdb
2280 * backend. It has been moved into idmap now. Since idmap is now
2281 * wrapped up behind winbind, this means you have to run winbindd if you
2282 * want new accounts to get a new RID when "enable rid algorithm = no".
2283 * Tough. We now have a uniform way of allocating RIDs regardless
2284 * of what ever passdb backend people may use.
2285 * --jerry (2003-07-10)
2286 *********************************************************************/
2288 if ( !pw ) {
2290 * we can't check both the ending $ and the acb_info.
2292 * UserManager creates trust accounts (ending in $,
2293 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2294 * JFM, 11/29/2001
2296 if (account[strlen(account)-1] == '$')
2297 pstrcpy(add_script, lp_addmachine_script());
2298 else
2299 pstrcpy(add_script, lp_adduser_script());
2301 if (*add_script) {
2302 int add_ret;
2303 all_string_sub(add_script, "%u", account, sizeof(account));
2304 add_ret = smbrun(add_script,NULL);
2305 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2307 else /* no add user script -- ask winbindd to do it */
2309 if ( !winbind_create_user( account, &new_rid ) ) {
2310 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2311 account));
2317 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2319 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2320 return nt_status;
2322 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2324 if (!pdb_add_sam_account(sam_pass)) {
2325 pdb_free_sam(&sam_pass);
2326 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2327 account));
2328 return NT_STATUS_ACCESS_DENIED;
2331 /* Get the user's SID */
2332 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2334 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2335 se_map_generic(&des_access, &usr_generic_mapping);
2336 if (!NT_STATUS_IS_OK(nt_status =
2337 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2338 des_access, &acc_granted, "_samr_create_user"))) {
2339 return nt_status;
2342 /* associate the user's SID with the new handle. */
2343 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2344 pdb_free_sam(&sam_pass);
2345 return NT_STATUS_NO_MEMORY;
2348 ZERO_STRUCTP(info);
2349 info->sid = sid;
2350 info->acc_granted = acc_granted;
2352 /* get a (unique) handle. open a policy on it. */
2353 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2354 pdb_free_sam(&sam_pass);
2355 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2358 r_u->user_rid=pdb_get_user_rid(sam_pass);
2360 r_u->access_granted = acc_granted;
2362 pdb_free_sam(&sam_pass);
2364 return NT_STATUS_OK;
2367 /*******************************************************************
2368 samr_reply_connect_anon
2369 ********************************************************************/
2371 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2373 struct samr_info *info = NULL;
2374 uint32 des_access = q_u->access_mask;
2376 /* Access check */
2378 if (!pipe_access_check(p)) {
2379 DEBUG(3, ("access denied to samr_connect_anon\n"));
2380 r_u->status = NT_STATUS_ACCESS_DENIED;
2381 return r_u->status;
2384 /* set up the SAMR connect_anon response */
2386 r_u->status = NT_STATUS_OK;
2388 /* associate the user's SID with the new handle. */
2389 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2390 return NT_STATUS_NO_MEMORY;
2392 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2393 was observed from a win98 client trying to enumerate users (when configured
2394 user level access control on shares) --jerry */
2396 se_map_generic( &des_access, &sam_generic_mapping );
2397 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2399 info->status = q_u->unknown_0;
2401 /* get a (unique) handle. open a policy on it. */
2402 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2403 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2405 return r_u->status;
2408 /*******************************************************************
2409 samr_reply_connect
2410 ********************************************************************/
2412 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2414 struct samr_info *info = NULL;
2415 SEC_DESC *psd = NULL;
2416 uint32 acc_granted;
2417 uint32 des_access = q_u->access_mask;
2418 size_t sd_size;
2419 NTSTATUS nt_status;
2422 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2424 /* Access check */
2426 if (!pipe_access_check(p)) {
2427 DEBUG(3, ("access denied to samr_connect\n"));
2428 r_u->status = NT_STATUS_ACCESS_DENIED;
2429 return r_u->status;
2432 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2433 se_map_generic(&des_access, &sam_generic_mapping);
2434 if (!NT_STATUS_IS_OK(nt_status =
2435 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2436 des_access, &acc_granted, "_samr_connect"))) {
2437 return nt_status;
2440 r_u->status = NT_STATUS_OK;
2442 /* associate the user's SID and access granted with the new handle. */
2443 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2444 return NT_STATUS_NO_MEMORY;
2446 info->acc_granted = acc_granted;
2447 info->status = q_u->access_mask;
2449 /* get a (unique) handle. open a policy on it. */
2450 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2451 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2453 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2455 return r_u->status;
2458 /*******************************************************************
2459 samr_connect4
2460 ********************************************************************/
2462 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2464 struct samr_info *info = NULL;
2465 SEC_DESC *psd = NULL;
2466 uint32 acc_granted;
2467 uint32 des_access = q_u->access_mask;
2468 size_t sd_size;
2469 NTSTATUS nt_status;
2472 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2474 /* Access check */
2476 if (!pipe_access_check(p)) {
2477 DEBUG(3, ("access denied to samr_connect4\n"));
2478 r_u->status = NT_STATUS_ACCESS_DENIED;
2479 return r_u->status;
2482 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2483 se_map_generic(&des_access, &sam_generic_mapping);
2484 if (!NT_STATUS_IS_OK(nt_status =
2485 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2486 des_access, &acc_granted, "_samr_connect"))) {
2487 return nt_status;
2490 r_u->status = NT_STATUS_OK;
2492 /* associate the user's SID and access granted with the new handle. */
2493 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2494 return NT_STATUS_NO_MEMORY;
2496 info->acc_granted = acc_granted;
2497 info->status = q_u->access_mask;
2499 /* get a (unique) handle. open a policy on it. */
2500 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2501 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2503 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2505 return r_u->status;
2508 /**********************************************************************
2509 api_samr_lookup_domain
2510 **********************************************************************/
2512 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2514 struct samr_info *info;
2515 fstring domain_name;
2516 DOM_SID sid;
2518 r_u->status = NT_STATUS_OK;
2520 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2521 return NT_STATUS_INVALID_HANDLE;
2523 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2524 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2526 return r_u->status;
2529 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2531 ZERO_STRUCT(sid);
2533 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2534 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2537 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2539 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2541 return r_u->status;
2544 /******************************************************************
2545 makes a SAMR_R_ENUM_DOMAINS structure.
2546 ********************************************************************/
2548 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2549 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2551 uint32 i;
2552 SAM_ENTRY *sam;
2553 UNISTR2 *uni_name;
2555 DEBUG(5, ("make_enum_domains\n"));
2557 *pp_sam = NULL;
2558 *pp_uni_name = NULL;
2560 if (num_sam_entries == 0)
2561 return True;
2563 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2564 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2566 if (sam == NULL || uni_name == NULL)
2567 return False;
2569 for (i = 0; i < num_sam_entries; i++) {
2570 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2571 init_sam_entry(&sam[i], &uni_name[i], 0);
2574 *pp_sam = sam;
2575 *pp_uni_name = uni_name;
2577 return True;
2580 /**********************************************************************
2581 api_samr_enum_domains
2582 **********************************************************************/
2584 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2586 struct samr_info *info;
2587 uint32 num_entries = 2;
2588 fstring dom[2];
2589 const char *name;
2591 r_u->status = NT_STATUS_OK;
2593 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2594 return NT_STATUS_INVALID_HANDLE;
2596 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2597 return r_u->status;
2600 name = get_global_sam_name();
2602 fstrcpy(dom[0],name);
2603 strupper_m(dom[0]);
2604 fstrcpy(dom[1],"Builtin");
2606 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2607 return NT_STATUS_NO_MEMORY;
2609 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2611 return r_u->status;
2614 /*******************************************************************
2615 api_samr_open_alias
2616 ********************************************************************/
2618 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2620 DOM_SID sid;
2621 POLICY_HND domain_pol = q_u->dom_pol;
2622 uint32 alias_rid = q_u->rid_alias;
2623 POLICY_HND *alias_pol = &r_u->pol;
2624 struct samr_info *info = NULL;
2625 SEC_DESC *psd = NULL;
2626 uint32 acc_granted;
2627 uint32 des_access = q_u->access_mask;
2628 size_t sd_size;
2629 NTSTATUS status;
2631 r_u->status = NT_STATUS_OK;
2633 /* find the domain policy and get the SID / access bits stored in the domain policy */
2634 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2635 return NT_STATUS_INVALID_HANDLE;
2637 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2638 return status;
2641 /* append the alias' RID to it */
2642 if (!sid_append_rid(&sid, alias_rid))
2643 return NT_STATUS_NO_SUCH_USER;
2645 /*check if access can be granted as requested by client. */
2646 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2647 se_map_generic(&des_access,&ali_generic_mapping);
2648 if (!NT_STATUS_IS_OK(status =
2649 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2650 des_access, &acc_granted, "_samr_open_alias"))) {
2651 return status;
2655 * we should check if the rid really exist !!!
2656 * JFM.
2659 /* associate the user's SID with the new handle. */
2660 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2661 return NT_STATUS_NO_MEMORY;
2663 info->acc_granted = acc_granted;
2665 /* get a (unique) handle. open a policy on it. */
2666 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2667 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2669 return r_u->status;
2672 /*******************************************************************
2673 set_user_info_10
2674 ********************************************************************/
2676 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2678 SAM_ACCOUNT *pwd =NULL;
2679 BOOL ret;
2681 pdb_init_sam(&pwd);
2683 ret = pdb_getsampwsid(pwd, sid);
2685 if(ret==False) {
2686 pdb_free_sam(&pwd);
2687 return False;
2690 if (id10 == NULL) {
2691 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2692 pdb_free_sam(&pwd);
2693 return False;
2696 /* FIX ME: check if the value is really changed --metze */
2697 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2698 pdb_free_sam(&pwd);
2699 return False;
2702 if(!pdb_update_sam_account(pwd)) {
2703 pdb_free_sam(&pwd);
2704 return False;
2707 pdb_free_sam(&pwd);
2709 return True;
2712 /*******************************************************************
2713 set_user_info_12
2714 ********************************************************************/
2716 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2718 SAM_ACCOUNT *pwd = NULL;
2720 pdb_init_sam(&pwd);
2722 if(!pdb_getsampwsid(pwd, sid)) {
2723 pdb_free_sam(&pwd);
2724 return False;
2727 if (id12 == NULL) {
2728 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2729 pdb_free_sam(&pwd);
2730 return False;
2733 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2734 pdb_free_sam(&pwd);
2735 return False;
2737 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2738 pdb_free_sam(&pwd);
2739 return False;
2741 if (!pdb_set_pass_changed_now (pwd)) {
2742 pdb_free_sam(&pwd);
2743 return False;
2746 if(!pdb_update_sam_account(pwd)) {
2747 pdb_free_sam(&pwd);
2748 return False;
2751 pdb_free_sam(&pwd);
2752 return True;
2755 /*******************************************************************
2756 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2757 ********************************************************************/
2758 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2760 struct group *grp;
2761 gid_t gid;
2763 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2764 &gid))) {
2765 DEBUG(2,("Could not get gid for primary group of "
2766 "user %s\n", pdb_get_username(sampass)));
2767 return False;
2770 grp = getgrgid(gid);
2772 if (grp == NULL) {
2773 DEBUG(2,("Could not find primary group %lu for "
2774 "user %s\n", (unsigned long)gid,
2775 pdb_get_username(sampass)));
2776 return False;
2779 if (smb_set_primary_group(grp->gr_name,
2780 pdb_get_username(sampass)) != 0) {
2781 DEBUG(2,("Could not set primary group for user %s to "
2782 "%s\n",
2783 pdb_get_username(sampass), grp->gr_name));
2784 return False;
2787 return True;
2791 /*******************************************************************
2792 set_user_info_20
2793 ********************************************************************/
2795 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2797 SAM_ACCOUNT *pwd = NULL;
2799 if (id20 == NULL) {
2800 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2801 return False;
2804 pdb_init_sam(&pwd);
2806 if (!pdb_getsampwsid(pwd, sid)) {
2807 pdb_free_sam(&pwd);
2808 return False;
2811 copy_id20_to_sam_passwd(pwd, id20);
2813 /* write the change out */
2814 if(!pdb_update_sam_account(pwd)) {
2815 pdb_free_sam(&pwd);
2816 return False;
2819 pdb_free_sam(&pwd);
2821 return True;
2823 /*******************************************************************
2824 set_user_info_21
2825 ********************************************************************/
2827 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2829 SAM_ACCOUNT *pwd = NULL;
2831 if (id21 == NULL) {
2832 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2833 return False;
2836 pdb_init_sam(&pwd);
2838 if (!pdb_getsampwsid(pwd, sid)) {
2839 pdb_free_sam(&pwd);
2840 return False;
2843 copy_id21_to_sam_passwd(pwd, id21);
2846 * The funny part about the previous two calls is
2847 * that pwd still has the password hashes from the
2848 * passdb entry. These have not been updated from
2849 * id21. I don't know if they need to be set. --jerry
2852 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2853 set_unix_primary_group(pwd);
2855 /* write the change out */
2856 if(!pdb_update_sam_account(pwd)) {
2857 pdb_free_sam(&pwd);
2858 return False;
2861 pdb_free_sam(&pwd);
2863 return True;
2866 /*******************************************************************
2867 set_user_info_23
2868 ********************************************************************/
2870 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2872 SAM_ACCOUNT *pwd = NULL;
2873 pstring plaintext_buf;
2874 uint32 len;
2875 uint16 acct_ctrl;
2877 if (id23 == NULL) {
2878 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2879 return False;
2882 pdb_init_sam(&pwd);
2884 if (!pdb_getsampwsid(pwd, sid)) {
2885 pdb_free_sam(&pwd);
2886 return False;
2889 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2890 pdb_get_username(pwd)));
2892 acct_ctrl = pdb_get_acct_ctrl(pwd);
2894 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2895 pdb_free_sam(&pwd);
2896 return False;
2899 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2900 pdb_free_sam(&pwd);
2901 return False;
2904 copy_id23_to_sam_passwd(pwd, id23);
2906 /* if it's a trust account, don't update /etc/passwd */
2907 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2908 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2909 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2910 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2911 } else {
2912 /* update the UNIX password */
2913 if (lp_unix_password_sync() )
2914 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2915 pdb_free_sam(&pwd);
2916 return False;
2920 ZERO_STRUCT(plaintext_buf);
2922 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2923 set_unix_primary_group(pwd);
2925 if(!pdb_update_sam_account(pwd)) {
2926 pdb_free_sam(&pwd);
2927 return False;
2930 pdb_free_sam(&pwd);
2932 return True;
2935 /*******************************************************************
2936 set_user_info_pw
2937 ********************************************************************/
2939 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2941 SAM_ACCOUNT *pwd = NULL;
2942 uint32 len;
2943 pstring plaintext_buf;
2944 uint16 acct_ctrl;
2946 pdb_init_sam(&pwd);
2948 if (!pdb_getsampwsid(pwd, sid)) {
2949 pdb_free_sam(&pwd);
2950 return False;
2953 DEBUG(5, ("Attempting administrator password change for user %s\n",
2954 pdb_get_username(pwd)));
2956 acct_ctrl = pdb_get_acct_ctrl(pwd);
2958 ZERO_STRUCT(plaintext_buf);
2960 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2961 pdb_free_sam(&pwd);
2962 return False;
2965 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2966 pdb_free_sam(&pwd);
2967 return False;
2970 /* if it's a trust account, don't update /etc/passwd */
2971 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2972 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2973 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2974 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2975 } else {
2976 /* update the UNIX password */
2977 if (lp_unix_password_sync()) {
2978 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2979 pdb_free_sam(&pwd);
2980 return False;
2985 ZERO_STRUCT(plaintext_buf);
2987 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2989 /* update the SAMBA password */
2990 if(!pdb_update_sam_account(pwd)) {
2991 pdb_free_sam(&pwd);
2992 return False;
2995 pdb_free_sam(&pwd);
2997 return True;
3000 /*******************************************************************
3001 samr_reply_set_userinfo
3002 ********************************************************************/
3004 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3006 DOM_SID sid;
3007 POLICY_HND *pol = &q_u->pol;
3008 uint16 switch_value = q_u->switch_value;
3009 SAM_USERINFO_CTR *ctr = q_u->ctr;
3010 uint32 acc_granted;
3011 uint32 acc_required;
3013 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3015 r_u->status = NT_STATUS_OK;
3017 /* find the policy handle. open a policy on it. */
3018 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3019 return NT_STATUS_INVALID_HANDLE;
3021 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3022 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3023 return r_u->status;
3026 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3028 if (ctr == NULL) {
3029 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3030 return NT_STATUS_INVALID_INFO_CLASS;
3033 /* ok! user info levels (lots: see MSDEV help), off we go... */
3034 switch (switch_value) {
3035 case 0x12:
3036 if (!set_user_info_12(ctr->info.id12, &sid))
3037 return NT_STATUS_ACCESS_DENIED;
3038 break;
3040 case 24:
3041 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
3043 dump_data(100, (char *)ctr->info.id24->pass, 516);
3045 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3046 return NT_STATUS_ACCESS_DENIED;
3047 break;
3049 case 25:
3050 #if 0
3052 * Currently we don't really know how to unmarshall
3053 * the level 25 struct, and the password encryption
3054 * is different. This is a placeholder for when we
3055 * do understand it. In the meantime just return INVALID
3056 * info level and W2K SP2 drops down to level 23... JRA.
3059 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3061 dump_data(100, (char *)ctr->info.id25->pass, 532);
3063 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3064 return NT_STATUS_ACCESS_DENIED;
3065 break;
3066 #endif
3067 return NT_STATUS_INVALID_INFO_CLASS;
3069 case 23:
3070 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3072 dump_data(100, (char *)ctr->info.id23->pass, 516);
3074 if (!set_user_info_23(ctr->info.id23, &sid))
3075 return NT_STATUS_ACCESS_DENIED;
3076 break;
3078 default:
3079 return NT_STATUS_INVALID_INFO_CLASS;
3082 return r_u->status;
3085 /*******************************************************************
3086 samr_reply_set_userinfo2
3087 ********************************************************************/
3089 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3091 DOM_SID sid;
3092 SAM_USERINFO_CTR *ctr = q_u->ctr;
3093 POLICY_HND *pol = &q_u->pol;
3094 uint16 switch_value = q_u->switch_value;
3095 uint32 acc_granted;
3096 uint32 acc_required;
3098 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3100 r_u->status = NT_STATUS_OK;
3102 /* find the policy handle. open a policy on it. */
3103 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3104 return NT_STATUS_INVALID_HANDLE;
3106 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3107 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3108 return r_u->status;
3111 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3113 if (ctr == NULL) {
3114 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3115 return NT_STATUS_INVALID_INFO_CLASS;
3118 switch_value=ctr->switch_value;
3120 /* ok! user info levels (lots: see MSDEV help), off we go... */
3121 switch (switch_value) {
3122 case 21:
3123 if (!set_user_info_21(ctr->info.id21, &sid))
3124 return NT_STATUS_ACCESS_DENIED;
3125 break;
3126 case 20:
3127 if (!set_user_info_20(ctr->info.id20, &sid))
3128 return NT_STATUS_ACCESS_DENIED;
3129 break;
3130 case 16:
3131 if (!set_user_info_10(ctr->info.id10, &sid))
3132 return NT_STATUS_ACCESS_DENIED;
3133 break;
3134 case 18:
3135 /* Used by AS/U JRA. */
3136 if (!set_user_info_12(ctr->info.id12, &sid))
3137 return NT_STATUS_ACCESS_DENIED;
3138 break;
3139 default:
3140 return NT_STATUS_INVALID_INFO_CLASS;
3143 return r_u->status;
3146 /*********************************************************************
3147 _samr_query_aliasmem
3148 *********************************************************************/
3150 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3152 int num_groups = 0, tmp_num_groups=0;
3153 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3154 struct samr_info *info = NULL;
3155 int i,j;
3157 NTSTATUS ntstatus1;
3158 NTSTATUS ntstatus2;
3160 /* until i see a real useraliases query, we fack one up */
3162 /* I have seen one, JFM 2/12/2001 */
3164 * Explanation of what this call does:
3165 * for all the SID given in the request:
3166 * return a list of alias (local groups)
3167 * that have those SID as members.
3169 * and that's the alias in the domain specified
3170 * in the policy_handle
3172 * if the policy handle is on an incorrect sid
3173 * for example a user's sid
3174 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3177 r_u->status = NT_STATUS_OK;
3179 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3181 /* find the policy handle. open a policy on it. */
3182 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3183 return NT_STATUS_INVALID_HANDLE;
3185 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3186 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3188 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3189 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3190 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3191 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3195 if (!sid_check_is_domain(&info->sid) &&
3196 !sid_check_is_builtin(&info->sid))
3197 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3200 for (i=0; i<q_u->num_sids1; i++) {
3202 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3205 * if there is an error, we just continue as
3206 * it can be an unfound user or group
3208 if (!NT_STATUS_IS_OK(r_u->status)) {
3209 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3210 continue;
3213 if (tmp_num_groups==0) {
3214 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3215 continue;
3218 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3219 if (new_rids==NULL) {
3220 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3221 return NT_STATUS_NO_MEMORY;
3223 rids=new_rids;
3225 for (j=0; j<tmp_num_groups; j++)
3226 rids[j+num_groups]=tmp_rids[j];
3228 safe_free(tmp_rids);
3230 num_groups+=tmp_num_groups;
3233 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3234 return NT_STATUS_OK;
3237 /*********************************************************************
3238 _samr_query_aliasmem
3239 *********************************************************************/
3241 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3243 int i;
3245 GROUP_MAP map;
3246 int num_uids = 0;
3247 DOM_SID2 *sid;
3248 uid_t *uid=NULL;
3250 DOM_SID alias_sid;
3251 DOM_SID als_sid;
3252 uint32 alias_rid;
3253 fstring alias_sid_str;
3254 DOM_SID temp_sid;
3256 SAM_ACCOUNT *sam_user = NULL;
3257 BOOL check;
3258 uint32 acc_granted;
3260 /* find the policy handle. open a policy on it. */
3261 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3262 return NT_STATUS_INVALID_HANDLE;
3264 if (!NT_STATUS_IS_OK(r_u->status =
3265 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3266 return r_u->status;
3269 sid_copy(&als_sid, &alias_sid);
3270 sid_to_string(alias_sid_str, &alias_sid);
3271 sid_split_rid(&alias_sid, &alias_rid);
3273 DEBUG(10, ("sid is %s\n", alias_sid_str));
3275 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3276 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3277 if(!get_builtin_group_from_sid(als_sid, &map))
3278 return NT_STATUS_NO_SUCH_ALIAS;
3279 } else {
3280 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3281 DEBUG(10, ("lookup on Server SID\n"));
3282 if(!get_local_group_from_sid(als_sid, &map))
3283 return NT_STATUS_NO_SUCH_ALIAS;
3287 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3288 return NT_STATUS_NO_SUCH_ALIAS;
3290 DEBUG(10, ("sid is %s\n", alias_sid_str));
3291 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3292 if (num_uids!=0 && sid == NULL)
3293 return NT_STATUS_NO_MEMORY;
3295 for (i = 0; i < num_uids; i++) {
3296 struct passwd *pass;
3297 uint32 rid;
3299 sid_copy(&temp_sid, get_global_sam_sid());
3301 pass = getpwuid_alloc(uid[i]);
3302 if (!pass) continue;
3304 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3305 passwd_free(&pass);
3306 continue;
3309 become_root();
3310 check = pdb_getsampwnam(sam_user, pass->pw_name);
3311 unbecome_root();
3313 if (check != True) {
3314 pdb_free_sam(&sam_user);
3315 passwd_free(&pass);
3316 continue;
3319 rid = pdb_get_user_rid(sam_user);
3320 if (rid == 0) {
3321 pdb_free_sam(&sam_user);
3322 passwd_free(&pass);
3323 continue;
3326 pdb_free_sam(&sam_user);
3327 passwd_free(&pass);
3329 sid_append_rid(&temp_sid, rid);
3331 init_dom_sid2(&sid[i], &temp_sid);
3334 DEBUG(10, ("sid is %s\n", alias_sid_str));
3335 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3337 return NT_STATUS_OK;
3340 /*********************************************************************
3341 _samr_query_groupmem
3342 *********************************************************************/
3344 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3346 int num_uids = 0;
3347 int i;
3348 DOM_SID group_sid;
3349 uint32 group_rid;
3350 fstring group_sid_str;
3351 uid_t *uid=NULL;
3353 GROUP_MAP map;
3355 uint32 *rid=NULL;
3356 uint32 *attr=NULL;
3358 SAM_ACCOUNT *sam_user = NULL;
3359 BOOL check;
3360 uint32 acc_granted;
3362 /* find the policy handle. open a policy on it. */
3363 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3364 return NT_STATUS_INVALID_HANDLE;
3366 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3367 return r_u->status;
3370 /* todo: change to use sid_compare_front */
3372 sid_split_rid(&group_sid, &group_rid);
3373 sid_to_string(group_sid_str, &group_sid);
3374 DEBUG(10, ("sid is %s\n", group_sid_str));
3376 /* can we get a query for an SID outside our domain ? */
3377 if (!sid_equal(&group_sid, get_global_sam_sid()))
3378 return NT_STATUS_NO_SUCH_GROUP;
3380 sid_append_rid(&group_sid, group_rid);
3381 DEBUG(10, ("lookup on Domain SID\n"));
3383 if(!get_domain_group_from_sid(group_sid, &map))
3384 return NT_STATUS_NO_SUCH_GROUP;
3386 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3387 return NT_STATUS_NO_SUCH_GROUP;
3389 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3390 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3392 if (num_uids!=0 && (rid==NULL || attr==NULL))
3393 return NT_STATUS_NO_MEMORY;
3395 for (i=0; i<num_uids; i++) {
3396 struct passwd *pass;
3397 uint32 urid;
3399 pass = getpwuid_alloc(uid[i]);
3400 if (!pass) continue;
3402 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3403 passwd_free(&pass);
3404 continue;
3407 become_root();
3408 check = pdb_getsampwnam(sam_user, pass->pw_name);
3409 unbecome_root();
3411 if (check != True) {
3412 pdb_free_sam(&sam_user);
3413 passwd_free(&pass);
3414 continue;
3417 urid = pdb_get_user_rid(sam_user);
3418 if (urid == 0) {
3419 pdb_free_sam(&sam_user);
3420 passwd_free(&pass);
3421 continue;
3424 pdb_free_sam(&sam_user);
3425 passwd_free(&pass);
3427 rid[i] = urid;
3428 attr[i] = SID_NAME_USER;
3431 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3433 return NT_STATUS_OK;
3436 /*********************************************************************
3437 _samr_add_aliasmem
3438 *********************************************************************/
3440 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3442 DOM_SID alias_sid;
3443 fstring alias_sid_str;
3444 uid_t uid;
3445 struct passwd *pwd;
3446 struct group *grp;
3447 fstring grp_name;
3448 GROUP_MAP map;
3449 NTSTATUS ret;
3450 SAM_ACCOUNT *sam_user = NULL;
3451 BOOL check;
3452 uint32 acc_granted;
3454 /* Find the policy handle. Open a policy on it. */
3455 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3456 return NT_STATUS_INVALID_HANDLE;
3458 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3459 return r_u->status;
3462 sid_to_string(alias_sid_str, &alias_sid);
3463 DEBUG(10, ("sid is %s\n", alias_sid_str));
3465 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3466 DEBUG(10, ("adding member on Server SID\n"));
3467 if(!get_local_group_from_sid(alias_sid, &map))
3468 return NT_STATUS_NO_SUCH_ALIAS;
3470 } else {
3471 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3472 DEBUG(10, ("adding member on BUILTIN SID\n"));
3473 if( !get_local_group_from_sid(alias_sid, &map))
3474 return NT_STATUS_NO_SUCH_ALIAS;
3476 } else
3477 return NT_STATUS_NO_SUCH_ALIAS;
3480 ret = pdb_init_sam(&sam_user);
3481 if (!NT_STATUS_IS_OK(ret))
3482 return ret;
3484 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3486 if (check != True) {
3487 pdb_free_sam(&sam_user);
3488 return NT_STATUS_NO_SUCH_USER;
3491 /* check a real user exist before we run the script to add a user to a group */
3492 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3493 pdb_free_sam(&sam_user);
3494 return NT_STATUS_NO_SUCH_USER;
3497 pdb_free_sam(&sam_user);
3499 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3500 return NT_STATUS_NO_SUCH_USER;
3503 if ((grp=getgrgid(map.gid)) == NULL) {
3504 passwd_free(&pwd);
3505 return NT_STATUS_NO_SUCH_ALIAS;
3508 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3509 fstrcpy(grp_name, grp->gr_name);
3511 /* if the user is already in the group */
3512 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3513 passwd_free(&pwd);
3514 return NT_STATUS_MEMBER_IN_ALIAS;
3518 * ok, the group exist, the user exist, the user is not in the group,
3519 * we can (finally) add it to the group !
3521 smb_add_user_group(grp_name, pwd->pw_name);
3523 /* check if the user has been added then ... */
3524 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3525 passwd_free(&pwd);
3526 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3529 passwd_free(&pwd);
3530 return NT_STATUS_OK;
3533 /*********************************************************************
3534 _samr_del_aliasmem
3535 *********************************************************************/
3537 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3539 DOM_SID alias_sid;
3540 fstring alias_sid_str;
3541 struct group *grp;
3542 fstring grp_name;
3543 GROUP_MAP map;
3544 SAM_ACCOUNT *sam_pass=NULL;
3545 uint32 acc_granted;
3547 /* Find the policy handle. Open a policy on it. */
3548 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3549 return NT_STATUS_INVALID_HANDLE;
3551 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3552 return r_u->status;
3555 sid_to_string(alias_sid_str, &alias_sid);
3556 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3558 if (!sid_check_is_in_our_domain(&alias_sid) &&
3559 !sid_check_is_in_builtin(&alias_sid)) {
3560 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3561 return NT_STATUS_NO_SUCH_ALIAS;
3564 if( !get_local_group_from_sid(alias_sid, &map))
3565 return NT_STATUS_NO_SUCH_ALIAS;
3567 if ((grp=getgrgid(map.gid)) == NULL)
3568 return NT_STATUS_NO_SUCH_ALIAS;
3570 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3571 fstrcpy(grp_name, grp->gr_name);
3573 /* check if the user exists before trying to remove it from the group */
3574 pdb_init_sam(&sam_pass);
3575 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3576 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3577 pdb_free_sam(&sam_pass);
3578 return NT_STATUS_NO_SUCH_USER;
3581 /* if the user is not in the group */
3582 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3583 pdb_free_sam(&sam_pass);
3584 return NT_STATUS_MEMBER_IN_ALIAS;
3587 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3589 /* check if the user has been removed then ... */
3590 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3591 pdb_free_sam(&sam_pass);
3592 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3595 pdb_free_sam(&sam_pass);
3596 return NT_STATUS_OK;
3599 /*********************************************************************
3600 _samr_add_groupmem
3601 *********************************************************************/
3603 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3605 DOM_SID group_sid;
3606 DOM_SID user_sid;
3607 fstring group_sid_str;
3608 uid_t uid;
3609 struct passwd *pwd;
3610 struct group *grp;
3611 fstring grp_name;
3612 GROUP_MAP map;
3613 NTSTATUS ret;
3614 SAM_ACCOUNT *sam_user=NULL;
3615 BOOL check;
3616 uint32 acc_granted;
3618 /* Find the policy handle. Open a policy on it. */
3619 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3620 return NT_STATUS_INVALID_HANDLE;
3622 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3623 return r_u->status;
3626 sid_to_string(group_sid_str, &group_sid);
3627 DEBUG(10, ("sid is %s\n", group_sid_str));
3629 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3630 return NT_STATUS_NO_SUCH_GROUP;
3632 DEBUG(10, ("lookup on Domain SID\n"));
3634 if(!get_domain_group_from_sid(group_sid, &map))
3635 return NT_STATUS_NO_SUCH_GROUP;
3637 sid_copy(&user_sid, get_global_sam_sid());
3638 sid_append_rid(&user_sid, q_u->rid);
3640 ret = pdb_init_sam(&sam_user);
3641 if (!NT_STATUS_IS_OK(ret))
3642 return ret;
3644 check = pdb_getsampwsid(sam_user, &user_sid);
3646 if (check != True) {
3647 pdb_free_sam(&sam_user);
3648 return NT_STATUS_NO_SUCH_USER;
3651 /* check a real user exist before we run the script to add a user to a group */
3652 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3653 pdb_free_sam(&sam_user);
3654 return NT_STATUS_NO_SUCH_USER;
3657 pdb_free_sam(&sam_user);
3659 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3660 return NT_STATUS_NO_SUCH_USER;
3663 if ((grp=getgrgid(map.gid)) == NULL) {
3664 passwd_free(&pwd);
3665 return NT_STATUS_NO_SUCH_GROUP;
3668 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3669 fstrcpy(grp_name, grp->gr_name);
3671 /* if the user is already in the group */
3672 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3673 passwd_free(&pwd);
3674 return NT_STATUS_MEMBER_IN_GROUP;
3678 * ok, the group exist, the user exist, the user is not in the group,
3680 * we can (finally) add it to the group !
3683 smb_add_user_group(grp_name, pwd->pw_name);
3685 /* check if the user has been added then ... */
3686 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3687 passwd_free(&pwd);
3688 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3691 passwd_free(&pwd);
3692 return NT_STATUS_OK;
3695 /*********************************************************************
3696 _samr_del_groupmem
3697 *********************************************************************/
3699 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3701 DOM_SID group_sid;
3702 DOM_SID user_sid;
3703 SAM_ACCOUNT *sam_pass=NULL;
3704 GROUP_MAP map;
3705 fstring grp_name;
3706 struct group *grp;
3707 uint32 acc_granted;
3710 * delete the group member named q_u->rid
3711 * who is a member of the sid associated with the handle
3712 * the rid is a user's rid as the group is a domain group.
3715 /* Find the policy handle. Open a policy on it. */
3716 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3717 return NT_STATUS_INVALID_HANDLE;
3719 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3720 return r_u->status;
3723 if (!sid_check_is_in_our_domain(&group_sid))
3724 return NT_STATUS_NO_SUCH_GROUP;
3726 sid_copy(&user_sid, get_global_sam_sid());
3727 sid_append_rid(&user_sid, q_u->rid);
3729 if (!get_domain_group_from_sid(group_sid, &map))
3730 return NT_STATUS_NO_SUCH_GROUP;
3732 if ((grp=getgrgid(map.gid)) == NULL)
3733 return NT_STATUS_NO_SUCH_GROUP;
3735 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3736 fstrcpy(grp_name, grp->gr_name);
3738 /* check if the user exists before trying to remove it from the group */
3739 pdb_init_sam(&sam_pass);
3740 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3741 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3742 pdb_free_sam(&sam_pass);
3743 return NT_STATUS_NO_SUCH_USER;
3746 /* if the user is not in the group */
3747 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3748 pdb_free_sam(&sam_pass);
3749 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3752 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3754 /* check if the user has been removed then ... */
3755 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3756 pdb_free_sam(&sam_pass);
3757 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3760 pdb_free_sam(&sam_pass);
3761 return NT_STATUS_OK;
3765 /****************************************************************************
3766 Delete a UNIX user on demand.
3767 ****************************************************************************/
3769 static int smb_delete_user(const char *unix_user)
3771 pstring del_script;
3772 int ret;
3774 /* try winbindd first since it is impossible to determine where
3775 a user came from via NSS. Try the delete user script if this fails
3776 meaning the user did not exist in winbindd's list of accounts */
3778 if ( winbind_delete_user( unix_user ) ) {
3779 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3780 return 0;
3784 /* fall back to 'delete user script' */
3786 pstrcpy(del_script, lp_deluser_script());
3787 if (! *del_script)
3788 return -1;
3789 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3790 ret = smbrun(del_script,NULL);
3791 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3793 return ret;
3796 /*********************************************************************
3797 _samr_delete_dom_user
3798 *********************************************************************/
3800 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3802 DOM_SID user_sid;
3803 SAM_ACCOUNT *sam_pass=NULL;
3804 uint32 acc_granted;
3806 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3808 /* Find the policy handle. Open a policy on it. */
3809 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3810 return NT_STATUS_INVALID_HANDLE;
3812 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3813 return r_u->status;
3816 if (!sid_check_is_in_our_domain(&user_sid))
3817 return NT_STATUS_CANNOT_DELETE;
3819 /* check if the user exists before trying to delete */
3820 pdb_init_sam(&sam_pass);
3821 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3822 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3823 sid_string_static(&user_sid)));
3824 pdb_free_sam(&sam_pass);
3825 return NT_STATUS_NO_SUCH_USER;
3828 /* delete the unix side */
3830 * note: we don't check if the delete really happened
3831 * as the script is not necessary present
3832 * and maybe the sysadmin doesn't want to delete the unix side
3834 smb_delete_user(pdb_get_username(sam_pass));
3836 /* and delete the samba side */
3837 if (!pdb_delete_sam_account(sam_pass)) {
3838 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3839 pdb_free_sam(&sam_pass);
3840 return NT_STATUS_CANNOT_DELETE;
3843 pdb_free_sam(&sam_pass);
3845 if (!close_policy_hnd(p, &q_u->user_pol))
3846 return NT_STATUS_OBJECT_NAME_INVALID;
3848 return NT_STATUS_OK;
3851 /*********************************************************************
3852 _samr_delete_dom_group
3853 *********************************************************************/
3855 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3857 DOM_SID group_sid;
3858 DOM_SID dom_sid;
3859 uint32 group_rid;
3860 fstring group_sid_str;
3861 gid_t gid;
3862 struct group *grp;
3863 GROUP_MAP map;
3864 uint32 acc_granted;
3866 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3868 /* Find the policy handle. Open a policy on it. */
3869 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3870 return NT_STATUS_INVALID_HANDLE;
3872 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3873 return r_u->status;
3876 sid_copy(&dom_sid, &group_sid);
3877 sid_to_string(group_sid_str, &dom_sid);
3878 sid_split_rid(&dom_sid, &group_rid);
3880 DEBUG(10, ("sid is %s\n", group_sid_str));
3882 /* we check if it's our SID before deleting */
3883 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3884 return NT_STATUS_NO_SUCH_GROUP;
3886 DEBUG(10, ("lookup on Domain SID\n"));
3888 if(!get_domain_group_from_sid(group_sid, &map))
3889 return NT_STATUS_NO_SUCH_GROUP;
3891 gid=map.gid;
3893 /* check if group really exists */
3894 if ( (grp=getgrgid(gid)) == NULL)
3895 return NT_STATUS_NO_SUCH_GROUP;
3897 /* we can delete the UNIX group */
3898 smb_delete_group(grp->gr_name);
3900 /* check if the group has been successfully deleted */
3901 if ( (grp=getgrgid(gid)) != NULL)
3902 return NT_STATUS_ACCESS_DENIED;
3904 if(!pdb_delete_group_mapping_entry(group_sid))
3905 return NT_STATUS_ACCESS_DENIED;
3907 if (!close_policy_hnd(p, &q_u->group_pol))
3908 return NT_STATUS_OBJECT_NAME_INVALID;
3910 return NT_STATUS_OK;
3913 /*********************************************************************
3914 _samr_delete_dom_alias
3915 *********************************************************************/
3917 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3919 DOM_SID alias_sid;
3920 DOM_SID dom_sid;
3921 uint32 alias_rid;
3922 fstring alias_sid_str;
3923 gid_t gid;
3924 struct group *grp;
3925 GROUP_MAP map;
3926 uint32 acc_granted;
3928 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3930 /* Find the policy handle. Open a policy on it. */
3931 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3932 return NT_STATUS_INVALID_HANDLE;
3934 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3935 return r_u->status;
3938 sid_copy(&dom_sid, &alias_sid);
3939 sid_to_string(alias_sid_str, &dom_sid);
3940 sid_split_rid(&dom_sid, &alias_rid);
3942 DEBUG(10, ("sid is %s\n", alias_sid_str));
3944 /* we check if it's our SID before deleting */
3945 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3946 return NT_STATUS_NO_SUCH_ALIAS;
3948 DEBUG(10, ("lookup on Local SID\n"));
3950 if(!get_local_group_from_sid(alias_sid, &map))
3951 return NT_STATUS_NO_SUCH_ALIAS;
3953 gid=map.gid;
3955 /* check if group really exists */
3956 if ( (grp=getgrgid(gid)) == NULL)
3957 return NT_STATUS_NO_SUCH_ALIAS;
3959 /* we can delete the UNIX group */
3960 smb_delete_group(grp->gr_name);
3962 /* check if the group has been successfully deleted */
3963 if ( (grp=getgrgid(gid)) != NULL)
3964 return NT_STATUS_ACCESS_DENIED;
3966 /* don't check if we removed it as it could be an un-mapped group */
3967 pdb_delete_group_mapping_entry(alias_sid);
3969 if (!close_policy_hnd(p, &q_u->alias_pol))
3970 return NT_STATUS_OBJECT_NAME_INVALID;
3972 return NT_STATUS_OK;
3975 /*********************************************************************
3976 _samr_create_dom_group
3977 *********************************************************************/
3979 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3981 DOM_SID dom_sid;
3982 DOM_SID info_sid;
3983 fstring name;
3984 fstring sid_string;
3985 struct group *grp;
3986 struct samr_info *info;
3987 uint32 acc_granted;
3988 gid_t gid;
3990 /* Find the policy handle. Open a policy on it. */
3991 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3992 return NT_STATUS_INVALID_HANDLE;
3994 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3995 return r_u->status;
3998 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3999 return NT_STATUS_ACCESS_DENIED;
4001 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4003 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4005 /* check if group already exist */
4006 if ((grp=getgrnam(name)) != NULL)
4007 return NT_STATUS_GROUP_EXISTS;
4009 /* we can create the UNIX group */
4010 if (smb_create_group(name, &gid) != 0)
4011 return NT_STATUS_ACCESS_DENIED;
4013 /* check if the group has been successfully created */
4014 if ((grp=getgrgid(gid)) == NULL)
4015 return NT_STATUS_ACCESS_DENIED;
4017 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4019 /* add the group to the mapping table */
4020 sid_copy(&info_sid, get_global_sam_sid());
4021 sid_append_rid(&info_sid, r_u->rid);
4022 sid_to_string(sid_string, &info_sid);
4024 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
4025 return NT_STATUS_ACCESS_DENIED;
4027 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4028 return NT_STATUS_NO_MEMORY;
4030 /* get a (unique) handle. open a policy on it. */
4031 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4032 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4034 return NT_STATUS_OK;
4037 /*********************************************************************
4038 _samr_create_dom_alias
4039 *********************************************************************/
4041 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4043 DOM_SID dom_sid;
4044 DOM_SID info_sid;
4045 fstring name;
4046 fstring sid_string;
4047 struct group *grp;
4048 struct samr_info *info;
4049 uint32 acc_granted;
4050 gid_t gid;
4052 /* Find the policy handle. Open a policy on it. */
4053 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4054 return NT_STATUS_INVALID_HANDLE;
4056 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4057 return r_u->status;
4060 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4061 return NT_STATUS_ACCESS_DENIED;
4063 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4065 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4067 /* check if group already exists */
4068 if ( (grp=getgrnam(name)) != NULL)
4069 return NT_STATUS_GROUP_EXISTS;
4071 /* we can create the UNIX group */
4072 if (smb_create_group(name, &gid) != 0)
4073 return NT_STATUS_ACCESS_DENIED;
4075 /* check if the group has been successfully created */
4076 if ((grp=getgrgid(gid)) == NULL)
4077 return NT_STATUS_ACCESS_DENIED;
4079 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4081 sid_copy(&info_sid, get_global_sam_sid());
4082 sid_append_rid(&info_sid, r_u->rid);
4083 sid_to_string(sid_string, &info_sid);
4085 /* add the group to the mapping table */
4086 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
4087 return NT_STATUS_ACCESS_DENIED;
4089 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4090 return NT_STATUS_NO_MEMORY;
4092 /* get a (unique) handle. open a policy on it. */
4093 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4094 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4096 return NT_STATUS_OK;
4099 /*********************************************************************
4100 _samr_query_groupinfo
4102 sends the name/comment pair of a domain group
4103 level 1 send also the number of users of that group
4104 *********************************************************************/
4106 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4108 DOM_SID group_sid;
4109 GROUP_MAP map;
4110 uid_t *uid=NULL;
4111 int num_uids=0;
4112 GROUP_INFO_CTR *ctr;
4113 uint32 acc_granted;
4115 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4116 return NT_STATUS_INVALID_HANDLE;
4118 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4119 return r_u->status;
4122 if (!get_domain_group_from_sid(group_sid, &map))
4123 return NT_STATUS_INVALID_HANDLE;
4125 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4126 if (ctr==NULL)
4127 return NT_STATUS_NO_MEMORY;
4129 switch (q_u->switch_level) {
4130 case 1:
4131 ctr->switch_value1 = 1;
4132 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4133 return NT_STATUS_NO_SUCH_GROUP;
4134 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4135 SAFE_FREE(uid);
4136 break;
4137 case 3:
4138 ctr->switch_value1 = 3;
4139 init_samr_group_info3(&ctr->group.info3);
4140 break;
4141 case 4:
4142 ctr->switch_value1 = 4;
4143 init_samr_group_info4(&ctr->group.info4, map.comment);
4144 break;
4145 default:
4146 return NT_STATUS_INVALID_INFO_CLASS;
4149 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4151 return NT_STATUS_OK;
4154 /*********************************************************************
4155 _samr_set_groupinfo
4157 update a domain group's comment.
4158 *********************************************************************/
4160 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4162 DOM_SID group_sid;
4163 GROUP_MAP map;
4164 GROUP_INFO_CTR *ctr;
4165 uint32 acc_granted;
4167 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4168 return NT_STATUS_INVALID_HANDLE;
4170 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4171 return r_u->status;
4174 if (!get_domain_group_from_sid(group_sid, &map))
4175 return NT_STATUS_NO_SUCH_GROUP;
4177 ctr=q_u->ctr;
4179 switch (ctr->switch_value1) {
4180 case 1:
4181 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4182 break;
4183 case 4:
4184 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4185 break;
4186 default:
4187 return NT_STATUS_INVALID_INFO_CLASS;
4190 if(!pdb_update_group_mapping_entry(&map)) {
4191 return NT_STATUS_NO_SUCH_GROUP;
4194 return NT_STATUS_OK;
4197 /*********************************************************************
4198 _samr_set_aliasinfo
4200 update an alias's comment.
4201 *********************************************************************/
4203 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4205 DOM_SID group_sid;
4206 GROUP_MAP map;
4207 ALIAS_INFO_CTR *ctr;
4208 uint32 acc_granted;
4210 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4211 return NT_STATUS_INVALID_HANDLE;
4213 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4214 return r_u->status;
4217 if (!get_local_group_from_sid(group_sid, &map))
4218 return NT_STATUS_NO_SUCH_GROUP;
4220 ctr=&q_u->ctr;
4222 switch (ctr->switch_value1) {
4223 case 3:
4224 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4225 break;
4226 default:
4227 return NT_STATUS_INVALID_INFO_CLASS;
4230 if(!pdb_update_group_mapping_entry(&map)) {
4231 return NT_STATUS_NO_SUCH_GROUP;
4234 return NT_STATUS_OK;
4237 /*********************************************************************
4238 _samr_get_dom_pwinfo
4239 *********************************************************************/
4241 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4243 /* Perform access check. Since this rpc does not require a
4244 policy handle it will not be caught by the access checks on
4245 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4247 if (!pipe_access_check(p)) {
4248 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4249 r_u->status = NT_STATUS_ACCESS_DENIED;
4250 return r_u->status;
4253 /* Actually, returning zeros here works quite well :-). */
4255 return NT_STATUS_OK;
4258 /*********************************************************************
4259 _samr_open_group
4260 *********************************************************************/
4262 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4264 DOM_SID sid;
4265 DOM_SID info_sid;
4266 GROUP_MAP map;
4267 struct samr_info *info;
4268 SEC_DESC *psd = NULL;
4269 uint32 acc_granted;
4270 uint32 des_access = q_u->access_mask;
4271 size_t sd_size;
4272 NTSTATUS status;
4273 fstring sid_string;
4275 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4276 return NT_STATUS_INVALID_HANDLE;
4278 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4279 return status;
4282 /*check if access can be granted as requested by client. */
4283 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4284 se_map_generic(&des_access,&grp_generic_mapping);
4285 if (!NT_STATUS_IS_OK(status =
4286 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4287 des_access, &acc_granted, "_samr_open_group"))) {
4288 return status;
4292 /* this should not be hard-coded like this */
4293 if (!sid_equal(&sid, get_global_sam_sid()))
4294 return NT_STATUS_ACCESS_DENIED;
4296 sid_copy(&info_sid, get_global_sam_sid());
4297 sid_append_rid(&info_sid, q_u->rid_group);
4298 sid_to_string(sid_string, &info_sid);
4300 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4301 return NT_STATUS_NO_MEMORY;
4303 info->acc_granted = acc_granted;
4305 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4307 /* check if that group really exists */
4308 if (!get_domain_group_from_sid(info->sid, &map))
4309 return NT_STATUS_NO_SUCH_GROUP;
4311 /* get a (unique) handle. open a policy on it. */
4312 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4313 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4315 return NT_STATUS_OK;
4318 /*********************************************************************
4319 _samr_remove_user_foreign_domain
4320 *********************************************************************/
4322 NTSTATUS _samr_remove_user_foreign_domain(pipes_struct *p,
4323 SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN *q_u,
4324 SAMR_R_REMOVE_USER_FOREIGN_DOMAIN *r_u)
4326 DOM_SID user_sid, dom_sid;
4327 SAM_ACCOUNT *sam_pass=NULL;
4328 uint32 acc_granted;
4330 sid_copy( &user_sid, &q_u->sid.sid );
4332 DEBUG(5,("_samr_remove_user_foreign_domain: removing user [%s]\n",
4333 sid_string_static(&user_sid)));
4335 /* Find the policy handle. Open a policy on it. */
4337 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4338 return NT_STATUS_INVALID_HANDLE;
4340 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted,
4341 STD_RIGHT_DELETE_ACCESS, "_samr_remove_user_foreign_domain")))
4343 return r_u->status;
4346 if ( !sid_check_is_in_our_domain(&user_sid) ) {
4347 DEBUG(5,("_samr_remove_user_foreign_domain: user not is our domain!\n"));
4348 return NT_STATUS_NO_SUCH_USER;
4351 /* check if the user exists before trying to delete */
4353 pdb_init_sam(&sam_pass);
4355 if ( !pdb_getsampwsid(sam_pass, &user_sid) ) {
4357 DEBUG(5,("_samr_remove_user_foreign_domain:User %s doesn't exist.\n",
4358 sid_string_static(&user_sid)));
4360 pdb_free_sam(&sam_pass);
4362 return NT_STATUS_NO_SUCH_USER;
4366 * delete the unix side
4368 * note: we don't check if the delete really happened
4369 * as the script is not necessary present
4370 * and maybe the sysadmin doesn't want to delete the unix side
4373 smb_delete_user(pdb_get_username(sam_pass));
4375 /* and delete the samba side */
4377 if ( !pdb_delete_sam_account(sam_pass) ) {
4379 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
4380 pdb_free_sam(&sam_pass);
4382 return NT_STATUS_CANNOT_DELETE;
4385 pdb_free_sam(&sam_pass);
4387 return NT_STATUS_OK;
4390 /*******************************************************************
4391 _samr_unknown_2e
4392 ********************************************************************/
4394 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4396 struct samr_info *info = NULL;
4397 SAM_UNK_CTR *ctr;
4398 uint32 min_pass_len,pass_hist,flag;
4399 time_t u_expire, u_min_age;
4400 NTTIME nt_expire, nt_min_age;
4402 time_t u_lock_duration, u_reset_time;
4403 NTTIME nt_lock_duration, nt_reset_time;
4404 uint32 lockout;
4406 time_t u_logout;
4407 NTTIME nt_logout;
4409 uint32 num_users=0, num_groups=0, num_aliases=0;
4411 uint32 account_policy_temp;
4413 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4414 return NT_STATUS_NO_MEMORY;
4416 ZERO_STRUCTP(ctr);
4418 r_u->status = NT_STATUS_OK;
4420 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4422 /* find the policy handle. open a policy on it. */
4423 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4424 return NT_STATUS_INVALID_HANDLE;
4426 switch (q_u->switch_value) {
4427 case 0x01:
4428 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4429 min_pass_len = account_policy_temp;
4431 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4432 pass_hist = account_policy_temp;
4434 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4435 flag = account_policy_temp;
4437 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4438 u_expire = account_policy_temp;
4440 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4441 u_min_age = account_policy_temp;
4443 unix_to_nt_time_abs(&nt_expire, u_expire);
4444 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4446 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4447 flag, nt_expire, nt_min_age);
4448 break;
4449 case 0x02:
4450 become_root();
4451 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4452 unbecome_root();
4453 if (!NT_STATUS_IS_OK(r_u->status)) {
4454 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4455 return r_u->status;
4457 num_users=info->disp_info.num_user_account;
4458 free_samr_db(info);
4460 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4461 if (NT_STATUS_IS_ERR(r_u->status)) {
4462 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4463 return r_u->status;
4465 num_groups=info->disp_info.num_group_account;
4466 free_samr_db(info);
4468 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4469 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4470 num_users, num_groups, num_aliases);
4471 break;
4472 case 0x03:
4473 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4474 u_logout = account_policy_temp;
4476 unix_to_nt_time_abs(&nt_logout, u_logout);
4478 init_unk_info3(&ctr->info.inf3, nt_logout);
4479 break;
4480 case 0x05:
4481 init_unk_info5(&ctr->info.inf5, global_myname());
4482 break;
4483 case 0x06:
4484 init_unk_info6(&ctr->info.inf6);
4485 break;
4486 case 0x07:
4487 init_unk_info7(&ctr->info.inf7);
4488 break;
4489 case 0x0c:
4490 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4491 u_lock_duration = account_policy_temp;
4493 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4494 u_reset_time = account_policy_temp;
4496 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4497 lockout = account_policy_temp;
4499 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4500 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4502 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4503 break;
4504 default:
4505 return NT_STATUS_INVALID_INFO_CLASS;
4508 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4510 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4512 return r_u->status;
4515 /*******************************************************************
4516 _samr_
4517 ********************************************************************/
4519 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4521 time_t u_expire, u_min_age;
4522 time_t u_logout;
4523 time_t u_lock_duration, u_reset_time;
4525 r_u->status = NT_STATUS_OK;
4527 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4529 /* find the policy handle. open a policy on it. */
4530 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4531 return NT_STATUS_INVALID_HANDLE;
4533 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4535 switch (q_u->switch_value) {
4536 case 0x01:
4537 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4538 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4540 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4541 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4542 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4543 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4544 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4545 break;
4546 case 0x02:
4547 break;
4548 case 0x03:
4549 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4550 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4551 break;
4552 case 0x05:
4553 break;
4554 case 0x06:
4555 break;
4556 case 0x07:
4557 break;
4558 case 0x0c:
4559 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4560 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4562 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4563 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4564 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4565 break;
4566 default:
4567 return NT_STATUS_INVALID_INFO_CLASS;
4570 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4572 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4574 return r_u->status;