More code to store ACEs and SIDs. I have almost enough to start testing
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_samr_nt.c
blob5a8a16b256042913e5a037bde8e82f11f24bd70b
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Anthony Liguori 2002,
11 * Copyright (C) Jim McDonough 2002.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
32 #include "includes.h"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern 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 DISP_USER_INFO *disp_user_info;
48 BOOL group_dbloaded;
49 uint32 num_group_account;
50 DISP_GROUP_INFO *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;
155 /*******************************************************************
156 Function to free the per handle data.
157 ********************************************************************/
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 /* Not really a free, actually a 'clear' */
165 pdb_free_sam(&info->disp_info.disp_user_info[i].sam);
168 info->disp_info.user_dbloaded=False;
169 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
176 static void free_samr_db(struct samr_info *info)
178 /* Groups are talloced */
180 free_samr_users(info);
182 info->disp_info.group_dbloaded=False;
183 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 DISP_USER_INFO *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=(DISP_USER_INFO *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
259 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
261 if (pwd_array==NULL)
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* link the SAM_ACCOUNT to the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=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 DISP_GROUP_INFO *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, MAPPING_WITHOUT_PRIV)) {
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=(DISP_GROUP_INFO *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
318 if (group_entries!=0 && grp_array==NULL) {
319 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
320 SAFE_FREE(map);
321 return NT_STATUS_NO_MEMORY;
324 info->disp_info.disp_group_info=grp_array;
326 for (i=0; i<group_entries; i++) {
328 grp_array[i].grp=(DOMAIN_GRP *)talloc(mem_ctx, sizeof(DOMAIN_GRP));
330 fstrcpy(grp_array[i].grp->name, map[i].nt_name);
331 fstrcpy(grp_array[i].grp->comment, map[i].comment);
332 sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
333 grp_array[i].grp->attr=SID_NAME_DOM_GRP;
336 SAFE_FREE(map);
338 /* the snapshoot is in memory, we're ready to enumerate fast */
340 info->disp_info.group_dbloaded=True;
342 DEBUG(10,("load_group_domain_entries: done\n"));
344 return NT_STATUS_OK;
348 /*******************************************************************
349 _samr_close_hnd
350 ********************************************************************/
352 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
354 r_u->status = NT_STATUS_OK;
356 /* close the policy handle */
357 if (!close_policy_hnd(p, &q_u->pol))
358 return NT_STATUS_OBJECT_NAME_INVALID;
360 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
362 return r_u->status;
365 /*******************************************************************
366 samr_reply_open_domain
367 ********************************************************************/
369 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
371 struct samr_info *info;
372 SEC_DESC *psd = NULL;
373 uint32 acc_granted;
374 uint32 des_access = q_u->flags;
375 size_t sd_size;
376 NTSTATUS status;
378 r_u->status = NT_STATUS_OK;
380 /* find the connection policy handle. */
381 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
382 return NT_STATUS_INVALID_HANDLE;
384 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
385 return status;
388 /*check if access can be granted as requested by client. */
389 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
390 se_map_generic(&des_access,&dom_generic_mapping);
392 if (!NT_STATUS_IS_OK(status =
393 access_check_samr_object(psd, p->pipe_user.nt_user_token,
394 des_access, &acc_granted, "_samr_open_domain"))) {
395 return status;
398 /* associate the domain SID with the (unique) handle. */
399 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
400 return NT_STATUS_NO_MEMORY;
401 info->acc_granted = acc_granted;
403 /* get a (unique) handle. open a policy on it. */
404 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
405 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
407 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
409 return r_u->status;
412 /*******************************************************************
413 _samr_get_usrdom_pwinfo
414 ********************************************************************/
416 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
418 struct samr_info *info = NULL;
420 r_u->status = NT_STATUS_OK;
422 /* find the policy handle. open a policy on it. */
423 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
424 return NT_STATUS_INVALID_HANDLE;
426 if (!sid_check_is_in_our_domain(&info->sid))
427 return NT_STATUS_OBJECT_TYPE_MISMATCH;
429 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
431 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
434 * NT sometimes return NT_STATUS_ACCESS_DENIED
435 * I don't know yet why.
438 return r_u->status;
441 /*******************************************************************
442 samr_make_dom_obj_sd
443 ********************************************************************/
445 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
447 extern DOM_SID global_sid_World;
448 DOM_SID adm_sid;
449 DOM_SID act_sid;
451 SEC_ACE ace[3];
452 SEC_ACCESS mask;
454 SEC_ACL *psa = NULL;
456 sid_copy(&adm_sid, &global_sid_Builtin);
457 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
459 sid_copy(&act_sid, &global_sid_Builtin);
460 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
462 /*basic access for every one*/
463 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
464 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
466 /*full access for builtin aliases Administrators and Account Operators*/
467 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
468 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
469 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
471 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
472 return NT_STATUS_NO_MEMORY;
474 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
475 return NT_STATUS_NO_MEMORY;
477 return NT_STATUS_OK;
480 /*******************************************************************
481 samr_make_usr_obj_sd
482 ********************************************************************/
484 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
486 extern DOM_SID global_sid_World;
487 DOM_SID adm_sid;
488 DOM_SID act_sid;
490 SEC_ACE ace[4];
491 SEC_ACCESS mask;
493 SEC_ACL *psa = NULL;
495 sid_copy(&adm_sid, &global_sid_Builtin);
496 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
498 sid_copy(&act_sid, &global_sid_Builtin);
499 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
501 /*basic access for every one*/
502 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
503 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
505 /*full access for builtin aliases Administrators and Account Operators*/
506 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
507 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
508 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 /*extended access for the user*/
511 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
512 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
514 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
515 return NT_STATUS_NO_MEMORY;
517 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
518 return NT_STATUS_NO_MEMORY;
520 return NT_STATUS_OK;
523 /*******************************************************************
524 samr_make_grp_obj_sd
525 ********************************************************************/
527 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
529 extern DOM_SID global_sid_World;
530 DOM_SID adm_sid;
531 DOM_SID act_sid;
533 SEC_ACE ace[3];
534 SEC_ACCESS mask;
536 SEC_ACL *psa = NULL;
538 sid_copy(&adm_sid, &global_sid_Builtin);
539 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
541 sid_copy(&act_sid, &global_sid_Builtin);
542 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
544 /*basic access for every one*/
545 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
546 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
548 /*full access for builtin aliases Administrators and Account Operators*/
549 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
550 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
551 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
553 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
554 return NT_STATUS_NO_MEMORY;
556 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
557 return NT_STATUS_NO_MEMORY;
559 return NT_STATUS_OK;
562 /*******************************************************************
563 samr_make_ali_obj_sd
564 ********************************************************************/
566 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
568 extern DOM_SID global_sid_World;
569 DOM_SID adm_sid;
570 DOM_SID act_sid;
572 SEC_ACE ace[3];
573 SEC_ACCESS mask;
575 SEC_ACL *psa = NULL;
577 sid_copy(&adm_sid, &global_sid_Builtin);
578 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
580 sid_copy(&act_sid, &global_sid_Builtin);
581 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
583 /*basic access for every one*/
584 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
585 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
587 /*full access for builtin aliases Administrators and Account Operators*/
588 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
589 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
590 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
592 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
593 return NT_STATUS_NO_MEMORY;
595 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
596 return NT_STATUS_NO_MEMORY;
598 return NT_STATUS_OK;
601 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
603 struct samr_info *info = NULL;
605 /* find the policy handle. open a policy on it. */
606 if (!find_policy_by_hnd(p, pol, (void **)&info))
607 return False;
609 if (!info)
610 return False;
612 *sid = info->sid;
613 *acc_granted = info->acc_granted;
614 return True;
617 /*******************************************************************
618 _samr_set_sec_obj
619 ********************************************************************/
621 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
623 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
624 return NT_STATUS_NOT_IMPLEMENTED;
628 /*******************************************************************
629 _samr_query_sec_obj
630 ********************************************************************/
632 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
634 DOM_SID pol_sid;
635 fstring str_sid;
636 SEC_DESC * psd = NULL;
637 size_t sd_size;
638 uint32 acc_granted;
640 r_u->status = NT_STATUS_OK;
642 /* Get the SID. */
643 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
644 return NT_STATUS_INVALID_HANDLE;
648 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
650 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
652 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
653 if (pol_sid.sid_rev_num == 0)
655 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
656 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
658 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
661 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
662 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
664 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
666 /* TODO: Builtin probably needs a different SD with restricted write access*/
667 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
668 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
670 else if (sid_check_is_in_our_domain(&pol_sid) ||
671 sid_check_is_in_builtin(&pol_sid))
673 /* TODO: different SDs have to be generated for aliases groups and users.
674 Currently all three get a default user SD */
675 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
676 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
678 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
680 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
681 return NT_STATUS_NO_MEMORY;
683 if (NT_STATUS_IS_OK(r_u->status))
684 r_u->ptr = 1;
686 return r_u->status;
689 /*******************************************************************
690 makes a SAM_ENTRY / UNISTR2* structure from a user list.
691 ********************************************************************/
693 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
694 uint32 num_entries, uint32 start_idx, DISP_USER_INFO *disp_user_info,
695 DOM_SID *domain_sid)
697 uint32 i;
698 SAM_ENTRY *sam;
699 UNISTR2 *uni_name;
700 SAM_ACCOUNT *pwd = NULL;
701 UNISTR2 uni_temp_name;
702 const char *temp_name;
703 const DOM_SID *user_sid;
704 uint32 user_rid;
705 fstring user_sid_string;
706 fstring domain_sid_string;
708 *sam_pp = NULL;
709 *uni_name_pp = NULL;
711 if (num_entries == 0)
712 return NT_STATUS_OK;
714 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
716 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
718 if (sam == NULL || uni_name == NULL) {
719 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
720 return NT_STATUS_NO_MEMORY;
723 for (i = 0; i < num_entries; i++) {
724 pwd = disp_user_info[i+start_idx].sam;
725 temp_name = pdb_get_username(pwd);
726 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
727 user_sid = pdb_get_user_sid(pwd);
729 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
730 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
731 "the domain sid %s. Failing operation.\n",
732 temp_name,
733 sid_to_string(user_sid_string, user_sid),
734 sid_to_string(domain_sid_string, domain_sid)));
735 return NT_STATUS_UNSUCCESSFUL;
738 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
739 copy_unistr2(&uni_name[i], &uni_temp_name);
742 *sam_pp = sam;
743 *uni_name_pp = uni_name;
744 return NT_STATUS_OK;
747 /*******************************************************************
748 samr_reply_enum_dom_users
749 ********************************************************************/
751 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
752 SAMR_R_ENUM_DOM_USERS *r_u)
754 struct samr_info *info = NULL;
755 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
756 int num_account;
757 uint32 enum_context=q_u->start_idx;
758 uint32 max_size=q_u->max_size;
759 uint32 temp_size;
760 enum remote_arch_types ra_type = get_remote_arch();
761 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
762 uint32 max_entries = max_sam_entries;
763 DOM_SID domain_sid;
765 r_u->status = NT_STATUS_OK;
767 /* find the policy handle. open a policy on it. */
768 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
769 return NT_STATUS_INVALID_HANDLE;
771 domain_sid = info->sid;
773 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
774 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
775 "_samr_enum_dom_users"))) {
776 return r_u->status;
779 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
781 become_root();
782 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
783 unbecome_root();
785 if (!NT_STATUS_IS_OK(r_u->status))
786 return r_u->status;
788 num_account = info->disp_info.num_user_account;
790 if (enum_context > num_account) {
791 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
792 return NT_STATUS_OK;
795 /* verify we won't overflow */
796 if (max_entries > num_account-enum_context) {
797 max_entries = num_account-enum_context;
798 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
801 /* calculate the size and limit on the number of entries we will return */
802 temp_size=max_entries*struct_size;
804 if (temp_size>max_size) {
805 max_entries=MIN((max_size/struct_size),max_entries);;
806 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
810 * Note from JRA. total_entries is not being used here. Currently if there is a
811 * large user base then it looks like NT will enumerate until get_sampwd_entries
812 * returns False due to num_entries being zero. This will cause an access denied
813 * return. I don't think this is right and needs further investigation. Note that
814 * this is also the same in the TNG code (I don't think that has been tested with
815 * a very large user list as MAX_SAM_ENTRIES is set to 600).
817 * I also think that one of the 'num_entries' return parameters is probably
818 * the "max entries" parameter - but in the TNG code they're all currently set to the same
819 * value (again I think this is wrong).
822 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
823 max_entries, enum_context,
824 info->disp_info.disp_user_info,
825 &domain_sid);
827 if (!NT_STATUS_IS_OK(r_u->status))
828 return r_u->status;
830 if (enum_context+max_entries < num_account)
831 r_u->status = STATUS_MORE_ENTRIES;
833 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
835 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
837 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
839 return r_u->status;
842 /*******************************************************************
843 makes a SAM_ENTRY / UNISTR2* structure from a group list.
844 ********************************************************************/
846 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
847 uint32 num_sam_entries, DOMAIN_GRP *grp)
849 uint32 i;
850 SAM_ENTRY *sam;
851 UNISTR2 *uni_name;
853 *sam_pp = NULL;
854 *uni_name_pp = NULL;
856 if (num_sam_entries == 0)
857 return;
859 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
861 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
863 if (sam == NULL || uni_name == NULL) {
864 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
865 return;
868 for (i = 0; i < num_sam_entries; i++) {
870 * JRA. I think this should include the null. TNG does not.
872 int len = strlen(grp[i].name)+1;
874 init_sam_entry(&sam[i], len, grp[i].rid);
875 init_unistr2(&uni_name[i], grp[i].name, len);
878 *sam_pp = sam;
879 *uni_name_pp = uni_name;
882 /*******************************************************************
883 Get the group entries - similar to get_sampwd_entries().
884 ********************************************************************/
886 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
887 uint32 *p_num_entries, uint32 max_entries)
889 fstring sid_str;
890 uint32 num_entries = 0;
891 int i;
892 GROUP_MAP smap;
893 GROUP_MAP *map = NULL;
895 sid_to_string(sid_str, sid);
896 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
898 *p_num_entries = 0;
900 /* well-known aliases */
901 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
903 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
905 if (num_entries != 0) {
906 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
907 if (*d_grp==NULL)
908 return NT_STATUS_NO_MEMORY;
910 for(i=0; i<num_entries && i<max_entries; i++) {
911 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
912 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
916 SAFE_FREE(map);
918 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
919 struct sys_grent *glist;
920 struct sys_grent *grp;
921 struct passwd *pw;
922 gid_t winbind_gid_low, winbind_gid_high;
923 BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
925 /* local aliases */
926 /* we return the UNIX groups here. This seems to be the right */
927 /* thing to do, since NT member servers return their local */
928 /* groups in the same situation. */
930 /* use getgrent_list() to retrieve the list of groups to avoid
931 * problems with getgrent possible infinite loop by internal
932 * libc grent structures overwrites by called functions */
933 grp = glist = getgrent_list();
934 if (grp == NULL)
935 return NT_STATUS_NO_MEMORY;
937 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
938 uint32 trid;
940 if(!pdb_getgrgid(&smap, grp->gr_gid, MAPPING_WITHOUT_PRIV))
941 continue;
943 if (smap.sid_name_use!=SID_NAME_ALIAS) {
944 continue;
947 sid_split_rid(&smap.sid, &trid);
949 if (!sid_equal(sid, &smap.sid))
950 continue;
952 /* Don't return winbind groups as they are not local! */
953 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
954 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
955 continue;
958 /* Don't return user private groups... */
960 if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
961 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
962 continue;
965 for( i = 0; i < num_entries; i++)
966 if ( (*d_grp)[i].rid == trid )
967 break;
969 if ( i < num_entries ) {
970 continue; /* rid was there, dup! */
973 /* JRA - added this for large group db enumeration... */
975 if (start_idx > 0) {
976 /* skip the requested number of entries.
977 not very efficient, but hey...
979 start_idx--;
980 continue;
983 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
984 if (*d_grp==NULL) {
985 grent_free(glist);
986 return NT_STATUS_NO_MEMORY;
989 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
990 (*d_grp)[num_entries].rid = trid;
991 num_entries++;
992 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
995 grent_free(glist);
998 *p_num_entries = num_entries;
1000 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
1002 if (num_entries >= max_entries)
1003 return STATUS_MORE_ENTRIES;
1004 return NT_STATUS_OK;
1007 /*******************************************************************
1008 Get the group entries - similar to get_sampwd_entries().
1009 ********************************************************************/
1011 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1012 uint32 *p_num_entries, uint32 max_entries)
1014 GROUP_MAP *map=NULL;
1015 int i;
1016 uint32 group_entries = 0;
1017 uint32 num_entries = 0;
1019 *p_num_entries = 0;
1021 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
1023 num_entries=group_entries-start_idx;
1025 /* limit the number of entries */
1026 if (num_entries>max_entries) {
1027 DEBUG(5,("Limiting to %d entries\n", max_entries));
1028 num_entries=max_entries;
1031 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1032 if (num_entries!=0 && *d_grp==NULL){
1033 SAFE_FREE(map);
1034 return NT_STATUS_NO_MEMORY;
1037 for (i=0; i<num_entries; i++) {
1038 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1039 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1040 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1041 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1044 SAFE_FREE(map);
1046 *p_num_entries = num_entries;
1048 return NT_STATUS_OK;
1051 /*******************************************************************
1052 samr_reply_enum_dom_groups
1053 ********************************************************************/
1055 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1057 DOMAIN_GRP *grp=NULL;
1058 uint32 num_entries;
1059 DOM_SID sid;
1060 uint32 acc_granted;
1062 r_u->status = NT_STATUS_OK;
1064 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1065 return NT_STATUS_INVALID_HANDLE;
1067 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1068 return r_u->status;
1071 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1073 /* the domain group array is being allocated in the function below */
1074 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))) {
1075 return r_u->status;
1078 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1080 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1082 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1084 return r_u->status;
1088 /*******************************************************************
1089 samr_reply_enum_dom_aliases
1090 ********************************************************************/
1092 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1094 DOMAIN_GRP *grp=NULL;
1095 uint32 num_entries = 0;
1096 fstring sid_str;
1097 DOM_SID sid;
1098 NTSTATUS status;
1099 uint32 acc_granted;
1101 r_u->status = NT_STATUS_OK;
1103 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1104 return NT_STATUS_INVALID_HANDLE;
1106 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1107 return r_u->status;
1110 sid_to_string(sid_str, &sid);
1111 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1113 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1114 &num_entries, MAX_SAM_ENTRIES);
1115 if (NT_STATUS_IS_ERR(status)) return status;
1117 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1119 /*safe_free(grp);*/
1121 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1123 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1125 return r_u->status;
1128 /*******************************************************************
1129 samr_reply_query_dispinfo
1130 ********************************************************************/
1131 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1132 SAMR_R_QUERY_DISPINFO *r_u)
1134 struct samr_info *info = NULL;
1135 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1137 uint32 max_entries=q_u->max_entries;
1138 uint32 enum_context=q_u->start_idx;
1139 uint32 max_size=q_u->max_size;
1141 SAM_DISPINFO_CTR *ctr;
1142 uint32 temp_size=0, total_data_size=0;
1143 NTSTATUS disp_ret;
1144 uint32 num_account = 0;
1145 enum remote_arch_types ra_type = get_remote_arch();
1146 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1147 DOM_SID domain_sid;
1149 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1150 r_u->status = NT_STATUS_OK;
1152 /* find the policy handle. open a policy on it. */
1153 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1154 return NT_STATUS_INVALID_HANDLE;
1156 domain_sid = info->sid;
1159 * calculate how many entries we will return.
1160 * based on
1161 * - the number of entries the client asked
1162 * - our limit on that
1163 * - the starting point (enumeration context)
1164 * - the buffer size the client will accept
1168 * We are a lot more like W2K. Instead of reading the SAM
1169 * each time to find the records we need to send back,
1170 * we read it once and link that copy to the sam handle.
1171 * For large user list (over the MAX_SAM_ENTRIES)
1172 * it's a definitive win.
1173 * second point to notice: between enumerations
1174 * our sam is now the same as it's a snapshoot.
1175 * third point: got rid of the static SAM_USER_21 struct
1176 * no more intermediate.
1177 * con: it uses much more memory, as a full copy is stored
1178 * in memory.
1180 * If you want to change it, think twice and think
1181 * of the second point , that's really important.
1183 * JFM, 12/20/2001
1186 /* Get what we need from the password database */
1187 switch (q_u->switch_level) {
1188 case 0x1:
1189 /* When playing with usrmgr, this is necessary
1190 if you want immediate refresh after editing
1191 a user. I would like to do this after the
1192 setuserinfo2, but we do not have access to
1193 the domain handle in that call, only to the
1194 user handle. Where else does this hurt?
1195 -- Volker
1197 #if 0
1198 /* We cannot do this here - it kills performace. JRA. */
1199 free_samr_users(info);
1200 #endif
1201 case 0x2:
1202 case 0x4:
1203 become_root();
1204 /* Level 2 is for all machines, otherwise only 'normal' users */
1205 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1206 unbecome_root();
1207 if (!NT_STATUS_IS_OK(r_u->status)) {
1208 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1209 return r_u->status;
1211 num_account = info->disp_info.num_user_account;
1212 break;
1213 case 0x3:
1214 case 0x5:
1215 r_u->status = load_group_domain_entries(info, &info->sid);
1216 if (!NT_STATUS_IS_OK(r_u->status))
1217 return r_u->status;
1218 num_account = info->disp_info.num_group_account;
1219 break;
1220 default:
1221 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1222 return NT_STATUS_INVALID_INFO_CLASS;
1225 /* first limit the number of entries we will return */
1226 if(max_entries > max_sam_entries) {
1227 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1228 max_entries = max_sam_entries;
1231 if (enum_context > num_account) {
1232 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1233 return NT_STATUS_NO_MORE_ENTRIES;
1236 /* verify we won't overflow */
1237 if (max_entries > num_account-enum_context) {
1238 max_entries = num_account-enum_context;
1239 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1242 /* calculate the size and limit on the number of entries we will return */
1243 temp_size=max_entries*struct_size;
1245 if (temp_size>max_size) {
1246 max_entries=MIN((max_size/struct_size),max_entries);;
1247 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1250 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1251 return NT_STATUS_NO_MEMORY;
1253 ZERO_STRUCTP(ctr);
1255 /* Now create reply structure */
1256 switch (q_u->switch_level) {
1257 case 0x1:
1258 if (max_entries) {
1259 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1260 return NT_STATUS_NO_MEMORY;
1262 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1263 info->disp_info.disp_user_info, &domain_sid);
1264 if (!NT_STATUS_IS_OK(disp_ret))
1265 return disp_ret;
1266 break;
1267 case 0x2:
1268 if (max_entries) {
1269 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1270 return NT_STATUS_NO_MEMORY;
1272 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1273 info->disp_info.disp_user_info, &domain_sid);
1274 if (!NT_STATUS_IS_OK(disp_ret))
1275 return disp_ret;
1276 break;
1277 case 0x3:
1278 if (max_entries) {
1279 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1280 return NT_STATUS_NO_MEMORY;
1282 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1283 if (!NT_STATUS_IS_OK(disp_ret))
1284 return disp_ret;
1285 break;
1286 case 0x4:
1287 if (max_entries) {
1288 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1289 return NT_STATUS_NO_MEMORY;
1291 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1292 if (!NT_STATUS_IS_OK(disp_ret))
1293 return disp_ret;
1294 break;
1295 case 0x5:
1296 if (max_entries) {
1297 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1298 return NT_STATUS_NO_MEMORY;
1300 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1301 if (!NT_STATUS_IS_OK(disp_ret))
1302 return disp_ret;
1303 break;
1305 default:
1306 ctr->sam.info = NULL;
1307 return NT_STATUS_INVALID_INFO_CLASS;
1310 /* calculate the total size */
1311 total_data_size=num_account*struct_size;
1313 if (enum_context+max_entries < num_account)
1314 r_u->status = STATUS_MORE_ENTRIES;
1316 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1318 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1320 return r_u->status;
1324 /*******************************************************************
1325 samr_reply_query_aliasinfo
1326 ********************************************************************/
1328 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1330 DOM_SID sid;
1331 GROUP_MAP map;
1332 uint32 acc_granted;
1334 r_u->status = NT_STATUS_OK;
1336 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1338 /* find the policy handle. open a policy on it. */
1339 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1340 return NT_STATUS_INVALID_HANDLE;
1341 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1342 return r_u->status;
1345 if (!sid_check_is_in_our_domain(&sid) &&
1346 !sid_check_is_in_builtin(&sid))
1347 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1349 if (!pdb_getgrsid(&map, sid, MAPPING_WITHOUT_PRIV))
1350 return NT_STATUS_NO_SUCH_ALIAS;
1352 switch (q_u->switch_level) {
1353 case 1:
1354 r_u->ptr = 1;
1355 r_u->ctr.switch_value1 = 1;
1356 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1357 break;
1358 case 3:
1359 r_u->ptr = 1;
1360 r_u->ctr.switch_value1 = 3;
1361 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1362 break;
1363 default:
1364 return NT_STATUS_INVALID_INFO_CLASS;
1367 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1369 return r_u->status;
1372 #if 0
1373 /*******************************************************************
1374 samr_reply_lookup_ids
1375 ********************************************************************/
1377 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1379 uint32 rid[MAX_SAM_ENTRIES];
1380 int num_rids = q_u->num_sids1;
1382 r_u->status = NT_STATUS_OK;
1384 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1386 if (num_rids > MAX_SAM_ENTRIES) {
1387 num_rids = MAX_SAM_ENTRIES;
1388 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1391 #if 0
1392 int i;
1393 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1395 for (i = 0; i < num_rids && status == 0; i++)
1397 struct sam_passwd *sam_pass;
1398 fstring user_name;
1401 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1402 q_u->uni_user_name[i].uni_str_len));
1404 /* find the user account */
1405 become_root();
1406 sam_pass = get_smb21pwd_entry(user_name, 0);
1407 unbecome_root();
1409 if (sam_pass == NULL)
1411 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1412 rid[i] = 0;
1414 else
1416 rid[i] = sam_pass->user_rid;
1419 #endif
1421 num_rids = 1;
1422 rid[0] = BUILTIN_ALIAS_RID_USERS;
1424 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1426 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1428 return r_u->status;
1430 #endif
1432 /*******************************************************************
1433 _samr_lookup_names
1434 ********************************************************************/
1436 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1438 uint32 rid[MAX_SAM_ENTRIES];
1439 uint32 local_rid;
1440 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1441 enum SID_NAME_USE local_type;
1442 int i;
1443 int num_rids = q_u->num_names2;
1444 DOM_SID pol_sid;
1445 fstring sid_str;
1446 uint32 acc_granted;
1448 r_u->status = NT_STATUS_OK;
1450 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1452 ZERO_ARRAY(rid);
1453 ZERO_ARRAY(type);
1455 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1456 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1457 return r_u->status;
1460 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 */
1461 return r_u->status;
1464 if (num_rids > MAX_SAM_ENTRIES) {
1465 num_rids = MAX_SAM_ENTRIES;
1466 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1469 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1471 become_root(); /* local_lookup_name can require root privs */
1473 for (i = 0; i < num_rids; i++) {
1474 fstring name;
1475 DOM_SID sid;
1477 r_u->status = NT_STATUS_NONE_MAPPED;
1479 rid [i] = 0xffffffff;
1480 type[i] = SID_NAME_UNKNOWN;
1482 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.
1495 if(local_lookup_name(name, &sid, &local_type)) {
1496 sid_split_rid(&sid, &local_rid);
1498 if (sid_equal(&sid, &pol_sid)) {
1499 rid[i]=local_rid;
1500 type[i]=local_type;
1501 r_u->status = NT_STATUS_OK;
1506 unbecome_root();
1508 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1510 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1512 return r_u->status;
1515 /*******************************************************************
1516 _samr_chgpasswd_user
1517 ********************************************************************/
1519 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1521 fstring user_name;
1522 fstring wks;
1524 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1526 r_u->status = NT_STATUS_OK;
1528 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1529 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1531 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1534 * Pass the user through the NT -> unix user mapping
1535 * function.
1538 (void)map_username(user_name);
1541 * UNIX username case mangling not required, pass_oem_change
1542 * is case insensitive.
1545 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1546 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1548 init_samr_r_chgpasswd_user(r_u, r_u->status);
1550 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1552 return r_u->status;
1555 /*******************************************************************
1556 makes a SAMR_R_LOOKUP_RIDS structure.
1557 ********************************************************************/
1559 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1560 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1562 uint32 i;
1563 UNIHDR *hdr_name=NULL;
1564 UNISTR2 *uni_name=NULL;
1566 *pp_uni_name = NULL;
1567 *pp_hdr_name = NULL;
1569 if (num_names != 0) {
1570 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1571 if (hdr_name == NULL)
1572 return False;
1574 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1575 if (uni_name == NULL)
1576 return False;
1579 for (i = 0; i < num_names; i++) {
1580 int len = names[i] != NULL ? strlen(names[i]) : 0;
1581 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1582 init_uni_hdr(&hdr_name[i], len);
1583 init_unistr2(&uni_name[i], names[i], len);
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 _api_samr_open_user. Safe - gives out no passwd info.
1665 ********************************************************************/
1667 NTSTATUS _api_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, (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 _api_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 _api_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 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2210 /* Get the domain SID stored in the domain policy */
2211 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2212 return NT_STATUS_INVALID_HANDLE;
2214 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2215 return nt_status;
2218 /* find the account: tell the caller if it exists.
2219 lkclXXXX i have *no* idea if this is a problem or not
2220 or even if you are supposed to construct a different
2221 reply if the account already exists...
2224 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2225 strlower(account);
2227 pdb_init_sam(&sam_pass);
2229 become_root();
2230 ret = pdb_getsampwnam(sam_pass, account);
2231 unbecome_root();
2232 if (ret == True) {
2233 /* this account exists: say so */
2234 pdb_free_sam(&sam_pass);
2235 return NT_STATUS_USER_EXISTS;
2238 pdb_free_sam(&sam_pass);
2241 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2242 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2243 * that only people with write access to the smbpasswd file will be able
2244 * to create a user. JRA.
2248 * add the user in the /etc/passwd file or the unix authority system.
2249 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2250 * a) local_password_change() checks for us if the /etc/passwd account really exists
2251 * b) smb_create_user() would return an error if the account already exists
2252 * and as it could return an error also if it can't create the account, it would be tricky.
2254 * So we go the easy way, only check after if the account exists.
2255 * JFM (2/3/2001), to clear any possible bad understanding (-:
2257 * We now have seperate script paramaters for adding users/machines so we
2258 * now have some sainity-checking to match.
2261 DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
2262 #if 0
2263 if ((acb_info & ACB_WSTRUST) && (account[strlen(account)-1] == '$')) {
2264 pstrcpy(add_script, lp_addmachine_script());
2265 } else if ((!(acb_info & ACB_WSTRUST)) && (account[strlen(account)-1] != '$')) {
2266 pstrcpy(add_script, lp_adduser_script());
2267 } else {
2268 DEBUG(0, ("_api_samr_create_user: mismatch between trust flags and $ termination\n"));
2269 pdb_free_sam(&sam_pass);
2270 return NT_STATUS_UNSUCCESSFUL;
2272 #endif
2275 * we can't check both the ending $ and the acb_info.
2277 * UserManager creates trust accounts (ending in $,
2278 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2279 * JFM, 11/29/2001
2281 if (account[strlen(account)-1] == '$')
2282 pstrcpy(add_script, lp_addmachine_script());
2283 else
2284 pstrcpy(add_script, lp_adduser_script());
2286 if (*add_script) {
2287 int add_ret;
2288 all_string_sub(add_script, "%u", account, sizeof(account));
2289 add_ret = smbrun(add_script,NULL);
2290 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2293 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sam_pass))) {
2294 return nt_status;
2297 pw = getpwnam_alloc(account);
2299 if (pw) {
2300 DOM_SID user_sid;
2301 DOM_SID group_sid;
2302 if (!uid_to_sid(&user_sid, pw->pw_uid)) {
2303 passwd_free(&pw); /* done with this now */
2304 pdb_free_sam(&sam_pass);
2305 DEBUG(1, ("_api_samr_create_user: uid_to_sid failed, cannot add user.\n"));
2306 return NT_STATUS_ACCESS_DENIED;
2309 if (!pdb_set_user_sid(sam_pass, &user_sid, PDB_CHANGED)) {
2310 passwd_free(&pw); /* done with this now */
2311 pdb_free_sam(&sam_pass);
2312 return NT_STATUS_NO_MEMORY;
2315 if (!gid_to_sid(&group_sid, pw->pw_gid)) {
2316 passwd_free(&pw); /* done with this now */
2317 pdb_free_sam(&sam_pass);
2318 DEBUG(1, ("_api_samr_create_user: gid_to_sid failed, cannot add user.\n"));
2319 return NT_STATUS_ACCESS_DENIED;
2322 if (!pdb_set_group_sid(sam_pass, &group_sid, PDB_CHANGED)) {
2323 passwd_free(&pw); /* done with this now */
2324 pdb_free_sam(&sam_pass);
2325 return NT_STATUS_NO_MEMORY;
2328 passwd_free(&pw); /* done with this now */
2329 } else {
2330 DEBUG(3,("attempting to create non-unix account %s\n", account));
2334 if (!pdb_set_username(sam_pass, account, PDB_CHANGED)) {
2335 pdb_free_sam(&sam_pass);
2336 return NT_STATUS_NO_MEMORY;
2339 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2341 if (!pdb_add_sam_account(sam_pass)) {
2342 pdb_free_sam(&sam_pass);
2343 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2344 account));
2345 return NT_STATUS_ACCESS_DENIED;
2348 pdb_reset_sam(sam_pass);
2350 if (!pdb_getsampwnam(sam_pass, account)) {
2351 pdb_free_sam(&sam_pass);
2352 DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n",
2353 account));
2354 return NT_STATUS_ACCESS_DENIED;
2357 /* Get the user's SID */
2358 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2360 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2361 se_map_generic(&des_access, &usr_generic_mapping);
2362 if (!NT_STATUS_IS_OK(nt_status =
2363 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2364 des_access, &acc_granted, "_samr_create_user"))) {
2365 return nt_status;
2368 /* associate the user's SID with the new handle. */
2369 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2370 pdb_free_sam(&sam_pass);
2371 return NT_STATUS_NO_MEMORY;
2374 ZERO_STRUCTP(info);
2375 info->sid = sid;
2376 info->acc_granted = acc_granted;
2378 /* get a (unique) handle. open a policy on it. */
2379 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2380 pdb_free_sam(&sam_pass);
2381 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2384 r_u->user_rid=pdb_get_user_rid(sam_pass);
2386 r_u->access_granted = acc_granted;
2388 pdb_free_sam(&sam_pass);
2390 return NT_STATUS_OK;
2393 /*******************************************************************
2394 samr_reply_connect_anon
2395 ********************************************************************/
2397 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2399 struct samr_info *info = NULL;
2401 /* Access check */
2403 if (!pipe_access_check(p)) {
2404 DEBUG(3, ("access denied to samr_connect_anon\n"));
2405 r_u->status = NT_STATUS_ACCESS_DENIED;
2406 return r_u->status;
2409 /* set up the SAMR connect_anon response */
2411 r_u->status = NT_STATUS_OK;
2413 /* associate the user's SID with the new handle. */
2414 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2415 return NT_STATUS_NO_MEMORY;
2417 info->status = q_u->unknown_0;
2419 /* get a (unique) handle. open a policy on it. */
2420 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2421 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2423 return r_u->status;
2426 /*******************************************************************
2427 samr_reply_connect
2428 ********************************************************************/
2430 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2432 struct samr_info *info = NULL;
2433 SEC_DESC *psd = NULL;
2434 uint32 acc_granted;
2435 uint32 des_access = q_u->access_mask;
2436 size_t sd_size;
2437 NTSTATUS nt_status;
2440 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2442 /* Access check */
2444 if (!pipe_access_check(p)) {
2445 DEBUG(3, ("access denied to samr_connect\n"));
2446 r_u->status = NT_STATUS_ACCESS_DENIED;
2447 return r_u->status;
2450 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2451 se_map_generic(&des_access, &sam_generic_mapping);
2452 if (!NT_STATUS_IS_OK(nt_status =
2453 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2454 des_access, &acc_granted, "_samr_connect"))) {
2455 return nt_status;
2458 r_u->status = NT_STATUS_OK;
2460 /* associate the user's SID and access granted with the new handle. */
2461 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2462 return NT_STATUS_NO_MEMORY;
2464 info->acc_granted = acc_granted;
2465 info->status = q_u->access_mask;
2467 /* get a (unique) handle. open a policy on it. */
2468 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2469 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2471 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2473 return r_u->status;
2476 /*******************************************************************
2477 samr_connect4
2478 ********************************************************************/
2480 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2482 struct samr_info *info = NULL;
2483 SEC_DESC *psd = NULL;
2484 uint32 acc_granted;
2485 uint32 des_access = q_u->access_mask;
2486 size_t sd_size;
2487 NTSTATUS nt_status;
2490 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2492 /* Access check */
2494 if (!pipe_access_check(p)) {
2495 DEBUG(3, ("access denied to samr_connect4\n"));
2496 r_u->status = NT_STATUS_ACCESS_DENIED;
2497 return r_u->status;
2500 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2501 se_map_generic(&des_access, &sam_generic_mapping);
2502 if (!NT_STATUS_IS_OK(nt_status =
2503 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2504 des_access, &acc_granted, "_samr_connect"))) {
2505 return nt_status;
2508 r_u->status = NT_STATUS_OK;
2510 /* associate the user's SID and access granted with the new handle. */
2511 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2512 return NT_STATUS_NO_MEMORY;
2514 info->acc_granted = acc_granted;
2515 info->status = q_u->access_mask;
2517 /* get a (unique) handle. open a policy on it. */
2518 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2519 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2521 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2523 return r_u->status;
2526 /**********************************************************************
2527 api_samr_lookup_domain
2528 **********************************************************************/
2530 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2532 struct samr_info *info;
2533 fstring domain_name;
2534 DOM_SID sid;
2536 r_u->status = NT_STATUS_OK;
2538 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2539 return NT_STATUS_INVALID_HANDLE;
2541 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
2542 return r_u->status;
2545 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2547 ZERO_STRUCT(sid);
2549 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2550 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2553 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2555 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2557 return r_u->status;
2560 /******************************************************************
2561 makes a SAMR_R_ENUM_DOMAINS structure.
2562 ********************************************************************/
2564 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2565 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2567 uint32 i;
2568 SAM_ENTRY *sam;
2569 UNISTR2 *uni_name;
2571 DEBUG(5, ("make_enum_domains\n"));
2573 *pp_sam = NULL;
2574 *pp_uni_name = NULL;
2576 if (num_sam_entries == 0)
2577 return True;
2579 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2580 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2582 if (sam == NULL || uni_name == NULL)
2583 return False;
2585 for (i = 0; i < num_sam_entries; i++) {
2586 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2588 init_sam_entry(&sam[i], len, 0);
2589 init_unistr2(&uni_name[i], doms[i], len);
2592 *pp_sam = sam;
2593 *pp_uni_name = uni_name;
2595 return True;
2598 /**********************************************************************
2599 api_samr_enum_domains
2600 **********************************************************************/
2602 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2604 struct samr_info *info;
2605 uint32 num_entries = 2;
2606 fstring dom[2];
2607 const char *name;
2609 r_u->status = NT_STATUS_OK;
2611 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2612 return NT_STATUS_INVALID_HANDLE;
2614 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2615 return r_u->status;
2618 switch (lp_server_role()) {
2619 case ROLE_DOMAIN_PDC:
2620 case ROLE_DOMAIN_BDC:
2621 name = lp_workgroup();
2622 break;
2623 default:
2624 name = global_myname();
2627 fstrcpy(dom[0],name);
2628 strupper(dom[0]);
2629 fstrcpy(dom[1],"Builtin");
2631 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2632 return NT_STATUS_NO_MEMORY;
2634 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2636 return r_u->status;
2639 /*******************************************************************
2640 api_samr_open_alias
2641 ********************************************************************/
2643 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2645 DOM_SID sid;
2646 POLICY_HND domain_pol = q_u->dom_pol;
2647 uint32 alias_rid = q_u->rid_alias;
2648 POLICY_HND *alias_pol = &r_u->pol;
2649 struct samr_info *info = NULL;
2650 SEC_DESC *psd = NULL;
2651 uint32 acc_granted;
2652 uint32 des_access = q_u->access_mask;
2653 size_t sd_size;
2654 NTSTATUS status;
2656 r_u->status = NT_STATUS_OK;
2658 /* find the domain policy and get the SID / access bits stored in the domain policy */
2659 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2660 return NT_STATUS_INVALID_HANDLE;
2662 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2663 return status;
2666 /* append the alias' RID to it */
2667 if (!sid_append_rid(&sid, alias_rid))
2668 return NT_STATUS_NO_SUCH_USER;
2670 /*check if access can be granted as requested by client. */
2671 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2672 se_map_generic(&des_access,&ali_generic_mapping);
2673 if (!NT_STATUS_IS_OK(status =
2674 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2675 des_access, &acc_granted, "_samr_open_alias"))) {
2676 return status;
2680 * we should check if the rid really exist !!!
2681 * JFM.
2684 /* associate the user's SID with the new handle. */
2685 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2686 return NT_STATUS_NO_MEMORY;
2688 info->acc_granted = acc_granted;
2690 /* get a (unique) handle. open a policy on it. */
2691 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2692 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2694 return r_u->status;
2697 /*******************************************************************
2698 set_user_info_10
2699 ********************************************************************/
2701 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2703 SAM_ACCOUNT *pwd =NULL;
2704 BOOL ret;
2706 pdb_init_sam(&pwd);
2708 ret = pdb_getsampwsid(pwd, sid);
2710 if(ret==False) {
2711 pdb_free_sam(&pwd);
2712 return False;
2715 if (id10 == NULL) {
2716 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2717 pdb_free_sam(&pwd);
2718 return False;
2721 /* FIX ME: check if the value is really changed --metze */
2722 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2723 pdb_free_sam(&pwd);
2724 return False;
2727 if(!pdb_update_sam_account(pwd)) {
2728 pdb_free_sam(&pwd);
2729 return False;
2732 pdb_free_sam(&pwd);
2734 return True;
2737 /*******************************************************************
2738 set_user_info_12
2739 ********************************************************************/
2741 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2743 SAM_ACCOUNT *pwd = NULL;
2745 pdb_init_sam(&pwd);
2747 if(!pdb_getsampwsid(pwd, sid)) {
2748 pdb_free_sam(&pwd);
2749 return False;
2752 if (id12 == NULL) {
2753 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2754 pdb_free_sam(&pwd);
2755 return False;
2758 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2759 pdb_free_sam(&pwd);
2760 return False;
2762 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2763 pdb_free_sam(&pwd);
2764 return False;
2766 if (!pdb_set_pass_changed_now (pwd)) {
2767 pdb_free_sam(&pwd);
2768 return False;
2771 if(!pdb_update_sam_account(pwd)) {
2772 pdb_free_sam(&pwd);
2773 return False;
2776 pdb_free_sam(&pwd);
2777 return True;
2780 /*******************************************************************
2781 set_user_info_21
2782 ********************************************************************/
2784 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2786 SAM_ACCOUNT *pwd = NULL;
2788 if (id21 == NULL) {
2789 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2790 return False;
2793 pdb_init_sam(&pwd);
2795 if (!pdb_getsampwsid(pwd, sid)) {
2796 pdb_free_sam(&pwd);
2797 return False;
2800 copy_id21_to_sam_passwd(pwd, id21);
2803 * The funny part about the previous two calls is
2804 * that pwd still has the password hashes from the
2805 * passdb entry. These have not been updated from
2806 * id21. I don't know if they need to be set. --jerry
2809 /* write the change out */
2810 if(!pdb_update_sam_account(pwd)) {
2811 pdb_free_sam(&pwd);
2812 return False;
2815 pdb_free_sam(&pwd);
2817 return True;
2820 /*******************************************************************
2821 set_user_info_23
2822 ********************************************************************/
2824 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2826 SAM_ACCOUNT *pwd = NULL;
2827 pstring plaintext_buf;
2828 uint32 len;
2829 uint16 acct_ctrl;
2831 if (id23 == NULL) {
2832 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2833 return False;
2836 pdb_init_sam(&pwd);
2838 if (!pdb_getsampwsid(pwd, sid)) {
2839 pdb_free_sam(&pwd);
2840 return False;
2843 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2844 pdb_get_username(pwd)));
2846 acct_ctrl = pdb_get_acct_ctrl(pwd);
2848 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2849 pdb_free_sam(&pwd);
2850 return False;
2853 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2854 pdb_free_sam(&pwd);
2855 return False;
2858 copy_id23_to_sam_passwd(pwd, id23);
2860 /* if it's a trust account, don't update /etc/passwd */
2861 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2862 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2863 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2864 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2865 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2866 } else {
2867 /* update the UNIX password */
2868 if (lp_unix_password_sync() )
2869 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2870 pdb_free_sam(&pwd);
2871 return False;
2875 ZERO_STRUCT(plaintext_buf);
2877 if(!pdb_update_sam_account(pwd)) {
2878 pdb_free_sam(&pwd);
2879 return False;
2882 pdb_free_sam(&pwd);
2884 return True;
2887 /*******************************************************************
2888 set_user_info_pw
2889 ********************************************************************/
2891 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2893 SAM_ACCOUNT *pwd = NULL;
2894 uint32 len;
2895 pstring plaintext_buf;
2896 uint16 acct_ctrl;
2898 pdb_init_sam(&pwd);
2900 if (!pdb_getsampwsid(pwd, sid)) {
2901 pdb_free_sam(&pwd);
2902 return False;
2905 DEBUG(5, ("Attempting administrator password change for user %s\n",
2906 pdb_get_username(pwd)));
2908 acct_ctrl = pdb_get_acct_ctrl(pwd);
2910 ZERO_STRUCT(plaintext_buf);
2912 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2913 pdb_free_sam(&pwd);
2914 return False;
2917 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2918 pdb_free_sam(&pwd);
2919 return False;
2922 /* if it's a trust account, don't update /etc/passwd */
2923 if ( (!IS_SAM_UNIX_USER(pwd)) ||
2924 ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2925 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2926 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2927 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2928 } else {
2929 /* update the UNIX password */
2930 if (lp_unix_password_sync()) {
2931 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2932 pdb_free_sam(&pwd);
2933 return False;
2938 ZERO_STRUCT(plaintext_buf);
2940 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2942 /* update the SAMBA password */
2943 if(!pdb_update_sam_account(pwd)) {
2944 pdb_free_sam(&pwd);
2945 return False;
2948 pdb_free_sam(&pwd);
2950 return True;
2953 /*******************************************************************
2954 samr_reply_set_userinfo
2955 ********************************************************************/
2957 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2959 DOM_SID sid;
2960 POLICY_HND *pol = &q_u->pol;
2961 uint16 switch_value = q_u->switch_value;
2962 SAM_USERINFO_CTR *ctr = q_u->ctr;
2963 uint32 acc_granted;
2964 uint32 acc_required;
2966 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2968 r_u->status = NT_STATUS_OK;
2970 /* find the policy handle. open a policy on it. */
2971 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2972 return NT_STATUS_INVALID_HANDLE;
2974 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2975 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2976 return r_u->status;
2979 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2981 if (ctr == NULL) {
2982 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2983 return NT_STATUS_INVALID_INFO_CLASS;
2986 /* ok! user info levels (lots: see MSDEV help), off we go... */
2987 switch (switch_value) {
2988 case 0x12:
2989 if (!set_user_info_12(ctr->info.id12, &sid))
2990 return NT_STATUS_ACCESS_DENIED;
2991 break;
2993 case 24:
2994 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
2996 dump_data(100, (char *)ctr->info.id24->pass, 516);
2998 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2999 return NT_STATUS_ACCESS_DENIED;
3000 break;
3002 case 25:
3003 #if 0
3005 * Currently we don't really know how to unmarshall
3006 * the level 25 struct, and the password encryption
3007 * is different. This is a placeholder for when we
3008 * do understand it. In the meantime just return INVALID
3009 * info level and W2K SP2 drops down to level 23... JRA.
3012 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3014 dump_data(100, (char *)ctr->info.id25->pass, 532);
3016 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3017 return NT_STATUS_ACCESS_DENIED;
3018 break;
3019 #endif
3020 return NT_STATUS_INVALID_INFO_CLASS;
3022 case 23:
3023 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3025 dump_data(100, (char *)ctr->info.id23->pass, 516);
3027 if (!set_user_info_23(ctr->info.id23, &sid))
3028 return NT_STATUS_ACCESS_DENIED;
3029 break;
3031 default:
3032 return NT_STATUS_INVALID_INFO_CLASS;
3035 return r_u->status;
3038 /*******************************************************************
3039 samr_reply_set_userinfo2
3040 ********************************************************************/
3042 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3044 DOM_SID sid;
3045 SAM_USERINFO_CTR *ctr = q_u->ctr;
3046 POLICY_HND *pol = &q_u->pol;
3047 uint16 switch_value = q_u->switch_value;
3048 uint32 acc_granted;
3049 uint32 acc_required;
3051 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3053 r_u->status = NT_STATUS_OK;
3055 /* find the policy handle. open a policy on it. */
3056 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3057 return NT_STATUS_INVALID_HANDLE;
3059 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3060 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3061 return r_u->status;
3064 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3066 if (ctr == NULL) {
3067 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3068 return NT_STATUS_INVALID_INFO_CLASS;
3071 switch_value=ctr->switch_value;
3073 /* ok! user info levels (lots: see MSDEV help), off we go... */
3074 switch (switch_value) {
3075 case 21:
3076 if (!set_user_info_21(ctr->info.id21, &sid))
3077 return NT_STATUS_ACCESS_DENIED;
3078 break;
3079 case 16:
3080 if (!set_user_info_10(ctr->info.id10, &sid))
3081 return NT_STATUS_ACCESS_DENIED;
3082 break;
3083 case 18:
3084 /* Used by AS/U JRA. */
3085 if (!set_user_info_12(ctr->info.id12, &sid))
3086 return NT_STATUS_ACCESS_DENIED;
3087 break;
3088 default:
3089 return NT_STATUS_INVALID_INFO_CLASS;
3092 return r_u->status;
3095 /*********************************************************************
3096 _samr_query_aliasmem
3097 *********************************************************************/
3099 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3101 int num_groups = 0, tmp_num_groups=0;
3102 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3103 struct samr_info *info = NULL;
3104 int i,j;
3106 NTSTATUS ntstatus1;
3107 NTSTATUS ntstatus2;
3109 /* until i see a real useraliases query, we fack one up */
3111 /* I have seen one, JFM 2/12/2001 */
3113 * Explanation of what this call does:
3114 * for all the SID given in the request:
3115 * return a list of alias (local groups)
3116 * that have those SID as members.
3118 * and that's the alias in the domain specified
3119 * in the policy_handle
3121 * if the policy handle is on an incorrect sid
3122 * for example a user's sid
3123 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3126 r_u->status = NT_STATUS_OK;
3128 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3130 /* find the policy handle. open a policy on it. */
3131 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3132 return NT_STATUS_INVALID_HANDLE;
3134 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3135 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3137 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3138 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3139 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3140 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3144 if (!sid_check_is_domain(&info->sid) &&
3145 !sid_check_is_builtin(&info->sid))
3146 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3149 for (i=0; i<q_u->num_sids1; i++) {
3151 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3154 * if there is an error, we just continue as
3155 * it can be an unfound user or group
3157 if (!NT_STATUS_IS_OK(r_u->status)) {
3158 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3159 continue;
3162 if (tmp_num_groups==0) {
3163 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3164 continue;
3167 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3168 if (new_rids==NULL) {
3169 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3170 return NT_STATUS_NO_MEMORY;
3172 rids=new_rids;
3174 for (j=0; j<tmp_num_groups; j++)
3175 rids[j+num_groups]=tmp_rids[j];
3177 safe_free(tmp_rids);
3179 num_groups+=tmp_num_groups;
3182 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3183 return NT_STATUS_OK;
3186 /*********************************************************************
3187 _samr_query_aliasmem
3188 *********************************************************************/
3190 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3192 int i;
3194 GROUP_MAP map;
3195 int num_uids = 0;
3196 DOM_SID2 *sid;
3197 uid_t *uid=NULL;
3199 DOM_SID alias_sid;
3200 DOM_SID als_sid;
3201 uint32 alias_rid;
3202 fstring alias_sid_str;
3203 DOM_SID temp_sid;
3205 SAM_ACCOUNT *sam_user = NULL;
3206 BOOL check;
3207 uint32 acc_granted;
3209 /* find the policy handle. open a policy on it. */
3210 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3211 return NT_STATUS_INVALID_HANDLE;
3213 if (!NT_STATUS_IS_OK(r_u->status =
3214 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3215 return r_u->status;
3218 sid_copy(&als_sid, &alias_sid);
3219 sid_to_string(alias_sid_str, &alias_sid);
3220 sid_split_rid(&alias_sid, &alias_rid);
3222 DEBUG(10, ("sid is %s\n", alias_sid_str));
3224 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3225 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3226 if(!get_builtin_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3227 return NT_STATUS_NO_SUCH_ALIAS;
3228 } else {
3229 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3230 DEBUG(10, ("lookup on Server SID\n"));
3231 if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
3232 return NT_STATUS_NO_SUCH_ALIAS;
3236 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3237 return NT_STATUS_NO_SUCH_ALIAS;
3239 DEBUG(10, ("sid is %s\n", alias_sid_str));
3240 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3241 if (num_uids!=0 && sid == NULL)
3242 return NT_STATUS_NO_MEMORY;
3244 for (i = 0; i < num_uids; i++) {
3245 struct passwd *pass;
3246 uint32 rid;
3248 sid_copy(&temp_sid, get_global_sam_sid());
3250 pass = getpwuid_alloc(uid[i]);
3251 if (!pass) continue;
3253 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3254 passwd_free(&pass);
3255 continue;
3258 become_root();
3259 check = pdb_getsampwnam(sam_user, pass->pw_name);
3260 unbecome_root();
3262 if (check != True) {
3263 pdb_free_sam(&sam_user);
3264 passwd_free(&pass);
3265 continue;
3268 rid = pdb_get_user_rid(sam_user);
3269 if (rid == 0) {
3270 pdb_free_sam(&sam_user);
3271 passwd_free(&pass);
3272 continue;
3275 pdb_free_sam(&sam_user);
3276 passwd_free(&pass);
3278 sid_append_rid(&temp_sid, rid);
3280 init_dom_sid2(&sid[i], &temp_sid);
3283 DEBUG(10, ("sid is %s\n", alias_sid_str));
3284 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3286 return NT_STATUS_OK;
3289 /*********************************************************************
3290 _samr_query_groupmem
3291 *********************************************************************/
3293 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3295 int num_uids = 0;
3296 int i;
3297 DOM_SID group_sid;
3298 uint32 group_rid;
3299 fstring group_sid_str;
3300 uid_t *uid=NULL;
3302 GROUP_MAP map;
3304 uint32 *rid=NULL;
3305 uint32 *attr=NULL;
3307 SAM_ACCOUNT *sam_user = NULL;
3308 BOOL check;
3309 uint32 acc_granted;
3311 /* find the policy handle. open a policy on it. */
3312 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3313 return NT_STATUS_INVALID_HANDLE;
3315 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3316 return r_u->status;
3319 /* todo: change to use sid_compare_front */
3321 sid_split_rid(&group_sid, &group_rid);
3322 sid_to_string(group_sid_str, &group_sid);
3323 DEBUG(10, ("sid is %s\n", group_sid_str));
3325 /* can we get a query for an SID outside our domain ? */
3326 if (!sid_equal(&group_sid, get_global_sam_sid()))
3327 return NT_STATUS_NO_SUCH_GROUP;
3329 sid_append_rid(&group_sid, group_rid);
3330 DEBUG(10, ("lookup on Domain SID\n"));
3332 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3333 return NT_STATUS_NO_SUCH_GROUP;
3335 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3336 return NT_STATUS_NO_SUCH_GROUP;
3338 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3339 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3341 if (num_uids!=0 && (rid==NULL || attr==NULL))
3342 return NT_STATUS_NO_MEMORY;
3344 for (i=0; i<num_uids; i++) {
3345 struct passwd *pass;
3346 uint32 urid;
3348 pass = getpwuid_alloc(uid[i]);
3349 if (!pass) continue;
3351 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3352 passwd_free(&pass);
3353 continue;
3356 become_root();
3357 check = pdb_getsampwnam(sam_user, pass->pw_name);
3358 unbecome_root();
3360 if (check != True) {
3361 pdb_free_sam(&sam_user);
3362 passwd_free(&pass);
3363 continue;
3366 urid = pdb_get_user_rid(sam_user);
3367 if (urid == 0) {
3368 pdb_free_sam(&sam_user);
3369 passwd_free(&pass);
3370 continue;
3373 pdb_free_sam(&sam_user);
3374 passwd_free(&pass);
3376 rid[i] = urid;
3377 attr[i] = SID_NAME_USER;
3380 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3382 return NT_STATUS_OK;
3385 /*********************************************************************
3386 _samr_add_aliasmem
3387 *********************************************************************/
3389 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3391 DOM_SID alias_sid;
3392 fstring alias_sid_str;
3393 uid_t uid;
3394 struct passwd *pwd;
3395 struct group *grp;
3396 fstring grp_name;
3397 GROUP_MAP map;
3398 NTSTATUS ret;
3399 SAM_ACCOUNT *sam_user = NULL;
3400 BOOL check;
3401 uint32 acc_granted;
3403 /* Find the policy handle. Open a policy on it. */
3404 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3405 return NT_STATUS_INVALID_HANDLE;
3407 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3408 return r_u->status;
3411 sid_to_string(alias_sid_str, &alias_sid);
3412 DEBUG(10, ("sid is %s\n", alias_sid_str));
3414 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3415 DEBUG(10, ("adding member on Server SID\n"));
3416 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3417 return NT_STATUS_NO_SUCH_ALIAS;
3419 } else {
3420 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3421 DEBUG(10, ("adding member on BUILTIN SID\n"));
3422 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3423 return NT_STATUS_NO_SUCH_ALIAS;
3425 } else
3426 return NT_STATUS_NO_SUCH_ALIAS;
3429 ret = pdb_init_sam(&sam_user);
3430 if (!NT_STATUS_IS_OK(ret))
3431 return ret;
3433 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3435 if (check != True) {
3436 pdb_free_sam(&sam_user);
3437 return NT_STATUS_NO_SUCH_USER;
3440 uid = pdb_get_uid(sam_user);
3441 if (uid == -1) {
3442 pdb_free_sam(&sam_user);
3443 return NT_STATUS_NO_SUCH_USER;
3446 pdb_free_sam(&sam_user);
3448 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3449 return NT_STATUS_NO_SUCH_USER;
3452 if ((grp=getgrgid(map.gid)) == NULL) {
3453 passwd_free(&pwd);
3454 return NT_STATUS_NO_SUCH_ALIAS;
3457 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3458 fstrcpy(grp_name, grp->gr_name);
3460 /* if the user is already in the group */
3461 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3462 passwd_free(&pwd);
3463 return NT_STATUS_MEMBER_IN_ALIAS;
3467 * ok, the group exist, the user exist, the user is not in the group,
3468 * we can (finally) add it to the group !
3470 smb_add_user_group(grp_name, pwd->pw_name);
3472 /* check if the user has been added then ... */
3473 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3474 passwd_free(&pwd);
3475 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3478 passwd_free(&pwd);
3479 return NT_STATUS_OK;
3482 /*********************************************************************
3483 _samr_del_aliasmem
3484 *********************************************************************/
3486 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3488 DOM_SID alias_sid;
3489 fstring alias_sid_str;
3490 struct group *grp;
3491 fstring grp_name;
3492 GROUP_MAP map;
3493 SAM_ACCOUNT *sam_pass=NULL;
3494 uint32 acc_granted;
3496 /* Find the policy handle. Open a policy on it. */
3497 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3498 return NT_STATUS_INVALID_HANDLE;
3500 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3501 return r_u->status;
3504 sid_to_string(alias_sid_str, &alias_sid);
3505 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3507 if (!sid_check_is_in_our_domain(&alias_sid) &&
3508 !sid_check_is_in_builtin(&alias_sid)) {
3509 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3510 return NT_STATUS_NO_SUCH_ALIAS;
3513 if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3514 return NT_STATUS_NO_SUCH_ALIAS;
3516 if ((grp=getgrgid(map.gid)) == NULL)
3517 return NT_STATUS_NO_SUCH_ALIAS;
3519 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3520 fstrcpy(grp_name, grp->gr_name);
3522 /* check if the user exists before trying to remove it from the group */
3523 pdb_init_sam(&sam_pass);
3524 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3525 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3526 pdb_free_sam(&sam_pass);
3527 return NT_STATUS_NO_SUCH_USER;
3530 /* if the user is not in the group */
3531 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3532 pdb_free_sam(&sam_pass);
3533 return NT_STATUS_MEMBER_IN_ALIAS;
3536 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3538 /* check if the user has been removed then ... */
3539 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3540 pdb_free_sam(&sam_pass);
3541 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3544 pdb_free_sam(&sam_pass);
3545 return NT_STATUS_OK;
3548 /*********************************************************************
3549 _samr_add_groupmem
3550 *********************************************************************/
3552 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3554 DOM_SID group_sid;
3555 DOM_SID user_sid;
3556 fstring group_sid_str;
3557 struct passwd *pwd;
3558 struct group *grp;
3559 fstring grp_name;
3560 GROUP_MAP map;
3561 uid_t uid;
3562 NTSTATUS ret;
3563 SAM_ACCOUNT *sam_user=NULL;
3564 BOOL check;
3565 uint32 acc_granted;
3567 /* Find the policy handle. Open a policy on it. */
3568 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3569 return NT_STATUS_INVALID_HANDLE;
3571 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3572 return r_u->status;
3575 sid_to_string(group_sid_str, &group_sid);
3576 DEBUG(10, ("sid is %s\n", group_sid_str));
3578 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3579 return NT_STATUS_NO_SUCH_GROUP;
3581 DEBUG(10, ("lookup on Domain SID\n"));
3583 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3584 return NT_STATUS_NO_SUCH_GROUP;
3586 sid_copy(&user_sid, get_global_sam_sid());
3587 sid_append_rid(&user_sid, q_u->rid);
3589 ret = pdb_init_sam(&sam_user);
3590 if (!NT_STATUS_IS_OK(ret))
3591 return ret;
3593 check = pdb_getsampwsid(sam_user, &user_sid);
3595 if (check != True) {
3596 pdb_free_sam(&sam_user);
3597 return NT_STATUS_NO_SUCH_USER;
3600 uid = pdb_get_uid(sam_user);
3601 if (uid == -1) {
3602 pdb_free_sam(&sam_user);
3603 return NT_STATUS_NO_SUCH_USER;
3606 pdb_free_sam(&sam_user);
3608 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3609 return NT_STATUS_NO_SUCH_USER;
3612 if ((grp=getgrgid(map.gid)) == NULL) {
3613 passwd_free(&pwd);
3614 return NT_STATUS_NO_SUCH_GROUP;
3617 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3618 fstrcpy(grp_name, grp->gr_name);
3620 /* if the user is already in the group */
3621 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3622 passwd_free(&pwd);
3623 return NT_STATUS_MEMBER_IN_GROUP;
3627 * ok, the group exist, the user exist, the user is not in the group,
3629 * we can (finally) add it to the group !
3632 smb_add_user_group(grp_name, pwd->pw_name);
3634 /* check if the user has been added then ... */
3635 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3636 passwd_free(&pwd);
3637 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3640 passwd_free(&pwd);
3641 return NT_STATUS_OK;
3644 /*********************************************************************
3645 _samr_del_groupmem
3646 *********************************************************************/
3648 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3650 DOM_SID group_sid;
3651 DOM_SID user_sid;
3652 SAM_ACCOUNT *sam_pass=NULL;
3653 GROUP_MAP map;
3654 fstring grp_name;
3655 struct group *grp;
3656 uint32 acc_granted;
3659 * delete the group member named q_u->rid
3660 * who is a member of the sid associated with the handle
3661 * the rid is a user's rid as the group is a domain group.
3664 /* Find the policy handle. Open a policy on it. */
3665 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3666 return NT_STATUS_INVALID_HANDLE;
3668 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3669 return r_u->status;
3672 if (!sid_check_is_in_our_domain(&group_sid))
3673 return NT_STATUS_NO_SUCH_GROUP;
3675 sid_copy(&user_sid, get_global_sam_sid());
3676 sid_append_rid(&user_sid, q_u->rid);
3678 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3679 return NT_STATUS_NO_SUCH_GROUP;
3681 if ((grp=getgrgid(map.gid)) == NULL)
3682 return NT_STATUS_NO_SUCH_GROUP;
3684 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3685 fstrcpy(grp_name, grp->gr_name);
3687 /* check if the user exists before trying to remove it from the group */
3688 pdb_init_sam(&sam_pass);
3689 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3690 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3691 pdb_free_sam(&sam_pass);
3692 return NT_STATUS_NO_SUCH_USER;
3695 /* if the user is not in the group */
3696 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3697 pdb_free_sam(&sam_pass);
3698 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3701 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3703 /* check if the user has been removed then ... */
3704 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3705 pdb_free_sam(&sam_pass);
3706 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3709 pdb_free_sam(&sam_pass);
3710 return NT_STATUS_OK;
3714 /****************************************************************************
3715 Delete a UNIX user on demand.
3716 ****************************************************************************/
3718 static int smb_delete_user(const char *unix_user)
3720 pstring del_script;
3721 int ret;
3723 pstrcpy(del_script, lp_deluser_script());
3724 if (! *del_script)
3725 return -1;
3726 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3727 ret = smbrun(del_script,NULL);
3728 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3729 return ret;
3732 /*********************************************************************
3733 _samr_delete_dom_user
3734 *********************************************************************/
3736 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3738 DOM_SID user_sid;
3739 SAM_ACCOUNT *sam_pass=NULL;
3740 uint32 acc_granted;
3742 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3744 /* Find the policy handle. Open a policy on it. */
3745 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3746 return NT_STATUS_INVALID_HANDLE;
3748 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3749 return r_u->status;
3752 if (!sid_check_is_in_our_domain(&user_sid))
3753 return NT_STATUS_CANNOT_DELETE;
3755 /* check if the user exists before trying to delete */
3756 pdb_init_sam(&sam_pass);
3757 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3758 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3759 pdb_free_sam(&sam_pass);
3760 return NT_STATUS_NO_SUCH_USER;
3763 /* delete the unix side */
3765 * note: we don't check if the delete really happened
3766 * as the script is not necessary present
3767 * and maybe the sysadmin doesn't want to delete the unix side
3769 smb_delete_user(pdb_get_username(sam_pass));
3771 /* and delete the samba side */
3772 if (!pdb_delete_sam_account(sam_pass)) {
3773 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3774 pdb_free_sam(&sam_pass);
3775 return NT_STATUS_CANNOT_DELETE;
3778 pdb_free_sam(&sam_pass);
3780 if (!close_policy_hnd(p, &q_u->user_pol))
3781 return NT_STATUS_OBJECT_NAME_INVALID;
3783 return NT_STATUS_OK;
3786 /*********************************************************************
3787 _samr_delete_dom_group
3788 *********************************************************************/
3790 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3792 DOM_SID group_sid;
3793 DOM_SID dom_sid;
3794 uint32 group_rid;
3795 fstring group_sid_str;
3796 gid_t gid;
3797 struct group *grp;
3798 GROUP_MAP map;
3799 uint32 acc_granted;
3801 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3803 /* Find the policy handle. Open a policy on it. */
3804 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3805 return NT_STATUS_INVALID_HANDLE;
3807 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3808 return r_u->status;
3811 sid_copy(&dom_sid, &group_sid);
3812 sid_to_string(group_sid_str, &dom_sid);
3813 sid_split_rid(&dom_sid, &group_rid);
3815 DEBUG(10, ("sid is %s\n", group_sid_str));
3817 /* we check if it's our SID before deleting */
3818 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3819 return NT_STATUS_NO_SUCH_GROUP;
3821 DEBUG(10, ("lookup on Domain SID\n"));
3823 if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
3824 return NT_STATUS_NO_SUCH_GROUP;
3826 gid=map.gid;
3828 /* check if group really exists */
3829 if ( (grp=getgrgid(gid)) == NULL)
3830 return NT_STATUS_NO_SUCH_GROUP;
3832 /* we can delete the UNIX group */
3833 smb_delete_group(grp->gr_name);
3835 /* check if the group has been successfully deleted */
3836 if ( (grp=getgrgid(gid)) != NULL)
3837 return NT_STATUS_ACCESS_DENIED;
3839 if(!pdb_delete_group_mapping_entry(group_sid))
3840 return NT_STATUS_ACCESS_DENIED;
3842 if (!close_policy_hnd(p, &q_u->group_pol))
3843 return NT_STATUS_OBJECT_NAME_INVALID;
3845 return NT_STATUS_OK;
3848 /*********************************************************************
3849 _samr_delete_dom_alias
3850 *********************************************************************/
3852 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3854 DOM_SID alias_sid;
3855 DOM_SID dom_sid;
3856 uint32 alias_rid;
3857 fstring alias_sid_str;
3858 gid_t gid;
3859 struct group *grp;
3860 GROUP_MAP map;
3861 uint32 acc_granted;
3863 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3865 /* Find the policy handle. Open a policy on it. */
3866 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3867 return NT_STATUS_INVALID_HANDLE;
3869 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3870 return r_u->status;
3873 sid_copy(&dom_sid, &alias_sid);
3874 sid_to_string(alias_sid_str, &dom_sid);
3875 sid_split_rid(&dom_sid, &alias_rid);
3877 DEBUG(10, ("sid is %s\n", alias_sid_str));
3879 /* we check if it's our SID before deleting */
3880 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3881 return NT_STATUS_NO_SUCH_ALIAS;
3883 DEBUG(10, ("lookup on Local SID\n"));
3885 if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
3886 return NT_STATUS_NO_SUCH_ALIAS;
3888 gid=map.gid;
3890 /* check if group really exists */
3891 if ( (grp=getgrgid(gid)) == NULL)
3892 return NT_STATUS_NO_SUCH_ALIAS;
3894 /* we can delete the UNIX group */
3895 smb_delete_group(grp->gr_name);
3897 /* check if the group has been successfully deleted */
3898 if ( (grp=getgrgid(gid)) != NULL)
3899 return NT_STATUS_ACCESS_DENIED;
3901 /* don't check if we removed it as it could be an un-mapped group */
3902 pdb_delete_group_mapping_entry(alias_sid);
3904 if (!close_policy_hnd(p, &q_u->alias_pol))
3905 return NT_STATUS_OBJECT_NAME_INVALID;
3907 return NT_STATUS_OK;
3910 /*********************************************************************
3911 _samr_create_dom_group
3912 *********************************************************************/
3914 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3916 DOM_SID dom_sid;
3917 DOM_SID info_sid;
3918 fstring name;
3919 fstring sid_string;
3920 struct group *grp;
3921 struct samr_info *info;
3922 PRIVILEGE_SET priv_set;
3923 uint32 acc_granted;
3924 gid_t gid;
3926 init_privilege(&priv_set);
3928 /* Find the policy handle. Open a policy on it. */
3929 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3930 return NT_STATUS_INVALID_HANDLE;
3932 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3933 return r_u->status;
3936 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3937 return NT_STATUS_ACCESS_DENIED;
3939 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3941 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3943 /* check if group already exist */
3944 if ((grp=getgrnam(name)) != NULL)
3945 return NT_STATUS_GROUP_EXISTS;
3947 /* we can create the UNIX group */
3948 if (smb_create_group(name, &gid) != 0)
3949 return NT_STATUS_ACCESS_DENIED;
3951 /* check if the group has been successfully created */
3952 if ((grp=getgrgid(gid)) == NULL)
3953 return NT_STATUS_ACCESS_DENIED;
3955 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3957 /* add the group to the mapping table */
3958 sid_copy(&info_sid, get_global_sam_sid());
3959 sid_append_rid(&info_sid, r_u->rid);
3960 sid_to_string(sid_string, &info_sid);
3962 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
3963 return NT_STATUS_ACCESS_DENIED;
3965 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3966 return NT_STATUS_NO_MEMORY;
3968 /* get a (unique) handle. open a policy on it. */
3969 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3970 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3972 return NT_STATUS_OK;
3975 /*********************************************************************
3976 _samr_create_dom_alias
3977 *********************************************************************/
3979 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *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 PRIVILEGE_SET priv_set;
3988 uint32 acc_granted;
3989 gid_t gid;
3991 init_privilege(&priv_set);
3993 /* Find the policy handle. Open a policy on it. */
3994 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3995 return NT_STATUS_INVALID_HANDLE;
3997 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3998 return r_u->status;
4001 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4002 return NT_STATUS_ACCESS_DENIED;
4004 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4006 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4008 /* check if group already exists */
4009 if ( (grp=getgrnam(name)) != NULL)
4010 return NT_STATUS_GROUP_EXISTS;
4012 /* we can create the UNIX group */
4013 if (smb_create_group(name, &gid) != 0)
4014 return NT_STATUS_ACCESS_DENIED;
4016 /* check if the group has been successfully created */
4017 if ((grp=getgrgid(gid)) == NULL)
4018 return NT_STATUS_ACCESS_DENIED;
4020 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4022 sid_copy(&info_sid, get_global_sam_sid());
4023 sid_append_rid(&info_sid, r_u->rid);
4024 sid_to_string(sid_string, &info_sid);
4026 /* add the group to the mapping table */
4027 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
4028 return NT_STATUS_ACCESS_DENIED;
4030 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4031 return NT_STATUS_NO_MEMORY;
4033 /* get a (unique) handle. open a policy on it. */
4034 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4035 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4037 return NT_STATUS_OK;
4040 /*********************************************************************
4041 _samr_query_groupinfo
4043 sends the name/comment pair of a domain group
4044 level 1 send also the number of users of that group
4045 *********************************************************************/
4047 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4049 DOM_SID group_sid;
4050 GROUP_MAP map;
4051 uid_t *uid=NULL;
4052 int num_uids=0;
4053 GROUP_INFO_CTR *ctr;
4054 uint32 acc_granted;
4056 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4057 return NT_STATUS_INVALID_HANDLE;
4059 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4060 return r_u->status;
4063 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
4064 return NT_STATUS_INVALID_HANDLE;
4066 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4067 if (ctr==NULL)
4068 return NT_STATUS_NO_MEMORY;
4070 switch (q_u->switch_level) {
4071 case 1:
4072 ctr->switch_value1 = 1;
4073 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4074 return NT_STATUS_NO_SUCH_GROUP;
4075 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4076 SAFE_FREE(uid);
4077 break;
4078 case 3:
4079 ctr->switch_value1 = 3;
4080 init_samr_group_info3(&ctr->group.info3);
4081 break;
4082 case 4:
4083 ctr->switch_value1 = 4;
4084 init_samr_group_info4(&ctr->group.info4, map.comment);
4085 break;
4086 default:
4087 return NT_STATUS_INVALID_INFO_CLASS;
4090 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4092 return NT_STATUS_OK;
4095 /*********************************************************************
4096 _samr_set_groupinfo
4098 update a domain group's comment.
4099 *********************************************************************/
4101 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4103 DOM_SID group_sid;
4104 GROUP_MAP map;
4105 GROUP_INFO_CTR *ctr;
4106 uint32 acc_granted;
4108 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4109 return NT_STATUS_INVALID_HANDLE;
4111 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4112 return r_u->status;
4115 if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4116 return NT_STATUS_NO_SUCH_GROUP;
4118 ctr=q_u->ctr;
4120 switch (ctr->switch_value1) {
4121 case 1:
4122 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4123 break;
4124 case 4:
4125 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4126 break;
4127 default:
4128 free_privilege(&map.priv_set);
4129 return NT_STATUS_INVALID_INFO_CLASS;
4132 if(!pdb_update_group_mapping_entry(&map)) {
4133 free_privilege(&map.priv_set);
4134 return NT_STATUS_NO_SUCH_GROUP;
4137 free_privilege(&map.priv_set);
4139 return NT_STATUS_OK;
4142 /*********************************************************************
4143 _samr_set_aliasinfo
4145 update an alias's comment.
4146 *********************************************************************/
4148 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4150 DOM_SID group_sid;
4151 GROUP_MAP map;
4152 ALIAS_INFO_CTR *ctr;
4153 uint32 acc_granted;
4155 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4156 return NT_STATUS_INVALID_HANDLE;
4158 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4159 return r_u->status;
4162 if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
4163 return NT_STATUS_NO_SUCH_GROUP;
4165 ctr=&q_u->ctr;
4167 switch (ctr->switch_value1) {
4168 case 3:
4169 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4170 break;
4171 default:
4172 free_privilege(&map.priv_set);
4173 return NT_STATUS_INVALID_INFO_CLASS;
4176 if(!pdb_update_group_mapping_entry(&map)) {
4177 free_privilege(&map.priv_set);
4178 return NT_STATUS_NO_SUCH_GROUP;
4181 free_privilege(&map.priv_set);
4183 return NT_STATUS_OK;
4186 /*********************************************************************
4187 _samr_get_dom_pwinfo
4188 *********************************************************************/
4190 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4192 /* Perform access check. Since this rpc does not require a
4193 policy handle it will not be caught by the access checks on
4194 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4196 if (!pipe_access_check(p)) {
4197 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4198 r_u->status = NT_STATUS_ACCESS_DENIED;
4199 return r_u->status;
4202 /* Actually, returning zeros here works quite well :-). */
4204 return NT_STATUS_OK;
4207 /*********************************************************************
4208 _samr_open_group
4209 *********************************************************************/
4211 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4213 DOM_SID sid;
4214 DOM_SID info_sid;
4215 GROUP_MAP map;
4216 struct samr_info *info;
4217 SEC_DESC *psd = NULL;
4218 uint32 acc_granted;
4219 uint32 des_access;
4220 size_t sd_size;
4221 NTSTATUS status;
4222 fstring sid_string;
4224 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4225 return NT_STATUS_INVALID_HANDLE;
4227 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4228 return status;
4231 /*check if access can be granted as requested by client. */
4232 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4233 se_map_generic(&des_access,&grp_generic_mapping);
4234 if (!NT_STATUS_IS_OK(status =
4235 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4236 des_access, &acc_granted, "_samr_open_group"))) {
4237 return status;
4241 /* this should not be hard-coded like this */
4242 if (!sid_equal(&sid, get_global_sam_sid()))
4243 return NT_STATUS_ACCESS_DENIED;
4245 sid_copy(&info_sid, get_global_sam_sid());
4246 sid_append_rid(&info_sid, q_u->rid_group);
4247 sid_to_string(sid_string, &info_sid);
4249 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4250 return NT_STATUS_NO_MEMORY;
4252 info->acc_granted = acc_granted;
4254 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4256 /* check if that group really exists */
4257 if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
4258 return NT_STATUS_NO_SUCH_GROUP;
4260 /* get a (unique) handle. open a policy on it. */
4261 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4262 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4264 return NT_STATUS_OK;
4267 /*********************************************************************
4268 _samr_unknown_2d
4269 *********************************************************************/
4271 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4273 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4274 return NT_STATUS_NOT_IMPLEMENTED;
4277 /*******************************************************************
4278 _samr_unknown_2e
4279 ********************************************************************/
4281 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4283 struct samr_info *info = NULL;
4284 SAM_UNK_CTR *ctr;
4285 uint32 min_pass_len,pass_hist,flag;
4286 time_t u_expire, u_min_age;
4287 NTTIME nt_expire, nt_min_age;
4289 time_t u_lock_duration, u_reset_time;
4290 NTTIME nt_lock_duration, nt_reset_time;
4291 uint32 lockout;
4293 time_t u_logout;
4294 NTTIME nt_logout;
4296 uint32 num_users=0, num_groups=0, num_aliases=0;
4298 uint32 account_policy_temp;
4300 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4301 return NT_STATUS_NO_MEMORY;
4303 ZERO_STRUCTP(ctr);
4305 r_u->status = NT_STATUS_OK;
4307 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4309 /* find the policy handle. open a policy on it. */
4310 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4311 return NT_STATUS_INVALID_HANDLE;
4313 switch (q_u->switch_value) {
4314 case 0x01:
4315 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4316 min_pass_len = account_policy_temp;
4318 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4319 pass_hist = account_policy_temp;
4321 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4322 flag = account_policy_temp;
4324 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4325 u_expire = account_policy_temp;
4327 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4328 u_min_age = account_policy_temp;
4330 unix_to_nt_time_abs(&nt_expire, u_expire);
4331 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4333 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4334 flag, nt_expire, nt_min_age);
4335 break;
4336 case 0x02:
4337 become_root();
4338 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4339 unbecome_root();
4340 if (!NT_STATUS_IS_OK(r_u->status)) {
4341 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4342 return r_u->status;
4344 num_users=info->disp_info.num_user_account;
4345 free_samr_db(info);
4347 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4348 if (NT_STATUS_IS_ERR(r_u->status)) {
4349 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4350 return r_u->status;
4352 num_groups=info->disp_info.num_group_account;
4353 free_samr_db(info);
4355 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4356 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4357 num_users, num_groups, num_aliases);
4358 break;
4359 case 0x03:
4360 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4361 u_logout = account_policy_temp;
4363 unix_to_nt_time_abs(&nt_logout, u_logout);
4365 init_unk_info3(&ctr->info.inf3, nt_logout);
4366 break;
4367 case 0x05:
4368 init_unk_info5(&ctr->info.inf5, global_myname());
4369 break;
4370 case 0x06:
4371 init_unk_info6(&ctr->info.inf6);
4372 break;
4373 case 0x07:
4374 init_unk_info7(&ctr->info.inf7);
4375 break;
4376 case 0x0c:
4377 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4378 u_lock_duration = account_policy_temp;
4380 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4381 u_reset_time = account_policy_temp;
4383 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4384 lockout = account_policy_temp;
4386 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4387 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4389 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4390 break;
4391 default:
4392 return NT_STATUS_INVALID_INFO_CLASS;
4395 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4397 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4399 return r_u->status;
4402 /*******************************************************************
4403 _samr_
4404 ********************************************************************/
4406 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4408 time_t u_expire, u_min_age;
4409 time_t u_logout;
4410 time_t u_lock_duration, u_reset_time;
4412 r_u->status = NT_STATUS_OK;
4414 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4416 /* find the policy handle. open a policy on it. */
4417 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4418 return NT_STATUS_INVALID_HANDLE;
4420 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4422 switch (q_u->switch_value) {
4423 case 0x01:
4424 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4425 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4427 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4428 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4429 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4430 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4431 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4432 break;
4433 case 0x02:
4434 break;
4435 case 0x03:
4436 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4437 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4438 break;
4439 case 0x05:
4440 break;
4441 case 0x06:
4442 break;
4443 case 0x07:
4444 break;
4445 case 0x0c:
4446 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4447 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4449 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4450 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4451 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4452 break;
4453 default:
4454 return NT_STATUS_INVALID_INFO_CLASS;
4457 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4459 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4461 return r_u->status;