Only set sids when they're retrurned by the MySQL query
[Samba/gebeck_regimport.git] / source / rpc_server / srv_samr_nt.c
blob7f7b5e8d5e4ead371d9250771869ee3db7006bea
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997,
7 * Copyright (C) Marc Jacobsen 1999,
8 * Copyright (C) Jeremy Allison 2001-2002,
9 * Copyright (C) Jean François Micouleau 1998-2001,
10 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002.
11 * Copyright (C) Gerald (Jerry) Carter 2003.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * This is the implementation of the SAMR code.
32 #include "includes.h"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
44 typedef struct _disp_info {
45 BOOL user_dbloaded;
46 uint32 num_user_account;
47 SAM_ACCOUNT *disp_user_info;
48 BOOL group_dbloaded;
49 uint32 num_group_account;
50 DOMAIN_GRP *disp_group_info;
51 } DISP_INFO;
53 struct samr_info {
54 /* for use by the \PIPE\samr policy */
55 DOM_SID sid;
56 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
57 uint32 acc_granted;
58 uint16 acb_mask;
59 BOOL all_machines;
60 DISP_INFO disp_info;
62 TALLOC_CTX *mem_ctx;
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
79 uint32 *acc_granted, const char *debug)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
83 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84 *acc_granted = des_access;
85 if (geteuid() == sec_initial_uid()) {
86 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
87 debug, des_access));
88 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89 status = NT_STATUS_OK;
91 else {
92 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
93 debug, des_access));
96 return status;
99 /*******************************************************************
100 Checks if access to a function can be granted
101 ********************************************************************/
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
105 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
106 debug, acc_granted, acc_required));
107 if ((acc_granted & acc_required) != acc_required) {
108 if (geteuid() == sec_initial_uid()) {
109 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
110 debug, acc_granted, acc_required));
111 DEBUGADD(4,("but overwritten by euid == 0\n"));
112 return NT_STATUS_OK;
114 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
115 debug, acc_granted, acc_required));
116 return NT_STATUS_ACCESS_DENIED;
118 return NT_STATUS_OK;
122 /*******************************************************************
123 Create a samr_info struct.
124 ********************************************************************/
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
128 struct samr_info *info;
129 fstring sid_str;
130 TALLOC_CTX *mem_ctx;
132 if (psid) {
133 sid_to_string(sid_str, psid);
134 } else {
135 fstrcpy(sid_str,"(NULL)");
138 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
140 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
141 return NULL;
143 ZERO_STRUCTP(info);
144 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
145 if (psid) {
146 sid_copy( &info->sid, psid);
147 } else {
148 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
150 info->mem_ctx = mem_ctx;
151 return info;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
158 static void free_samr_users(struct samr_info *info)
160 int i;
162 if (info->disp_info.user_dbloaded){
163 for (i=0; i<info->disp_info.num_user_account; i++) {
164 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165 /* Not really a free, actually a 'clear' */
166 pdb_free_sam(&sam);
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
187 static void free_samr_info(void *ptr)
189 struct samr_info *info=(struct samr_info *) ptr;
191 free_samr_db(info);
192 talloc_destroy(info->mem_ctx);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
202 if (!sam_pass)
203 return;
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
214 SAM_ACCOUNT *pwd = NULL;
215 SAM_ACCOUNT *pwd_array = NULL;
216 NTSTATUS nt_status = NT_STATUS_OK;
217 TALLOC_CTX *mem_ctx = info->mem_ctx;
219 DEBUG(10,("load_sampwd_entries\n"));
221 /* if the snapshoot is already loaded, return */
222 if ((info->disp_info.user_dbloaded==True)
223 && (info->acb_mask == acb_mask)
224 && (info->all_machines == all_machines)) {
225 DEBUG(10,("load_sampwd_entries: already in memory\n"));
226 return NT_STATUS_OK;
229 free_samr_users(info);
231 if (!pdb_setsampwent(False)) {
232 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233 return NT_STATUS_ACCESS_DENIED;
236 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
237 && pdb_getsampwent(pwd) == True; pwd=NULL) {
239 if (all_machines) {
240 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
241 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
243 pdb_free_sam(&pwd);
244 continue;
246 } else {
247 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
248 pdb_free_sam(&pwd);
249 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
250 continue;
254 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
257 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258 pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
259 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
261 if (pwd_array==NULL)
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* Copy the SAM_ACCOUNT into the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
270 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
272 info->disp_info.num_user_account++;
275 pdb_endsampwent();
277 /* the snapshoot is in memory, we're ready to enumerate fast */
279 info->acb_mask = acb_mask;
280 info->all_machines = all_machines;
281 info->disp_info.user_dbloaded=True;
283 DEBUG(10,("load_sampwd_entries: done\n"));
285 return nt_status;
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
290 GROUP_MAP *map=NULL;
291 DOMAIN_GRP *grp_array = NULL;
292 uint32 group_entries = 0;
293 uint32 i;
294 TALLOC_CTX *mem_ctx = info->mem_ctx;
296 DEBUG(10,("load_group_domain_entries\n"));
298 /* if the snapshoot is already loaded, return */
299 if (info->disp_info.group_dbloaded==True) {
300 DEBUG(10,("load_group_domain_entries: already in memory\n"));
301 return NT_STATUS_OK;
305 become_root();
307 if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED)) {
308 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
309 return NT_STATUS_NO_MEMORY;
312 unbecome_root();
314 info->disp_info.num_group_account=group_entries;
316 grp_array=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
317 if (group_entries!=0 && grp_array==NULL) {
318 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
319 SAFE_FREE(map);
320 return NT_STATUS_NO_MEMORY;
323 info->disp_info.disp_group_info=grp_array;
325 for (i=0; i<group_entries; i++) {
326 fstrcpy(grp_array[i].name, map[i].nt_name);
327 fstrcpy(grp_array[i].comment, map[i].comment);
328 sid_split_rid(&map[i].sid, &grp_array[i].rid);
329 grp_array[i].attr=SID_NAME_DOM_GRP;
332 SAFE_FREE(map);
334 /* the snapshoot is in memory, we're ready to enumerate fast */
336 info->disp_info.group_dbloaded=True;
338 DEBUG(10,("load_group_domain_entries: done\n"));
340 return NT_STATUS_OK;
344 /*******************************************************************
345 _samr_close_hnd
346 ********************************************************************/
348 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
350 r_u->status = NT_STATUS_OK;
352 /* close the policy handle */
353 if (!close_policy_hnd(p, &q_u->pol))
354 return NT_STATUS_OBJECT_NAME_INVALID;
356 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
358 return r_u->status;
361 /*******************************************************************
362 samr_reply_open_domain
363 ********************************************************************/
365 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
367 struct samr_info *info;
368 SEC_DESC *psd = NULL;
369 uint32 acc_granted;
370 uint32 des_access = q_u->flags;
371 size_t sd_size;
372 NTSTATUS status;
374 r_u->status = NT_STATUS_OK;
376 /* find the connection policy handle. */
377 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
378 return NT_STATUS_INVALID_HANDLE;
380 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
381 return status;
384 /*check if access can be granted as requested by client. */
385 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
386 se_map_generic(&des_access,&dom_generic_mapping);
388 if (!NT_STATUS_IS_OK(status =
389 access_check_samr_object(psd, p->pipe_user.nt_user_token,
390 des_access, &acc_granted, "_samr_open_domain"))) {
391 return status;
394 /* associate the domain SID with the (unique) handle. */
395 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
396 return NT_STATUS_NO_MEMORY;
397 info->acc_granted = acc_granted;
399 /* get a (unique) handle. open a policy on it. */
400 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
401 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
403 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
405 return r_u->status;
408 /*******************************************************************
409 _samr_get_usrdom_pwinfo
410 ********************************************************************/
412 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
414 struct samr_info *info = NULL;
416 r_u->status = NT_STATUS_OK;
418 /* find the policy handle. open a policy on it. */
419 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
420 return NT_STATUS_INVALID_HANDLE;
422 if (!sid_check_is_in_our_domain(&info->sid))
423 return NT_STATUS_OBJECT_TYPE_MISMATCH;
425 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
427 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
430 * NT sometimes return NT_STATUS_ACCESS_DENIED
431 * I don't know yet why.
434 return r_u->status;
437 /*******************************************************************
438 samr_make_dom_obj_sd
439 ********************************************************************/
441 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
443 extern DOM_SID global_sid_World;
444 DOM_SID adm_sid;
445 DOM_SID act_sid;
447 SEC_ACE ace[3];
448 SEC_ACCESS mask;
450 SEC_ACL *psa = NULL;
452 sid_copy(&adm_sid, &global_sid_Builtin);
453 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
455 sid_copy(&act_sid, &global_sid_Builtin);
456 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
458 /*basic access for every one*/
459 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
460 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
462 /*full access for builtin aliases Administrators and Account Operators*/
463 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
464 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
465 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
467 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
468 return NT_STATUS_NO_MEMORY;
470 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
471 return NT_STATUS_NO_MEMORY;
473 return NT_STATUS_OK;
476 /*******************************************************************
477 samr_make_usr_obj_sd
478 ********************************************************************/
480 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
482 extern DOM_SID global_sid_World;
483 DOM_SID adm_sid;
484 DOM_SID act_sid;
486 SEC_ACE ace[4];
487 SEC_ACCESS mask;
489 SEC_ACL *psa = NULL;
491 sid_copy(&adm_sid, &global_sid_Builtin);
492 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
494 sid_copy(&act_sid, &global_sid_Builtin);
495 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
497 /*basic access for every one*/
498 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
499 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
501 /*full access for builtin aliases Administrators and Account Operators*/
502 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
503 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
504 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
506 /*extended access for the user*/
507 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
508 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
510 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
511 return NT_STATUS_NO_MEMORY;
513 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
514 return NT_STATUS_NO_MEMORY;
516 return NT_STATUS_OK;
519 /*******************************************************************
520 samr_make_grp_obj_sd
521 ********************************************************************/
523 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
525 extern DOM_SID global_sid_World;
526 DOM_SID adm_sid;
527 DOM_SID act_sid;
529 SEC_ACE ace[3];
530 SEC_ACCESS mask;
532 SEC_ACL *psa = NULL;
534 sid_copy(&adm_sid, &global_sid_Builtin);
535 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
537 sid_copy(&act_sid, &global_sid_Builtin);
538 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
540 /*basic access for every one*/
541 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
542 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
544 /*full access for builtin aliases Administrators and Account Operators*/
545 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
546 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
547 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
549 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
550 return NT_STATUS_NO_MEMORY;
552 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
553 return NT_STATUS_NO_MEMORY;
555 return NT_STATUS_OK;
558 /*******************************************************************
559 samr_make_ali_obj_sd
560 ********************************************************************/
562 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
564 extern DOM_SID global_sid_World;
565 DOM_SID adm_sid;
566 DOM_SID act_sid;
568 SEC_ACE ace[3];
569 SEC_ACCESS mask;
571 SEC_ACL *psa = NULL;
573 sid_copy(&adm_sid, &global_sid_Builtin);
574 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
576 sid_copy(&act_sid, &global_sid_Builtin);
577 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
579 /*basic access for every one*/
580 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
581 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
583 /*full access for builtin aliases Administrators and Account Operators*/
584 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
585 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
588 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
589 return NT_STATUS_NO_MEMORY;
591 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
592 return NT_STATUS_NO_MEMORY;
594 return NT_STATUS_OK;
597 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
599 struct samr_info *info = NULL;
601 /* find the policy handle. open a policy on it. */
602 if (!find_policy_by_hnd(p, pol, (void **)&info))
603 return False;
605 if (!info)
606 return False;
608 *sid = info->sid;
609 *acc_granted = info->acc_granted;
610 return True;
613 /*******************************************************************
614 _samr_set_sec_obj
615 ********************************************************************/
617 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
619 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
620 return NT_STATUS_NOT_IMPLEMENTED;
624 /*******************************************************************
625 _samr_query_sec_obj
626 ********************************************************************/
628 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
630 DOM_SID pol_sid;
631 fstring str_sid;
632 SEC_DESC * psd = NULL;
633 size_t sd_size;
634 uint32 acc_granted;
636 r_u->status = NT_STATUS_OK;
638 /* Get the SID. */
639 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
640 return NT_STATUS_INVALID_HANDLE;
644 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
646 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
648 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
649 if (pol_sid.sid_rev_num == 0)
651 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
652 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
654 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
657 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
658 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
660 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
662 /* TODO: Builtin probably needs a different SD with restricted write access*/
663 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
664 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
666 else if (sid_check_is_in_our_domain(&pol_sid) ||
667 sid_check_is_in_builtin(&pol_sid))
669 /* TODO: different SDs have to be generated for aliases groups and users.
670 Currently all three get a default user SD */
671 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
672 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
674 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
676 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
677 return NT_STATUS_NO_MEMORY;
679 if (NT_STATUS_IS_OK(r_u->status))
680 r_u->ptr = 1;
682 return r_u->status;
685 /*******************************************************************
686 makes a SAM_ENTRY / UNISTR2* structure from a user list.
687 ********************************************************************/
689 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
690 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
691 DOM_SID *domain_sid)
693 uint32 i;
694 SAM_ENTRY *sam;
695 UNISTR2 *uni_name;
696 SAM_ACCOUNT *pwd = NULL;
697 UNISTR2 uni_temp_name;
698 const char *temp_name;
699 const DOM_SID *user_sid;
700 uint32 user_rid;
701 fstring user_sid_string;
702 fstring domain_sid_string;
704 *sam_pp = NULL;
705 *uni_name_pp = NULL;
707 if (num_entries == 0)
708 return NT_STATUS_OK;
710 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
712 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
714 if (sam == NULL || uni_name == NULL) {
715 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
716 return NT_STATUS_NO_MEMORY;
719 for (i = 0; i < num_entries; i++) {
720 pwd = &disp_user_info[i+start_idx];
721 temp_name = pdb_get_username(pwd);
722 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
723 user_sid = pdb_get_user_sid(pwd);
725 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
726 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
727 "the domain sid %s. Failing operation.\n",
728 temp_name,
729 sid_to_string(user_sid_string, user_sid),
730 sid_to_string(domain_sid_string, domain_sid)));
731 return NT_STATUS_UNSUCCESSFUL;
734 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
735 copy_unistr2(&uni_name[i], &uni_temp_name);
738 *sam_pp = sam;
739 *uni_name_pp = uni_name;
740 return NT_STATUS_OK;
743 /*******************************************************************
744 samr_reply_enum_dom_users
745 ********************************************************************/
747 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
748 SAMR_R_ENUM_DOM_USERS *r_u)
750 struct samr_info *info = NULL;
751 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
752 int num_account;
753 uint32 enum_context=q_u->start_idx;
754 uint32 max_size=q_u->max_size;
755 uint32 temp_size;
756 enum remote_arch_types ra_type = get_remote_arch();
757 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
758 uint32 max_entries = max_sam_entries;
759 DOM_SID domain_sid;
761 r_u->status = NT_STATUS_OK;
763 /* find the policy handle. open a policy on it. */
764 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
765 return NT_STATUS_INVALID_HANDLE;
767 domain_sid = info->sid;
769 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
770 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
771 "_samr_enum_dom_users"))) {
772 return r_u->status;
775 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
777 become_root();
778 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
779 unbecome_root();
781 if (!NT_STATUS_IS_OK(r_u->status))
782 return r_u->status;
784 num_account = info->disp_info.num_user_account;
786 if (enum_context > num_account) {
787 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
788 return NT_STATUS_OK;
791 /* verify we won't overflow */
792 if (max_entries > num_account-enum_context) {
793 max_entries = num_account-enum_context;
794 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
797 /* calculate the size and limit on the number of entries we will return */
798 temp_size=max_entries*struct_size;
800 if (temp_size>max_size) {
801 max_entries=MIN((max_size/struct_size),max_entries);;
802 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
806 * Note from JRA. total_entries is not being used here. Currently if there is a
807 * large user base then it looks like NT will enumerate until get_sampwd_entries
808 * returns False due to num_entries being zero. This will cause an access denied
809 * return. I don't think this is right and needs further investigation. Note that
810 * this is also the same in the TNG code (I don't think that has been tested with
811 * a very large user list as MAX_SAM_ENTRIES is set to 600).
813 * I also think that one of the 'num_entries' return parameters is probably
814 * the "max entries" parameter - but in the TNG code they're all currently set to the same
815 * value (again I think this is wrong).
818 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
819 max_entries, enum_context,
820 info->disp_info.disp_user_info,
821 &domain_sid);
823 if (!NT_STATUS_IS_OK(r_u->status))
824 return r_u->status;
826 if (enum_context+max_entries < num_account)
827 r_u->status = STATUS_MORE_ENTRIES;
829 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
831 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
833 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
835 return r_u->status;
838 /*******************************************************************
839 makes a SAM_ENTRY / UNISTR2* structure from a group list.
840 ********************************************************************/
842 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
843 uint32 num_sam_entries, DOMAIN_GRP *grp)
845 uint32 i;
846 SAM_ENTRY *sam;
847 UNISTR2 *uni_name;
849 *sam_pp = NULL;
850 *uni_name_pp = NULL;
852 if (num_sam_entries == 0)
853 return;
855 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
857 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
859 if (sam == NULL || uni_name == NULL) {
860 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
861 return;
864 for (i = 0; i < num_sam_entries; i++) {
866 * JRA. I think this should include the null. TNG does not.
868 int len = strlen(grp[i].name)+1;
870 init_sam_entry(&sam[i], len, grp[i].rid);
871 init_unistr2(&uni_name[i], grp[i].name, len);
874 *sam_pp = sam;
875 *uni_name_pp = uni_name;
878 /*******************************************************************
879 Get the group entries - similar to get_sampwd_entries().
880 ********************************************************************/
882 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
883 uint32 *p_num_entries, uint32 max_entries)
885 fstring sid_str;
886 uint32 num_entries = 0;
887 int i;
888 GROUP_MAP smap;
889 GROUP_MAP *map = NULL;
891 sid_to_string(sid_str, sid);
892 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
894 *p_num_entries = 0;
896 /* well-known aliases */
897 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
899 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED);
901 if (num_entries != 0) {
902 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
903 if (*d_grp==NULL)
904 return NT_STATUS_NO_MEMORY;
906 for(i=0; i<num_entries && i<max_entries; i++) {
907 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
908 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
912 SAFE_FREE(map);
914 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
915 struct sys_grent *glist;
916 struct sys_grent *grp;
917 gid_t winbind_gid_low, winbind_gid_high;
918 BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
920 /* local aliases */
921 /* we return the UNIX groups here. This seems to be the right */
922 /* thing to do, since NT member servers return their local */
923 /* groups in the same situation. */
925 /* use getgrent_list() to retrieve the list of groups to avoid
926 * problems with getgrent possible infinite loop by internal
927 * libc grent structures overwrites by called functions */
928 grp = glist = getgrent_list();
929 if (grp == NULL)
930 return NT_STATUS_NO_MEMORY;
932 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
933 uint32 trid;
935 if(!pdb_getgrgid(&smap, grp->gr_gid))
936 continue;
938 if (smap.sid_name_use!=SID_NAME_ALIAS) {
939 continue;
942 sid_split_rid(&smap.sid, &trid);
944 if (!sid_equal(sid, &smap.sid))
945 continue;
947 /* Don't return winbind groups as they are not local! */
948 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
949 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
950 continue;
953 /* Don't return user private groups... */
955 if (Get_Pwnam(smap.nt_name) != 0) {
956 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
957 continue;
960 for( i = 0; i < num_entries; i++)
961 if ( (*d_grp)[i].rid == trid )
962 break;
964 if ( i < num_entries ) {
965 continue; /* rid was there, dup! */
968 /* JRA - added this for large group db enumeration... */
970 if (start_idx > 0) {
971 /* skip the requested number of entries.
972 not very efficient, but hey...
974 start_idx--;
975 continue;
978 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
979 if (*d_grp==NULL) {
980 grent_free(glist);
981 return NT_STATUS_NO_MEMORY;
984 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
985 (*d_grp)[num_entries].rid = trid;
986 num_entries++;
987 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
990 grent_free(glist);
993 *p_num_entries = num_entries;
995 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
997 if (num_entries >= max_entries)
998 return STATUS_MORE_ENTRIES;
999 return NT_STATUS_OK;
1002 /*******************************************************************
1003 Get the group entries - similar to get_sampwd_entries().
1004 ********************************************************************/
1006 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1007 uint32 *p_num_entries, uint32 max_entries)
1009 GROUP_MAP *map=NULL;
1010 int i;
1011 uint32 group_entries = 0;
1012 uint32 num_entries = 0;
1014 *p_num_entries = 0;
1016 /* access checks for the users were performed higher up. become/unbecome_root()
1017 needed for some passdb backends to enumerate groups */
1019 become_root();
1020 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
1021 unbecome_root();
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 ********************************************************************/
1132 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1133 SAMR_R_QUERY_DISPINFO *r_u)
1135 struct samr_info *info = NULL;
1136 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1138 uint32 max_entries=q_u->max_entries;
1139 uint32 enum_context=q_u->start_idx;
1140 uint32 max_size=q_u->max_size;
1142 SAM_DISPINFO_CTR *ctr;
1143 uint32 temp_size=0, total_data_size=0;
1144 NTSTATUS disp_ret;
1145 uint32 num_account = 0;
1146 enum remote_arch_types ra_type = get_remote_arch();
1147 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1148 DOM_SID domain_sid;
1150 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1151 r_u->status = NT_STATUS_OK;
1153 /* find the policy handle. open a policy on it. */
1154 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1155 return NT_STATUS_INVALID_HANDLE;
1157 domain_sid = info->sid;
1160 * calculate how many entries we will return.
1161 * based on
1162 * - the number of entries the client asked
1163 * - our limit on that
1164 * - the starting point (enumeration context)
1165 * - the buffer size the client will accept
1169 * We are a lot more like W2K. Instead of reading the SAM
1170 * each time to find the records we need to send back,
1171 * we read it once and link that copy to the sam handle.
1172 * For large user list (over the MAX_SAM_ENTRIES)
1173 * it's a definitive win.
1174 * second point to notice: between enumerations
1175 * our sam is now the same as it's a snapshoot.
1176 * third point: got rid of the static SAM_USER_21 struct
1177 * no more intermediate.
1178 * con: it uses much more memory, as a full copy is stored
1179 * in memory.
1181 * If you want to change it, think twice and think
1182 * of the second point , that's really important.
1184 * JFM, 12/20/2001
1187 /* Get what we need from the password database */
1188 switch (q_u->switch_level) {
1189 case 0x1:
1190 /* When playing with usrmgr, this is necessary
1191 if you want immediate refresh after editing
1192 a user. I would like to do this after the
1193 setuserinfo2, but we do not have access to
1194 the domain handle in that call, only to the
1195 user handle. Where else does this hurt?
1196 -- Volker
1198 #if 0
1199 /* We cannot do this here - it kills performace. JRA. */
1200 free_samr_users(info);
1201 #endif
1202 case 0x2:
1203 case 0x4:
1204 become_root();
1205 /* Level 2 is for all machines, otherwise only 'normal' users */
1206 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1207 unbecome_root();
1208 if (!NT_STATUS_IS_OK(r_u->status)) {
1209 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1210 return r_u->status;
1212 num_account = info->disp_info.num_user_account;
1213 break;
1214 case 0x3:
1215 case 0x5:
1216 r_u->status = load_group_domain_entries(info, &info->sid);
1217 if (!NT_STATUS_IS_OK(r_u->status))
1218 return r_u->status;
1219 num_account = info->disp_info.num_group_account;
1220 break;
1221 default:
1222 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1223 return NT_STATUS_INVALID_INFO_CLASS;
1226 /* first limit the number of entries we will return */
1227 if(max_entries > max_sam_entries) {
1228 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1229 max_entries = max_sam_entries;
1232 if (enum_context > num_account) {
1233 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1234 return NT_STATUS_NO_MORE_ENTRIES;
1237 /* verify we won't overflow */
1238 if (max_entries > num_account-enum_context) {
1239 max_entries = num_account-enum_context;
1240 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1243 /* calculate the size and limit on the number of entries we will return */
1244 temp_size=max_entries*struct_size;
1246 if (temp_size>max_size) {
1247 max_entries=MIN((max_size/struct_size),max_entries);;
1248 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1251 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1252 return NT_STATUS_NO_MEMORY;
1254 ZERO_STRUCTP(ctr);
1256 /* Now create reply structure */
1257 switch (q_u->switch_level) {
1258 case 0x1:
1259 if (max_entries) {
1260 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1261 return NT_STATUS_NO_MEMORY;
1263 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1264 info->disp_info.disp_user_info, &domain_sid);
1265 if (!NT_STATUS_IS_OK(disp_ret))
1266 return disp_ret;
1267 break;
1268 case 0x2:
1269 if (max_entries) {
1270 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1271 return NT_STATUS_NO_MEMORY;
1273 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1274 info->disp_info.disp_user_info, &domain_sid);
1275 if (!NT_STATUS_IS_OK(disp_ret))
1276 return disp_ret;
1277 break;
1278 case 0x3:
1279 if (max_entries) {
1280 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1281 return NT_STATUS_NO_MEMORY;
1283 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1284 if (!NT_STATUS_IS_OK(disp_ret))
1285 return disp_ret;
1286 break;
1287 case 0x4:
1288 if (max_entries) {
1289 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1290 return NT_STATUS_NO_MEMORY;
1292 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1293 if (!NT_STATUS_IS_OK(disp_ret))
1294 return disp_ret;
1295 break;
1296 case 0x5:
1297 if (max_entries) {
1298 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1299 return NT_STATUS_NO_MEMORY;
1301 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1302 if (!NT_STATUS_IS_OK(disp_ret))
1303 return disp_ret;
1304 break;
1306 default:
1307 ctr->sam.info = NULL;
1308 return NT_STATUS_INVALID_INFO_CLASS;
1311 /* calculate the total size */
1312 total_data_size=num_account*struct_size;
1314 if (enum_context+max_entries < num_account)
1315 r_u->status = STATUS_MORE_ENTRIES;
1317 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1319 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1321 return r_u->status;
1325 /*******************************************************************
1326 samr_reply_query_aliasinfo
1327 ********************************************************************/
1329 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1331 DOM_SID sid;
1332 GROUP_MAP map;
1333 uint32 acc_granted;
1335 r_u->status = NT_STATUS_OK;
1337 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1339 /* find the policy handle. open a policy on it. */
1340 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1341 return NT_STATUS_INVALID_HANDLE;
1342 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1343 return r_u->status;
1346 if (!sid_check_is_in_our_domain(&sid) &&
1347 !sid_check_is_in_builtin(&sid))
1348 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1350 if (!pdb_getgrsid(&map, sid))
1351 return NT_STATUS_NO_SUCH_ALIAS;
1353 switch (q_u->switch_level) {
1354 case 1:
1355 r_u->ptr = 1;
1356 r_u->ctr.switch_value1 = 1;
1357 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1358 break;
1359 case 3:
1360 r_u->ptr = 1;
1361 r_u->ctr.switch_value1 = 3;
1362 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1363 break;
1364 default:
1365 return NT_STATUS_INVALID_INFO_CLASS;
1368 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1370 return r_u->status;
1373 #if 0
1374 /*******************************************************************
1375 samr_reply_lookup_ids
1376 ********************************************************************/
1378 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1380 uint32 rid[MAX_SAM_ENTRIES];
1381 int num_rids = q_u->num_sids1;
1383 r_u->status = NT_STATUS_OK;
1385 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1387 if (num_rids > MAX_SAM_ENTRIES) {
1388 num_rids = MAX_SAM_ENTRIES;
1389 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1392 #if 0
1393 int i;
1394 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1396 for (i = 0; i < num_rids && status == 0; i++)
1398 struct sam_passwd *sam_pass;
1399 fstring user_name;
1402 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1403 q_u->uni_user_name[i].uni_str_len));
1405 /* find the user account */
1406 become_root();
1407 sam_pass = get_smb21pwd_entry(user_name, 0);
1408 unbecome_root();
1410 if (sam_pass == NULL)
1412 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1413 rid[i] = 0;
1415 else
1417 rid[i] = sam_pass->user_rid;
1420 #endif
1422 num_rids = 1;
1423 rid[0] = BUILTIN_ALIAS_RID_USERS;
1425 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1427 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1429 return r_u->status;
1431 #endif
1433 /*******************************************************************
1434 _samr_lookup_names
1435 ********************************************************************/
1437 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1439 uint32 rid[MAX_SAM_ENTRIES];
1440 uint32 local_rid;
1441 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1442 enum SID_NAME_USE local_type;
1443 int i;
1444 int num_rids = q_u->num_names2;
1445 DOM_SID pol_sid;
1446 fstring sid_str;
1447 uint32 acc_granted;
1449 r_u->status = NT_STATUS_OK;
1451 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1453 ZERO_ARRAY(rid);
1454 ZERO_ARRAY(type);
1456 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1457 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1458 return r_u->status;
1461 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 */
1462 return r_u->status;
1465 if (num_rids > MAX_SAM_ENTRIES) {
1466 num_rids = MAX_SAM_ENTRIES;
1467 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1470 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1472 become_root(); /* local_lookup_name can require root privs */
1474 for (i = 0; i < num_rids; i++) {
1475 fstring name;
1476 DOM_SID sid;
1477 int ret;
1479 r_u->status = NT_STATUS_NONE_MAPPED;
1481 rid [i] = 0xffffffff;
1482 type[i] = SID_NAME_UNKNOWN;
1484 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1487 * we are only looking for a name
1488 * the SID we get back can be outside
1489 * the scope of the pol_sid
1491 * in clear: it prevents to reply to domain\group: yes
1492 * when only builtin\group exists.
1494 * a cleaner code is to add the sid of the domain we're looking in
1495 * to the local_lookup_name function.
1498 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1499 sid_split_rid(&sid, &local_rid);
1501 if (sid_equal(&sid, &pol_sid)) {
1502 rid[i]=local_rid;
1503 type[i]=local_type;
1504 r_u->status = NT_STATUS_OK;
1509 unbecome_root();
1511 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1513 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1515 return r_u->status;
1518 /*******************************************************************
1519 _samr_chgpasswd_user
1520 ********************************************************************/
1522 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1524 fstring user_name;
1525 fstring wks;
1527 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1529 r_u->status = NT_STATUS_OK;
1531 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1532 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1534 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1537 * Pass the user through the NT -> unix user mapping
1538 * function.
1541 (void)map_username(user_name);
1544 * UNIX username case mangling not required, pass_oem_change
1545 * is case insensitive.
1548 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1549 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1551 init_samr_r_chgpasswd_user(r_u, r_u->status);
1553 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1555 return r_u->status;
1558 /*******************************************************************
1559 makes a SAMR_R_LOOKUP_RIDS structure.
1560 ********************************************************************/
1562 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1563 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1565 uint32 i;
1566 UNIHDR *hdr_name=NULL;
1567 UNISTR2 *uni_name=NULL;
1569 *pp_uni_name = NULL;
1570 *pp_hdr_name = NULL;
1572 if (num_names != 0) {
1573 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1574 if (hdr_name == NULL)
1575 return False;
1577 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1578 if (uni_name == NULL)
1579 return False;
1582 for (i = 0; i < num_names; i++) {
1583 int len = names[i] != NULL ? strlen(names[i]) : 0;
1584 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1585 init_uni_hdr(&hdr_name[i], len);
1586 init_unistr2(&uni_name[i], names[i], len);
1589 *pp_uni_name = uni_name;
1590 *pp_hdr_name = hdr_name;
1592 return True;
1595 /*******************************************************************
1596 _samr_lookup_rids
1597 ********************************************************************/
1599 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1601 fstring group_names[MAX_SAM_ENTRIES];
1602 uint32 *group_attrs = NULL;
1603 UNIHDR *hdr_name = NULL;
1604 UNISTR2 *uni_name = NULL;
1605 DOM_SID pol_sid;
1606 int num_rids = q_u->num_rids1;
1607 int i;
1608 uint32 acc_granted;
1610 r_u->status = NT_STATUS_OK;
1612 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1614 /* find the policy handle. open a policy on it. */
1615 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1616 return NT_STATUS_INVALID_HANDLE;
1618 if (num_rids > MAX_SAM_ENTRIES) {
1619 num_rids = MAX_SAM_ENTRIES;
1620 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1623 if (num_rids) {
1624 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1625 return NT_STATUS_NO_MEMORY;
1628 r_u->status = NT_STATUS_NONE_MAPPED;
1630 become_root(); /* lookup_sid can require root privs */
1632 for (i = 0; i < num_rids; i++) {
1633 fstring tmpname;
1634 fstring domname;
1635 DOM_SID sid;
1636 enum SID_NAME_USE type;
1638 group_attrs[i] = SID_NAME_UNKNOWN;
1639 *group_names[i] = '\0';
1641 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1642 sid_copy(&sid, &pol_sid);
1643 sid_append_rid(&sid, q_u->rid[i]);
1645 if (lookup_sid(&sid, domname, tmpname, &type)) {
1646 r_u->status = NT_STATUS_OK;
1647 group_attrs[i] = (uint32)type;
1648 fstrcpy(group_names[i],tmpname);
1649 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1654 unbecome_root();
1656 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1657 return NT_STATUS_NO_MEMORY;
1659 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1661 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1663 return r_u->status;
1666 /*******************************************************************
1667 _samr_open_user. Safe - gives out no passwd info.
1668 ********************************************************************/
1670 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1672 SAM_ACCOUNT *sampass=NULL;
1673 DOM_SID sid;
1674 POLICY_HND domain_pol = q_u->domain_pol;
1675 POLICY_HND *user_pol = &r_u->user_pol;
1676 struct samr_info *info = NULL;
1677 SEC_DESC *psd = NULL;
1678 uint32 acc_granted;
1679 uint32 des_access = q_u->access_mask;
1680 size_t sd_size;
1681 BOOL ret;
1682 NTSTATUS nt_status;
1684 r_u->status = NT_STATUS_OK;
1686 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1687 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1688 return NT_STATUS_INVALID_HANDLE;
1690 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1691 return nt_status;
1694 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1695 if (!NT_STATUS_IS_OK(nt_status)) {
1696 return nt_status;
1699 /* append the user's RID to it */
1700 if (!sid_append_rid(&sid, q_u->user_rid))
1701 return NT_STATUS_NO_SUCH_USER;
1703 /* check if access can be granted as requested by client. */
1704 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1705 se_map_generic(&des_access, &usr_generic_mapping);
1706 if (!NT_STATUS_IS_OK(nt_status =
1707 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1708 des_access, &acc_granted, "_samr_open_user"))) {
1709 return nt_status;
1712 become_root();
1713 ret=pdb_getsampwsid(sampass, &sid);
1714 unbecome_root();
1716 /* check that the SID exists in our domain. */
1717 if (ret == False) {
1718 return NT_STATUS_NO_SUCH_USER;
1721 pdb_free_sam(&sampass);
1723 /* associate the user's SID and access bits with the new handle. */
1724 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1725 return NT_STATUS_NO_MEMORY;
1726 info->acc_granted = acc_granted;
1728 /* get a (unique) handle. open a policy on it. */
1729 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1730 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1732 return r_u->status;
1735 /*************************************************************************
1736 get_user_info_10. Safe. Only gives out acb bits.
1737 *************************************************************************/
1739 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1741 SAM_ACCOUNT *smbpass=NULL;
1742 BOOL ret;
1743 NTSTATUS nt_status;
1745 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1747 if (!NT_STATUS_IS_OK(nt_status)) {
1748 return nt_status;
1751 become_root();
1752 ret = pdb_getsampwsid(smbpass, user_sid);
1753 unbecome_root();
1755 if (ret==False) {
1756 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1757 return NT_STATUS_NO_SUCH_USER;
1760 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1762 ZERO_STRUCTP(id10);
1763 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1765 pdb_free_sam(&smbpass);
1767 return NT_STATUS_OK;
1770 /*************************************************************************
1771 get_user_info_12. OK - this is the killer as it gives out password info.
1772 Ensure that this is only allowed on an encrypted connection with a root
1773 user. JRA.
1774 *************************************************************************/
1776 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1778 SAM_ACCOUNT *smbpass=NULL;
1779 BOOL ret;
1780 NTSTATUS nt_status;
1782 if (!p->ntlmssp_auth_validated)
1783 return NT_STATUS_ACCESS_DENIED;
1785 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1786 return NT_STATUS_ACCESS_DENIED;
1789 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1792 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1794 if (!NT_STATUS_IS_OK(nt_status)) {
1795 return nt_status;
1798 ret = pdb_getsampwsid(smbpass, user_sid);
1800 if (ret == False) {
1801 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1802 pdb_free_sam(&smbpass);
1803 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1806 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1808 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1809 pdb_free_sam(&smbpass);
1810 return NT_STATUS_ACCOUNT_DISABLED;
1813 ZERO_STRUCTP(id12);
1814 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1816 pdb_free_sam(&smbpass);
1818 return NT_STATUS_OK;
1821 /*************************************************************************
1822 get_user_info_20
1823 *************************************************************************/
1825 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1827 SAM_ACCOUNT *sampass=NULL;
1828 BOOL ret;
1830 pdb_init_sam_talloc(mem_ctx, &sampass);
1832 become_root();
1833 ret = pdb_getsampwsid(sampass, user_sid);
1834 unbecome_root();
1836 if (ret == False) {
1837 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1838 return NT_STATUS_NO_SUCH_USER;
1841 samr_clear_sam_passwd(sampass);
1843 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1845 ZERO_STRUCTP(id20);
1846 init_sam_user_info20A(id20, sampass);
1848 pdb_free_sam(&sampass);
1850 return NT_STATUS_OK;
1853 /*************************************************************************
1854 get_user_info_21
1855 *************************************************************************/
1857 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1858 DOM_SID *user_sid, DOM_SID *domain_sid)
1860 SAM_ACCOUNT *sampass=NULL;
1861 BOOL ret;
1862 NTSTATUS nt_status;
1864 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1865 if (!NT_STATUS_IS_OK(nt_status)) {
1866 return nt_status;
1869 become_root();
1870 ret = pdb_getsampwsid(sampass, user_sid);
1871 unbecome_root();
1873 if (ret == False) {
1874 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1875 return NT_STATUS_NO_SUCH_USER;
1878 samr_clear_sam_passwd(sampass);
1880 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1882 ZERO_STRUCTP(id21);
1883 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1885 pdb_free_sam(&sampass);
1887 return NT_STATUS_OK;
1890 /*******************************************************************
1891 _samr_query_userinfo
1892 ********************************************************************/
1894 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1896 SAM_USERINFO_CTR *ctr;
1897 struct samr_info *info = NULL;
1898 DOM_SID domain_sid;
1899 uint32 rid;
1901 r_u->status=NT_STATUS_OK;
1903 /* search for the handle */
1904 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1905 return NT_STATUS_INVALID_HANDLE;
1907 domain_sid = info->sid;
1909 sid_split_rid(&domain_sid, &rid);
1911 if (!sid_check_is_in_our_domain(&info->sid))
1912 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1914 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1916 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1917 if (!ctr)
1918 return NT_STATUS_NO_MEMORY;
1920 ZERO_STRUCTP(ctr);
1922 /* ok! user info levels (lots: see MSDEV help), off we go... */
1923 ctr->switch_value = q_u->switch_value;
1925 switch (q_u->switch_value) {
1926 case 0x10:
1927 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1928 if (ctr->info.id10 == NULL)
1929 return NT_STATUS_NO_MEMORY;
1931 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1932 return r_u->status;
1933 break;
1935 #if 0
1936 /* whoops - got this wrong. i think. or don't understand what's happening. */
1937 case 0x11:
1939 NTTIME expire;
1940 info = (void *)&id11;
1942 expire.low = 0xffffffff;
1943 expire.high = 0x7fffffff;
1945 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1946 sizeof
1947 (*ctr->
1948 info.
1949 id11));
1950 ZERO_STRUCTP(ctr->info.id11);
1951 init_sam_user_info11(ctr->info.id11, &expire,
1952 "BROOKFIELDS$", /* name */
1953 0x03ef, /* user rid */
1954 0x201, /* group rid */
1955 0x0080); /* acb info */
1957 break;
1959 #endif
1961 case 0x12:
1962 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1963 if (ctr->info.id12 == NULL)
1964 return NT_STATUS_NO_MEMORY;
1966 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1967 return r_u->status;
1968 break;
1970 case 20:
1971 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1972 if (ctr->info.id20 == NULL)
1973 return NT_STATUS_NO_MEMORY;
1974 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1975 return r_u->status;
1976 break;
1978 case 21:
1979 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1980 if (ctr->info.id21 == NULL)
1981 return NT_STATUS_NO_MEMORY;
1982 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1983 &info->sid, &domain_sid)))
1984 return r_u->status;
1985 break;
1987 default:
1988 return NT_STATUS_INVALID_INFO_CLASS;
1991 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1993 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1995 return r_u->status;
1998 /*******************************************************************
1999 samr_reply_query_usergroups
2000 ********************************************************************/
2002 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
2004 SAM_ACCOUNT *sam_pass=NULL;
2005 DOM_SID sid;
2006 DOM_GID *gids = NULL;
2007 int num_groups = 0;
2008 uint32 acc_granted;
2009 BOOL ret;
2012 * from the SID in the request:
2013 * we should send back the list of DOMAIN GROUPS
2014 * the user is a member of
2016 * and only the DOMAIN GROUPS
2017 * no ALIASES !!! neither aliases of the domain
2018 * nor aliases of the builtin SID
2020 * JFM, 12/2/2001
2023 r_u->status = NT_STATUS_OK;
2025 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2027 /* find the policy handle. open a policy on it. */
2028 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2029 return NT_STATUS_INVALID_HANDLE;
2031 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2032 return r_u->status;
2035 if (!sid_check_is_in_our_domain(&sid))
2036 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2038 pdb_init_sam(&sam_pass);
2040 become_root();
2041 ret = pdb_getsampwsid(sam_pass, &sid);
2042 unbecome_root();
2044 if (ret == False) {
2045 pdb_free_sam(&sam_pass);
2046 return NT_STATUS_NO_SUCH_USER;
2049 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2050 pdb_free_sam(&sam_pass);
2051 return NT_STATUS_NO_SUCH_GROUP;
2054 /* construct the response. lkclXXXX: gids are not copied! */
2055 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2057 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2059 pdb_free_sam(&sam_pass);
2061 return r_u->status;
2064 /*******************************************************************
2065 _samr_query_dom_info
2066 ********************************************************************/
2068 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2070 struct samr_info *info = NULL;
2071 SAM_UNK_CTR *ctr;
2072 uint32 min_pass_len,pass_hist,flag;
2073 time_t u_expire, u_min_age;
2074 NTTIME nt_expire, nt_min_age;
2076 time_t u_lock_duration, u_reset_time;
2077 NTTIME nt_lock_duration, nt_reset_time;
2078 uint32 lockout;
2080 time_t u_logout;
2081 NTTIME nt_logout;
2083 uint32 account_policy_temp;
2085 uint32 num_users=0, num_groups=0, num_aliases=0;
2087 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2088 return NT_STATUS_NO_MEMORY;
2090 ZERO_STRUCTP(ctr);
2092 r_u->status = NT_STATUS_OK;
2094 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2096 /* find the policy handle. open a policy on it. */
2097 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2098 return NT_STATUS_INVALID_HANDLE;
2100 switch (q_u->switch_value) {
2101 case 0x01:
2103 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2104 min_pass_len = account_policy_temp;
2106 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2107 pass_hist = account_policy_temp;
2109 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2110 flag = account_policy_temp;
2112 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2113 u_expire = account_policy_temp;
2115 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2116 u_min_age = account_policy_temp;
2118 unix_to_nt_time_abs(&nt_expire, u_expire);
2119 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2121 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2122 flag, nt_expire, nt_min_age);
2123 break;
2124 case 0x02:
2125 become_root();
2126 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2127 unbecome_root();
2128 if (!NT_STATUS_IS_OK(r_u->status)) {
2129 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2130 return r_u->status;
2132 num_users=info->disp_info.num_user_account;
2133 free_samr_db(info);
2135 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2136 if (!NT_STATUS_IS_OK(r_u->status)) {
2137 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2138 return r_u->status;
2140 num_groups=info->disp_info.num_group_account;
2141 free_samr_db(info);
2143 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2144 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2145 num_users, num_groups, num_aliases);
2146 break;
2147 case 0x03:
2148 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2149 unix_to_nt_time_abs(&nt_logout, u_logout);
2151 init_unk_info3(&ctr->info.inf3, nt_logout);
2152 break;
2153 case 0x05:
2154 init_unk_info5(&ctr->info.inf5, global_myname());
2155 break;
2156 case 0x06:
2157 init_unk_info6(&ctr->info.inf6);
2158 break;
2159 case 0x07:
2160 init_unk_info7(&ctr->info.inf7);
2161 break;
2162 case 0x0c:
2163 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2164 u_lock_duration = account_policy_temp;
2166 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2167 u_reset_time = account_policy_temp;
2169 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2170 lockout = account_policy_temp;
2172 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2173 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2175 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2176 break;
2177 default:
2178 return NT_STATUS_INVALID_INFO_CLASS;
2181 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2183 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2185 return r_u->status;
2188 /*******************************************************************
2189 _samr_create_user
2190 Create an account, can be either a normal user or a machine.
2191 This funcion will need to be updated for bdc/domain trusts.
2192 ********************************************************************/
2194 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2196 SAM_ACCOUNT *sam_pass=NULL;
2197 fstring account;
2198 DOM_SID sid;
2199 pstring add_script;
2200 POLICY_HND dom_pol = q_u->domain_pol;
2201 UNISTR2 user_account = q_u->uni_name;
2202 uint16 acb_info = q_u->acb_info;
2203 POLICY_HND *user_pol = &r_u->user_pol;
2204 struct samr_info *info = NULL;
2205 BOOL ret;
2206 NTSTATUS nt_status;
2207 struct passwd *pw;
2208 uint32 acc_granted;
2209 SEC_DESC *psd;
2210 size_t sd_size;
2211 uint32 new_rid = 0;
2212 /* check this, when giving away 'add computer to domain' privs */
2213 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2215 /* Get the domain SID stored in the domain policy */
2216 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2217 return NT_STATUS_INVALID_HANDLE;
2219 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2220 return nt_status;
2223 /* find the account: tell the caller if it exists.
2224 lkclXXXX i have *no* idea if this is a problem or not
2225 or even if you are supposed to construct a different
2226 reply if the account already exists...
2229 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2230 strlower_m(account);
2232 pdb_init_sam(&sam_pass);
2234 become_root();
2235 ret = pdb_getsampwnam(sam_pass, account);
2236 unbecome_root();
2237 if (ret == True) {
2238 /* this account exists: say so */
2239 pdb_free_sam(&sam_pass);
2240 return NT_STATUS_USER_EXISTS;
2243 pdb_free_sam(&sam_pass);
2246 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2247 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2248 * that only people with write access to the smbpasswd file will be able
2249 * to create a user. JRA.
2253 * add the user in the /etc/passwd file or the unix authority system.
2254 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2255 * a) local_password_change() checks for us if the /etc/passwd account really exists
2256 * b) smb_create_user() would return an error if the account already exists
2257 * and as it could return an error also if it can't create the account, it would be tricky.
2259 * So we go the easy way, only check after if the account exists.
2260 * JFM (2/3/2001), to clear any possible bad understanding (-:
2262 * We now have seperate script paramaters for adding users/machines so we
2263 * now have some sainity-checking to match.
2266 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2269 * we used to have code here that made sure the acb_info flags
2270 * matched with the users named (e.g. an account flags as a machine
2271 * trust account ended in '$'). It has been ifdef'd out for a long
2272 * time, so I replaced it with this comment. --jerry
2275 /* the passdb lookup has failed; check to see if we need to run the
2276 add user/machine script */
2278 pw = Get_Pwnam(account);
2280 /*********************************************************************
2281 * HEADS UP! If we have to create a new user account, we have to get
2282 * a new RID from somewhere. This used to be done by the passdb
2283 * backend. It has been moved into idmap now. Since idmap is now
2284 * wrapped up behind winbind, this means you have to run winbindd if you
2285 * want new accounts to get a new RID when "enable rid algorithm = no".
2286 * Tough. We now have a uniform way of allocating RIDs regardless
2287 * of what ever passdb backend people may use.
2288 * --jerry (2003-07-10)
2289 *********************************************************************/
2291 if ( !pw ) {
2293 * we can't check both the ending $ and the acb_info.
2295 * UserManager creates trust accounts (ending in $,
2296 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2297 * JFM, 11/29/2001
2299 if (account[strlen(account)-1] == '$')
2300 pstrcpy(add_script, lp_addmachine_script());
2301 else
2302 pstrcpy(add_script, lp_adduser_script());
2304 if (*add_script) {
2305 int add_ret;
2306 all_string_sub(add_script, "%u", account, sizeof(account));
2307 add_ret = smbrun(add_script,NULL);
2308 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2310 else /* no add user script -- ask winbindd to do it */
2312 if ( !winbind_create_user( account, &new_rid ) ) {
2313 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2314 account));
2320 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2322 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2323 return nt_status;
2325 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2327 if (!pdb_add_sam_account(sam_pass)) {
2328 pdb_free_sam(&sam_pass);
2329 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2330 account));
2331 return NT_STATUS_ACCESS_DENIED;
2334 /* Get the user's SID */
2335 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2337 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2338 se_map_generic(&des_access, &usr_generic_mapping);
2339 if (!NT_STATUS_IS_OK(nt_status =
2340 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2341 des_access, &acc_granted, "_samr_create_user"))) {
2342 return nt_status;
2345 /* associate the user's SID with the new handle. */
2346 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2347 pdb_free_sam(&sam_pass);
2348 return NT_STATUS_NO_MEMORY;
2351 ZERO_STRUCTP(info);
2352 info->sid = sid;
2353 info->acc_granted = acc_granted;
2355 /* get a (unique) handle. open a policy on it. */
2356 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2357 pdb_free_sam(&sam_pass);
2358 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2361 r_u->user_rid=pdb_get_user_rid(sam_pass);
2363 r_u->access_granted = acc_granted;
2365 pdb_free_sam(&sam_pass);
2367 return NT_STATUS_OK;
2370 /*******************************************************************
2371 samr_reply_connect_anon
2372 ********************************************************************/
2374 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2376 struct samr_info *info = NULL;
2377 uint32 des_access = q_u->access_mask;
2379 /* Access check */
2381 if (!pipe_access_check(p)) {
2382 DEBUG(3, ("access denied to samr_connect_anon\n"));
2383 r_u->status = NT_STATUS_ACCESS_DENIED;
2384 return r_u->status;
2387 /* set up the SAMR connect_anon response */
2389 r_u->status = NT_STATUS_OK;
2391 /* associate the user's SID with the new handle. */
2392 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2393 return NT_STATUS_NO_MEMORY;
2395 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2396 was observed from a win98 client trying to enumerate users (when configured
2397 user level access control on shares) --jerry */
2399 se_map_generic( &des_access, &sam_generic_mapping );
2400 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2402 info->status = q_u->unknown_0;
2404 /* get a (unique) handle. open a policy on it. */
2405 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2406 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2408 return r_u->status;
2411 /*******************************************************************
2412 samr_reply_connect
2413 ********************************************************************/
2415 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2417 struct samr_info *info = NULL;
2418 SEC_DESC *psd = NULL;
2419 uint32 acc_granted;
2420 uint32 des_access = q_u->access_mask;
2421 size_t sd_size;
2422 NTSTATUS nt_status;
2425 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2427 /* Access check */
2429 if (!pipe_access_check(p)) {
2430 DEBUG(3, ("access denied to samr_connect\n"));
2431 r_u->status = NT_STATUS_ACCESS_DENIED;
2432 return r_u->status;
2435 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2436 se_map_generic(&des_access, &sam_generic_mapping);
2437 if (!NT_STATUS_IS_OK(nt_status =
2438 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2439 des_access, &acc_granted, "_samr_connect"))) {
2440 return nt_status;
2443 r_u->status = NT_STATUS_OK;
2445 /* associate the user's SID and access granted with the new handle. */
2446 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2447 return NT_STATUS_NO_MEMORY;
2449 info->acc_granted = acc_granted;
2450 info->status = q_u->access_mask;
2452 /* get a (unique) handle. open a policy on it. */
2453 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2454 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2456 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2458 return r_u->status;
2461 /*******************************************************************
2462 samr_connect4
2463 ********************************************************************/
2465 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2467 struct samr_info *info = NULL;
2468 SEC_DESC *psd = NULL;
2469 uint32 acc_granted;
2470 uint32 des_access = q_u->access_mask;
2471 size_t sd_size;
2472 NTSTATUS nt_status;
2475 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2477 /* Access check */
2479 if (!pipe_access_check(p)) {
2480 DEBUG(3, ("access denied to samr_connect4\n"));
2481 r_u->status = NT_STATUS_ACCESS_DENIED;
2482 return r_u->status;
2485 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2486 se_map_generic(&des_access, &sam_generic_mapping);
2487 if (!NT_STATUS_IS_OK(nt_status =
2488 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2489 des_access, &acc_granted, "_samr_connect"))) {
2490 return nt_status;
2493 r_u->status = NT_STATUS_OK;
2495 /* associate the user's SID and access granted with the new handle. */
2496 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2497 return NT_STATUS_NO_MEMORY;
2499 info->acc_granted = acc_granted;
2500 info->status = q_u->access_mask;
2502 /* get a (unique) handle. open a policy on it. */
2503 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2504 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2506 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2508 return r_u->status;
2511 /**********************************************************************
2512 api_samr_lookup_domain
2513 **********************************************************************/
2515 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2517 struct samr_info *info;
2518 fstring domain_name;
2519 DOM_SID sid;
2521 r_u->status = NT_STATUS_OK;
2523 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2524 return NT_STATUS_INVALID_HANDLE;
2526 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2527 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2529 return r_u->status;
2532 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2534 ZERO_STRUCT(sid);
2536 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2537 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2540 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2542 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2544 return r_u->status;
2547 /******************************************************************
2548 makes a SAMR_R_ENUM_DOMAINS structure.
2549 ********************************************************************/
2551 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2552 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2554 uint32 i;
2555 SAM_ENTRY *sam;
2556 UNISTR2 *uni_name;
2558 DEBUG(5, ("make_enum_domains\n"));
2560 *pp_sam = NULL;
2561 *pp_uni_name = NULL;
2563 if (num_sam_entries == 0)
2564 return True;
2566 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2567 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2569 if (sam == NULL || uni_name == NULL)
2570 return False;
2572 for (i = 0; i < num_sam_entries; i++) {
2573 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2575 init_sam_entry(&sam[i], len, 0);
2576 init_unistr2(&uni_name[i], doms[i], len);
2579 *pp_sam = sam;
2580 *pp_uni_name = uni_name;
2582 return True;
2585 /**********************************************************************
2586 api_samr_enum_domains
2587 **********************************************************************/
2589 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2591 struct samr_info *info;
2592 uint32 num_entries = 2;
2593 fstring dom[2];
2594 const char *name;
2596 r_u->status = NT_STATUS_OK;
2598 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2599 return NT_STATUS_INVALID_HANDLE;
2601 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2602 return r_u->status;
2605 name = get_global_sam_name();
2607 fstrcpy(dom[0],name);
2608 strupper_m(dom[0]);
2609 fstrcpy(dom[1],"Builtin");
2611 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2612 return NT_STATUS_NO_MEMORY;
2614 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2616 return r_u->status;
2619 /*******************************************************************
2620 api_samr_open_alias
2621 ********************************************************************/
2623 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2625 DOM_SID sid;
2626 POLICY_HND domain_pol = q_u->dom_pol;
2627 uint32 alias_rid = q_u->rid_alias;
2628 POLICY_HND *alias_pol = &r_u->pol;
2629 struct samr_info *info = NULL;
2630 SEC_DESC *psd = NULL;
2631 uint32 acc_granted;
2632 uint32 des_access = q_u->access_mask;
2633 size_t sd_size;
2634 NTSTATUS status;
2636 r_u->status = NT_STATUS_OK;
2638 /* find the domain policy and get the SID / access bits stored in the domain policy */
2639 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2640 return NT_STATUS_INVALID_HANDLE;
2642 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2643 return status;
2646 /* append the alias' RID to it */
2647 if (!sid_append_rid(&sid, alias_rid))
2648 return NT_STATUS_NO_SUCH_USER;
2650 /*check if access can be granted as requested by client. */
2651 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2652 se_map_generic(&des_access,&ali_generic_mapping);
2653 if (!NT_STATUS_IS_OK(status =
2654 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2655 des_access, &acc_granted, "_samr_open_alias"))) {
2656 return status;
2660 * we should check if the rid really exist !!!
2661 * JFM.
2664 /* associate the user's SID with the new handle. */
2665 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2666 return NT_STATUS_NO_MEMORY;
2668 info->acc_granted = acc_granted;
2670 /* get a (unique) handle. open a policy on it. */
2671 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2672 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2674 return r_u->status;
2677 /*******************************************************************
2678 set_user_info_10
2679 ********************************************************************/
2681 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2683 SAM_ACCOUNT *pwd =NULL;
2684 BOOL ret;
2686 pdb_init_sam(&pwd);
2688 ret = pdb_getsampwsid(pwd, sid);
2690 if(ret==False) {
2691 pdb_free_sam(&pwd);
2692 return False;
2695 if (id10 == NULL) {
2696 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2697 pdb_free_sam(&pwd);
2698 return False;
2701 /* FIX ME: check if the value is really changed --metze */
2702 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2703 pdb_free_sam(&pwd);
2704 return False;
2707 if(!pdb_update_sam_account(pwd)) {
2708 pdb_free_sam(&pwd);
2709 return False;
2712 pdb_free_sam(&pwd);
2714 return True;
2717 /*******************************************************************
2718 set_user_info_12
2719 ********************************************************************/
2721 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2723 SAM_ACCOUNT *pwd = NULL;
2725 pdb_init_sam(&pwd);
2727 if(!pdb_getsampwsid(pwd, sid)) {
2728 pdb_free_sam(&pwd);
2729 return False;
2732 if (id12 == NULL) {
2733 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2734 pdb_free_sam(&pwd);
2735 return False;
2738 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2739 pdb_free_sam(&pwd);
2740 return False;
2742 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2743 pdb_free_sam(&pwd);
2744 return False;
2746 if (!pdb_set_pass_changed_now (pwd)) {
2747 pdb_free_sam(&pwd);
2748 return False;
2751 if(!pdb_update_sam_account(pwd)) {
2752 pdb_free_sam(&pwd);
2753 return False;
2756 pdb_free_sam(&pwd);
2757 return True;
2760 /*******************************************************************
2761 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2762 ********************************************************************/
2763 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2765 struct group *grp;
2766 gid_t gid;
2768 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2769 &gid))) {
2770 DEBUG(2,("Could not get gid for primary group of "
2771 "user %s\n", pdb_get_username(sampass)));
2772 return False;
2775 grp = getgrgid(gid);
2777 if (grp == NULL) {
2778 DEBUG(2,("Could not find primary group %lu for "
2779 "user %s\n", (unsigned long)gid,
2780 pdb_get_username(sampass)));
2781 return False;
2784 if (smb_set_primary_group(grp->gr_name,
2785 pdb_get_username(sampass)) != 0) {
2786 DEBUG(2,("Could not set primary group for user %s to "
2787 "%s\n",
2788 pdb_get_username(sampass), grp->gr_name));
2789 return False;
2792 return True;
2796 /*******************************************************************
2797 set_user_info_21
2798 ********************************************************************/
2800 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2802 SAM_ACCOUNT *pwd = NULL;
2804 if (id21 == NULL) {
2805 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2806 return False;
2809 pdb_init_sam(&pwd);
2811 if (!pdb_getsampwsid(pwd, sid)) {
2812 pdb_free_sam(&pwd);
2813 return False;
2816 copy_id21_to_sam_passwd(pwd, id21);
2819 * The funny part about the previous two calls is
2820 * that pwd still has the password hashes from the
2821 * passdb entry. These have not been updated from
2822 * id21. I don't know if they need to be set. --jerry
2825 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2826 set_unix_primary_group(pwd);
2828 /* write the change out */
2829 if(!pdb_update_sam_account(pwd)) {
2830 pdb_free_sam(&pwd);
2831 return False;
2834 pdb_free_sam(&pwd);
2836 return True;
2839 /*******************************************************************
2840 set_user_info_23
2841 ********************************************************************/
2843 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2845 SAM_ACCOUNT *pwd = NULL;
2846 pstring plaintext_buf;
2847 uint32 len;
2848 uint16 acct_ctrl;
2850 if (id23 == NULL) {
2851 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2852 return False;
2855 pdb_init_sam(&pwd);
2857 if (!pdb_getsampwsid(pwd, sid)) {
2858 pdb_free_sam(&pwd);
2859 return False;
2862 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2863 pdb_get_username(pwd)));
2865 acct_ctrl = pdb_get_acct_ctrl(pwd);
2867 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2868 pdb_free_sam(&pwd);
2869 return False;
2872 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2873 pdb_free_sam(&pwd);
2874 return False;
2877 copy_id23_to_sam_passwd(pwd, id23);
2879 /* if it's a trust account, don't update /etc/passwd */
2880 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2881 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2882 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2883 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2884 } else {
2885 /* update the UNIX password */
2886 if (lp_unix_password_sync() )
2887 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2888 pdb_free_sam(&pwd);
2889 return False;
2893 ZERO_STRUCT(plaintext_buf);
2895 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2896 set_unix_primary_group(pwd);
2898 if(!pdb_update_sam_account(pwd)) {
2899 pdb_free_sam(&pwd);
2900 return False;
2903 pdb_free_sam(&pwd);
2905 return True;
2908 /*******************************************************************
2909 set_user_info_pw
2910 ********************************************************************/
2912 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2914 SAM_ACCOUNT *pwd = NULL;
2915 uint32 len;
2916 pstring plaintext_buf;
2917 uint16 acct_ctrl;
2919 pdb_init_sam(&pwd);
2921 if (!pdb_getsampwsid(pwd, sid)) {
2922 pdb_free_sam(&pwd);
2923 return False;
2926 DEBUG(5, ("Attempting administrator password change for user %s\n",
2927 pdb_get_username(pwd)));
2929 acct_ctrl = pdb_get_acct_ctrl(pwd);
2931 ZERO_STRUCT(plaintext_buf);
2933 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2934 pdb_free_sam(&pwd);
2935 return False;
2938 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2939 pdb_free_sam(&pwd);
2940 return False;
2943 /* if it's a trust account, don't update /etc/passwd */
2944 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2945 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2946 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2947 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2948 } else {
2949 /* update the UNIX password */
2950 if (lp_unix_password_sync()) {
2951 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2952 pdb_free_sam(&pwd);
2953 return False;
2958 ZERO_STRUCT(plaintext_buf);
2960 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2962 /* update the SAMBA password */
2963 if(!pdb_update_sam_account(pwd)) {
2964 pdb_free_sam(&pwd);
2965 return False;
2968 pdb_free_sam(&pwd);
2970 return True;
2973 /*******************************************************************
2974 samr_reply_set_userinfo
2975 ********************************************************************/
2977 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2979 DOM_SID sid;
2980 POLICY_HND *pol = &q_u->pol;
2981 uint16 switch_value = q_u->switch_value;
2982 SAM_USERINFO_CTR *ctr = q_u->ctr;
2983 uint32 acc_granted;
2984 uint32 acc_required;
2986 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2988 r_u->status = NT_STATUS_OK;
2990 /* find the policy handle. open a policy on it. */
2991 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2992 return NT_STATUS_INVALID_HANDLE;
2994 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2995 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2996 return r_u->status;
2999 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3001 if (ctr == NULL) {
3002 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3003 return NT_STATUS_INVALID_INFO_CLASS;
3006 /* ok! user info levels (lots: see MSDEV help), off we go... */
3007 switch (switch_value) {
3008 case 0x12:
3009 if (!set_user_info_12(ctr->info.id12, &sid))
3010 return NT_STATUS_ACCESS_DENIED;
3011 break;
3013 case 24:
3014 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
3016 dump_data(100, (char *)ctr->info.id24->pass, 516);
3018 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3019 return NT_STATUS_ACCESS_DENIED;
3020 break;
3022 case 25:
3023 #if 0
3025 * Currently we don't really know how to unmarshall
3026 * the level 25 struct, and the password encryption
3027 * is different. This is a placeholder for when we
3028 * do understand it. In the meantime just return INVALID
3029 * info level and W2K SP2 drops down to level 23... JRA.
3032 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3034 dump_data(100, (char *)ctr->info.id25->pass, 532);
3036 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3037 return NT_STATUS_ACCESS_DENIED;
3038 break;
3039 #endif
3040 return NT_STATUS_INVALID_INFO_CLASS;
3042 case 23:
3043 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3045 dump_data(100, (char *)ctr->info.id23->pass, 516);
3047 if (!set_user_info_23(ctr->info.id23, &sid))
3048 return NT_STATUS_ACCESS_DENIED;
3049 break;
3051 default:
3052 return NT_STATUS_INVALID_INFO_CLASS;
3055 return r_u->status;
3058 /*******************************************************************
3059 samr_reply_set_userinfo2
3060 ********************************************************************/
3062 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3064 DOM_SID sid;
3065 SAM_USERINFO_CTR *ctr = q_u->ctr;
3066 POLICY_HND *pol = &q_u->pol;
3067 uint16 switch_value = q_u->switch_value;
3068 uint32 acc_granted;
3069 uint32 acc_required;
3071 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3073 r_u->status = NT_STATUS_OK;
3075 /* find the policy handle. open a policy on it. */
3076 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3077 return NT_STATUS_INVALID_HANDLE;
3079 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3080 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3081 return r_u->status;
3084 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3086 if (ctr == NULL) {
3087 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3088 return NT_STATUS_INVALID_INFO_CLASS;
3091 switch_value=ctr->switch_value;
3093 /* ok! user info levels (lots: see MSDEV help), off we go... */
3094 switch (switch_value) {
3095 case 21:
3096 if (!set_user_info_21(ctr->info.id21, &sid))
3097 return NT_STATUS_ACCESS_DENIED;
3098 break;
3099 case 16:
3100 if (!set_user_info_10(ctr->info.id10, &sid))
3101 return NT_STATUS_ACCESS_DENIED;
3102 break;
3103 case 18:
3104 /* Used by AS/U JRA. */
3105 if (!set_user_info_12(ctr->info.id12, &sid))
3106 return NT_STATUS_ACCESS_DENIED;
3107 break;
3108 default:
3109 return NT_STATUS_INVALID_INFO_CLASS;
3112 return r_u->status;
3115 /*********************************************************************
3116 _samr_query_aliasmem
3117 *********************************************************************/
3119 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3121 int num_groups = 0, tmp_num_groups=0;
3122 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3123 struct samr_info *info = NULL;
3124 int i,j;
3126 NTSTATUS ntstatus1;
3127 NTSTATUS ntstatus2;
3129 /* until i see a real useraliases query, we fack one up */
3131 /* I have seen one, JFM 2/12/2001 */
3133 * Explanation of what this call does:
3134 * for all the SID given in the request:
3135 * return a list of alias (local groups)
3136 * that have those SID as members.
3138 * and that's the alias in the domain specified
3139 * in the policy_handle
3141 * if the policy handle is on an incorrect sid
3142 * for example a user's sid
3143 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3146 r_u->status = NT_STATUS_OK;
3148 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3150 /* find the policy handle. open a policy on it. */
3151 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3152 return NT_STATUS_INVALID_HANDLE;
3154 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3155 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3157 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3158 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3159 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3160 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3164 if (!sid_check_is_domain(&info->sid) &&
3165 !sid_check_is_builtin(&info->sid))
3166 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3169 for (i=0; i<q_u->num_sids1; i++) {
3171 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3174 * if there is an error, we just continue as
3175 * it can be an unfound user or group
3177 if (!NT_STATUS_IS_OK(r_u->status)) {
3178 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3179 continue;
3182 if (tmp_num_groups==0) {
3183 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3184 continue;
3187 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3188 if (new_rids==NULL) {
3189 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3190 return NT_STATUS_NO_MEMORY;
3192 rids=new_rids;
3194 for (j=0; j<tmp_num_groups; j++)
3195 rids[j+num_groups]=tmp_rids[j];
3197 safe_free(tmp_rids);
3199 num_groups+=tmp_num_groups;
3202 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3203 return NT_STATUS_OK;
3206 /*********************************************************************
3207 _samr_query_aliasmem
3208 *********************************************************************/
3210 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3212 int i;
3214 GROUP_MAP map;
3215 int num_uids = 0;
3216 DOM_SID2 *sid;
3217 uid_t *uid=NULL;
3219 DOM_SID alias_sid;
3220 DOM_SID als_sid;
3221 uint32 alias_rid;
3222 fstring alias_sid_str;
3223 DOM_SID temp_sid;
3225 SAM_ACCOUNT *sam_user = NULL;
3226 BOOL check;
3227 uint32 acc_granted;
3229 /* find the policy handle. open a policy on it. */
3230 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3231 return NT_STATUS_INVALID_HANDLE;
3233 if (!NT_STATUS_IS_OK(r_u->status =
3234 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3235 return r_u->status;
3238 sid_copy(&als_sid, &alias_sid);
3239 sid_to_string(alias_sid_str, &alias_sid);
3240 sid_split_rid(&alias_sid, &alias_rid);
3242 DEBUG(10, ("sid is %s\n", alias_sid_str));
3244 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3245 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3246 if(!get_builtin_group_from_sid(als_sid, &map))
3247 return NT_STATUS_NO_SUCH_ALIAS;
3248 } else {
3249 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3250 DEBUG(10, ("lookup on Server SID\n"));
3251 if(!get_local_group_from_sid(als_sid, &map))
3252 return NT_STATUS_NO_SUCH_ALIAS;
3256 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3257 return NT_STATUS_NO_SUCH_ALIAS;
3259 DEBUG(10, ("sid is %s\n", alias_sid_str));
3260 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3261 if (num_uids!=0 && sid == NULL)
3262 return NT_STATUS_NO_MEMORY;
3264 for (i = 0; i < num_uids; i++) {
3265 struct passwd *pass;
3266 uint32 rid;
3268 sid_copy(&temp_sid, get_global_sam_sid());
3270 pass = getpwuid_alloc(uid[i]);
3271 if (!pass) continue;
3273 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3274 passwd_free(&pass);
3275 continue;
3278 become_root();
3279 check = pdb_getsampwnam(sam_user, pass->pw_name);
3280 unbecome_root();
3282 if (check != True) {
3283 pdb_free_sam(&sam_user);
3284 passwd_free(&pass);
3285 continue;
3288 rid = pdb_get_user_rid(sam_user);
3289 if (rid == 0) {
3290 pdb_free_sam(&sam_user);
3291 passwd_free(&pass);
3292 continue;
3295 pdb_free_sam(&sam_user);
3296 passwd_free(&pass);
3298 sid_append_rid(&temp_sid, rid);
3300 init_dom_sid2(&sid[i], &temp_sid);
3303 DEBUG(10, ("sid is %s\n", alias_sid_str));
3304 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3306 return NT_STATUS_OK;
3309 /*********************************************************************
3310 _samr_query_groupmem
3311 *********************************************************************/
3313 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3315 int num_uids = 0;
3316 int i;
3317 DOM_SID group_sid;
3318 uint32 group_rid;
3319 fstring group_sid_str;
3320 uid_t *uid=NULL;
3322 GROUP_MAP map;
3324 uint32 *rid=NULL;
3325 uint32 *attr=NULL;
3327 SAM_ACCOUNT *sam_user = NULL;
3328 BOOL check;
3329 uint32 acc_granted;
3331 /* find the policy handle. open a policy on it. */
3332 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3333 return NT_STATUS_INVALID_HANDLE;
3335 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3336 return r_u->status;
3339 /* todo: change to use sid_compare_front */
3341 sid_split_rid(&group_sid, &group_rid);
3342 sid_to_string(group_sid_str, &group_sid);
3343 DEBUG(10, ("sid is %s\n", group_sid_str));
3345 /* can we get a query for an SID outside our domain ? */
3346 if (!sid_equal(&group_sid, get_global_sam_sid()))
3347 return NT_STATUS_NO_SUCH_GROUP;
3349 sid_append_rid(&group_sid, group_rid);
3350 DEBUG(10, ("lookup on Domain SID\n"));
3352 if(!get_domain_group_from_sid(group_sid, &map))
3353 return NT_STATUS_NO_SUCH_GROUP;
3355 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3356 return NT_STATUS_NO_SUCH_GROUP;
3358 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3359 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3361 if (num_uids!=0 && (rid==NULL || attr==NULL))
3362 return NT_STATUS_NO_MEMORY;
3364 for (i=0; i<num_uids; i++) {
3365 struct passwd *pass;
3366 uint32 urid;
3368 pass = getpwuid_alloc(uid[i]);
3369 if (!pass) continue;
3371 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3372 passwd_free(&pass);
3373 continue;
3376 become_root();
3377 check = pdb_getsampwnam(sam_user, pass->pw_name);
3378 unbecome_root();
3380 if (check != True) {
3381 pdb_free_sam(&sam_user);
3382 passwd_free(&pass);
3383 continue;
3386 urid = pdb_get_user_rid(sam_user);
3387 if (urid == 0) {
3388 pdb_free_sam(&sam_user);
3389 passwd_free(&pass);
3390 continue;
3393 pdb_free_sam(&sam_user);
3394 passwd_free(&pass);
3396 rid[i] = urid;
3397 attr[i] = SID_NAME_USER;
3400 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3402 return NT_STATUS_OK;
3405 /*********************************************************************
3406 _samr_add_aliasmem
3407 *********************************************************************/
3409 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3411 DOM_SID alias_sid;
3412 fstring alias_sid_str;
3413 uid_t uid;
3414 struct passwd *pwd;
3415 struct group *grp;
3416 fstring grp_name;
3417 GROUP_MAP map;
3418 NTSTATUS ret;
3419 SAM_ACCOUNT *sam_user = NULL;
3420 BOOL check;
3421 uint32 acc_granted;
3423 /* Find the policy handle. Open a policy on it. */
3424 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3425 return NT_STATUS_INVALID_HANDLE;
3427 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3428 return r_u->status;
3431 sid_to_string(alias_sid_str, &alias_sid);
3432 DEBUG(10, ("sid is %s\n", alias_sid_str));
3434 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3435 DEBUG(10, ("adding member on Server SID\n"));
3436 if(!get_local_group_from_sid(alias_sid, &map))
3437 return NT_STATUS_NO_SUCH_ALIAS;
3439 } else {
3440 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3441 DEBUG(10, ("adding member on BUILTIN SID\n"));
3442 if( !get_local_group_from_sid(alias_sid, &map))
3443 return NT_STATUS_NO_SUCH_ALIAS;
3445 } else
3446 return NT_STATUS_NO_SUCH_ALIAS;
3449 ret = pdb_init_sam(&sam_user);
3450 if (!NT_STATUS_IS_OK(ret))
3451 return ret;
3453 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3455 if (check != True) {
3456 pdb_free_sam(&sam_user);
3457 return NT_STATUS_NO_SUCH_USER;
3460 /* check a real user exist before we run the script to add a user to a group */
3461 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3462 pdb_free_sam(&sam_user);
3463 return NT_STATUS_NO_SUCH_USER;
3466 pdb_free_sam(&sam_user);
3468 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3469 return NT_STATUS_NO_SUCH_USER;
3472 if ((grp=getgrgid(map.gid)) == NULL) {
3473 passwd_free(&pwd);
3474 return NT_STATUS_NO_SUCH_ALIAS;
3477 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3478 fstrcpy(grp_name, grp->gr_name);
3480 /* if the user is already in the group */
3481 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3482 passwd_free(&pwd);
3483 return NT_STATUS_MEMBER_IN_ALIAS;
3487 * ok, the group exist, the user exist, the user is not in the group,
3488 * we can (finally) add it to the group !
3490 smb_add_user_group(grp_name, pwd->pw_name);
3492 /* check if the user has been added then ... */
3493 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3494 passwd_free(&pwd);
3495 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3498 passwd_free(&pwd);
3499 return NT_STATUS_OK;
3502 /*********************************************************************
3503 _samr_del_aliasmem
3504 *********************************************************************/
3506 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3508 DOM_SID alias_sid;
3509 fstring alias_sid_str;
3510 struct group *grp;
3511 fstring grp_name;
3512 GROUP_MAP map;
3513 SAM_ACCOUNT *sam_pass=NULL;
3514 uint32 acc_granted;
3516 /* Find the policy handle. Open a policy on it. */
3517 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3518 return NT_STATUS_INVALID_HANDLE;
3520 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3521 return r_u->status;
3524 sid_to_string(alias_sid_str, &alias_sid);
3525 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3527 if (!sid_check_is_in_our_domain(&alias_sid) &&
3528 !sid_check_is_in_builtin(&alias_sid)) {
3529 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3530 return NT_STATUS_NO_SUCH_ALIAS;
3533 if( !get_local_group_from_sid(alias_sid, &map))
3534 return NT_STATUS_NO_SUCH_ALIAS;
3536 if ((grp=getgrgid(map.gid)) == NULL)
3537 return NT_STATUS_NO_SUCH_ALIAS;
3539 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3540 fstrcpy(grp_name, grp->gr_name);
3542 /* check if the user exists before trying to remove it from the group */
3543 pdb_init_sam(&sam_pass);
3544 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3545 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3546 pdb_free_sam(&sam_pass);
3547 return NT_STATUS_NO_SUCH_USER;
3550 /* if the user is not in the group */
3551 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3552 pdb_free_sam(&sam_pass);
3553 return NT_STATUS_MEMBER_IN_ALIAS;
3556 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3558 /* check if the user has been removed then ... */
3559 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3560 pdb_free_sam(&sam_pass);
3561 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3564 pdb_free_sam(&sam_pass);
3565 return NT_STATUS_OK;
3568 /*********************************************************************
3569 _samr_add_groupmem
3570 *********************************************************************/
3572 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3574 DOM_SID group_sid;
3575 DOM_SID user_sid;
3576 fstring group_sid_str;
3577 uid_t uid;
3578 struct passwd *pwd;
3579 struct group *grp;
3580 fstring grp_name;
3581 GROUP_MAP map;
3582 NTSTATUS ret;
3583 SAM_ACCOUNT *sam_user=NULL;
3584 BOOL check;
3585 uint32 acc_granted;
3587 /* Find the policy handle. Open a policy on it. */
3588 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3589 return NT_STATUS_INVALID_HANDLE;
3591 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3592 return r_u->status;
3595 sid_to_string(group_sid_str, &group_sid);
3596 DEBUG(10, ("sid is %s\n", group_sid_str));
3598 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3599 return NT_STATUS_NO_SUCH_GROUP;
3601 DEBUG(10, ("lookup on Domain SID\n"));
3603 if(!get_domain_group_from_sid(group_sid, &map))
3604 return NT_STATUS_NO_SUCH_GROUP;
3606 sid_copy(&user_sid, get_global_sam_sid());
3607 sid_append_rid(&user_sid, q_u->rid);
3609 ret = pdb_init_sam(&sam_user);
3610 if (!NT_STATUS_IS_OK(ret))
3611 return ret;
3613 check = pdb_getsampwsid(sam_user, &user_sid);
3615 if (check != True) {
3616 pdb_free_sam(&sam_user);
3617 return NT_STATUS_NO_SUCH_USER;
3620 /* check a real user exist before we run the script to add a user to a group */
3621 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3622 pdb_free_sam(&sam_user);
3623 return NT_STATUS_NO_SUCH_USER;
3626 pdb_free_sam(&sam_user);
3628 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3629 return NT_STATUS_NO_SUCH_USER;
3632 if ((grp=getgrgid(map.gid)) == NULL) {
3633 passwd_free(&pwd);
3634 return NT_STATUS_NO_SUCH_GROUP;
3637 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3638 fstrcpy(grp_name, grp->gr_name);
3640 /* if the user is already in the group */
3641 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3642 passwd_free(&pwd);
3643 return NT_STATUS_MEMBER_IN_GROUP;
3647 * ok, the group exist, the user exist, the user is not in the group,
3649 * we can (finally) add it to the group !
3652 smb_add_user_group(grp_name, pwd->pw_name);
3654 /* check if the user has been added then ... */
3655 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3656 passwd_free(&pwd);
3657 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3660 passwd_free(&pwd);
3661 return NT_STATUS_OK;
3664 /*********************************************************************
3665 _samr_del_groupmem
3666 *********************************************************************/
3668 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3670 DOM_SID group_sid;
3671 DOM_SID user_sid;
3672 SAM_ACCOUNT *sam_pass=NULL;
3673 GROUP_MAP map;
3674 fstring grp_name;
3675 struct group *grp;
3676 uint32 acc_granted;
3679 * delete the group member named q_u->rid
3680 * who is a member of the sid associated with the handle
3681 * the rid is a user's rid as the group is a domain group.
3684 /* Find the policy handle. Open a policy on it. */
3685 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3686 return NT_STATUS_INVALID_HANDLE;
3688 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3689 return r_u->status;
3692 if (!sid_check_is_in_our_domain(&group_sid))
3693 return NT_STATUS_NO_SUCH_GROUP;
3695 sid_copy(&user_sid, get_global_sam_sid());
3696 sid_append_rid(&user_sid, q_u->rid);
3698 if (!get_domain_group_from_sid(group_sid, &map))
3699 return NT_STATUS_NO_SUCH_GROUP;
3701 if ((grp=getgrgid(map.gid)) == NULL)
3702 return NT_STATUS_NO_SUCH_GROUP;
3704 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3705 fstrcpy(grp_name, grp->gr_name);
3707 /* check if the user exists before trying to remove it from the group */
3708 pdb_init_sam(&sam_pass);
3709 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3710 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3711 pdb_free_sam(&sam_pass);
3712 return NT_STATUS_NO_SUCH_USER;
3715 /* if the user is not in the group */
3716 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3717 pdb_free_sam(&sam_pass);
3718 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3721 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3723 /* check if the user has been removed then ... */
3724 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3725 pdb_free_sam(&sam_pass);
3726 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3729 pdb_free_sam(&sam_pass);
3730 return NT_STATUS_OK;
3734 /****************************************************************************
3735 Delete a UNIX user on demand.
3736 ****************************************************************************/
3738 static int smb_delete_user(const char *unix_user)
3740 pstring del_script;
3741 int ret;
3743 /* try winbindd first since it is impossible to determine where
3744 a user came from via NSS. Try the delete user script if this fails
3745 meaning the user did not exist in winbindd's list of accounts */
3747 if ( winbind_delete_user( unix_user ) ) {
3748 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3749 return 0;
3753 /* fall back to 'delete user script' */
3755 pstrcpy(del_script, lp_deluser_script());
3756 if (! *del_script)
3757 return -1;
3758 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3759 ret = smbrun(del_script,NULL);
3760 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3762 return ret;
3765 /*********************************************************************
3766 _samr_delete_dom_user
3767 *********************************************************************/
3769 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3771 DOM_SID user_sid;
3772 SAM_ACCOUNT *sam_pass=NULL;
3773 uint32 acc_granted;
3775 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3777 /* Find the policy handle. Open a policy on it. */
3778 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3779 return NT_STATUS_INVALID_HANDLE;
3781 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3782 return r_u->status;
3785 if (!sid_check_is_in_our_domain(&user_sid))
3786 return NT_STATUS_CANNOT_DELETE;
3788 /* check if the user exists before trying to delete */
3789 pdb_init_sam(&sam_pass);
3790 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3791 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3792 sid_string_static(&user_sid)));
3793 pdb_free_sam(&sam_pass);
3794 return NT_STATUS_NO_SUCH_USER;
3797 /* delete the unix side */
3799 * note: we don't check if the delete really happened
3800 * as the script is not necessary present
3801 * and maybe the sysadmin doesn't want to delete the unix side
3803 smb_delete_user(pdb_get_username(sam_pass));
3805 /* and delete the samba side */
3806 if (!pdb_delete_sam_account(sam_pass)) {
3807 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3808 pdb_free_sam(&sam_pass);
3809 return NT_STATUS_CANNOT_DELETE;
3812 pdb_free_sam(&sam_pass);
3814 if (!close_policy_hnd(p, &q_u->user_pol))
3815 return NT_STATUS_OBJECT_NAME_INVALID;
3817 return NT_STATUS_OK;
3820 /*********************************************************************
3821 _samr_delete_dom_group
3822 *********************************************************************/
3824 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3826 DOM_SID group_sid;
3827 DOM_SID dom_sid;
3828 uint32 group_rid;
3829 fstring group_sid_str;
3830 gid_t gid;
3831 struct group *grp;
3832 GROUP_MAP map;
3833 uint32 acc_granted;
3835 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3837 /* Find the policy handle. Open a policy on it. */
3838 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3839 return NT_STATUS_INVALID_HANDLE;
3841 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3842 return r_u->status;
3845 sid_copy(&dom_sid, &group_sid);
3846 sid_to_string(group_sid_str, &dom_sid);
3847 sid_split_rid(&dom_sid, &group_rid);
3849 DEBUG(10, ("sid is %s\n", group_sid_str));
3851 /* we check if it's our SID before deleting */
3852 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3853 return NT_STATUS_NO_SUCH_GROUP;
3855 DEBUG(10, ("lookup on Domain SID\n"));
3857 if(!get_domain_group_from_sid(group_sid, &map))
3858 return NT_STATUS_NO_SUCH_GROUP;
3860 gid=map.gid;
3862 /* check if group really exists */
3863 if ( (grp=getgrgid(gid)) == NULL)
3864 return NT_STATUS_NO_SUCH_GROUP;
3866 /* we can delete the UNIX group */
3867 smb_delete_group(grp->gr_name);
3869 /* check if the group has been successfully deleted */
3870 if ( (grp=getgrgid(gid)) != NULL)
3871 return NT_STATUS_ACCESS_DENIED;
3873 if(!pdb_delete_group_mapping_entry(group_sid))
3874 return NT_STATUS_ACCESS_DENIED;
3876 if (!close_policy_hnd(p, &q_u->group_pol))
3877 return NT_STATUS_OBJECT_NAME_INVALID;
3879 return NT_STATUS_OK;
3882 /*********************************************************************
3883 _samr_delete_dom_alias
3884 *********************************************************************/
3886 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3888 DOM_SID alias_sid;
3889 DOM_SID dom_sid;
3890 uint32 alias_rid;
3891 fstring alias_sid_str;
3892 gid_t gid;
3893 struct group *grp;
3894 GROUP_MAP map;
3895 uint32 acc_granted;
3897 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3899 /* Find the policy handle. Open a policy on it. */
3900 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3901 return NT_STATUS_INVALID_HANDLE;
3903 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3904 return r_u->status;
3907 sid_copy(&dom_sid, &alias_sid);
3908 sid_to_string(alias_sid_str, &dom_sid);
3909 sid_split_rid(&dom_sid, &alias_rid);
3911 DEBUG(10, ("sid is %s\n", alias_sid_str));
3913 /* we check if it's our SID before deleting */
3914 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3915 return NT_STATUS_NO_SUCH_ALIAS;
3917 DEBUG(10, ("lookup on Local SID\n"));
3919 if(!get_local_group_from_sid(alias_sid, &map))
3920 return NT_STATUS_NO_SUCH_ALIAS;
3922 gid=map.gid;
3924 /* check if group really exists */
3925 if ( (grp=getgrgid(gid)) == NULL)
3926 return NT_STATUS_NO_SUCH_ALIAS;
3928 /* we can delete the UNIX group */
3929 smb_delete_group(grp->gr_name);
3931 /* check if the group has been successfully deleted */
3932 if ( (grp=getgrgid(gid)) != NULL)
3933 return NT_STATUS_ACCESS_DENIED;
3935 /* don't check if we removed it as it could be an un-mapped group */
3936 pdb_delete_group_mapping_entry(alias_sid);
3938 if (!close_policy_hnd(p, &q_u->alias_pol))
3939 return NT_STATUS_OBJECT_NAME_INVALID;
3941 return NT_STATUS_OK;
3944 /*********************************************************************
3945 _samr_create_dom_group
3946 *********************************************************************/
3948 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3950 DOM_SID dom_sid;
3951 DOM_SID info_sid;
3952 fstring name;
3953 fstring sid_string;
3954 struct group *grp;
3955 struct samr_info *info;
3956 uint32 acc_granted;
3957 gid_t gid;
3959 /* Find the policy handle. Open a policy on it. */
3960 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3961 return NT_STATUS_INVALID_HANDLE;
3963 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3964 return r_u->status;
3967 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3968 return NT_STATUS_ACCESS_DENIED;
3970 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3972 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3974 /* check if group already exist */
3975 if ((grp=getgrnam(name)) != NULL)
3976 return NT_STATUS_GROUP_EXISTS;
3978 /* we can create the UNIX group */
3979 if (smb_create_group(name, &gid) != 0)
3980 return NT_STATUS_ACCESS_DENIED;
3982 /* check if the group has been successfully created */
3983 if ((grp=getgrgid(gid)) == NULL)
3984 return NT_STATUS_ACCESS_DENIED;
3986 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3988 /* add the group to the mapping table */
3989 sid_copy(&info_sid, get_global_sam_sid());
3990 sid_append_rid(&info_sid, r_u->rid);
3991 sid_to_string(sid_string, &info_sid);
3993 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3994 return NT_STATUS_ACCESS_DENIED;
3996 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3997 return NT_STATUS_NO_MEMORY;
3999 /* get a (unique) handle. open a policy on it. */
4000 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4001 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4003 return NT_STATUS_OK;
4006 /*********************************************************************
4007 _samr_create_dom_alias
4008 *********************************************************************/
4010 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4012 DOM_SID dom_sid;
4013 DOM_SID info_sid;
4014 fstring name;
4015 fstring sid_string;
4016 struct group *grp;
4017 struct samr_info *info;
4018 uint32 acc_granted;
4019 gid_t gid;
4021 /* Find the policy handle. Open a policy on it. */
4022 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4023 return NT_STATUS_INVALID_HANDLE;
4025 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4026 return r_u->status;
4029 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4030 return NT_STATUS_ACCESS_DENIED;
4032 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4034 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4036 /* check if group already exists */
4037 if ( (grp=getgrnam(name)) != NULL)
4038 return NT_STATUS_GROUP_EXISTS;
4040 /* we can create the UNIX group */
4041 if (smb_create_group(name, &gid) != 0)
4042 return NT_STATUS_ACCESS_DENIED;
4044 /* check if the group has been successfully created */
4045 if ((grp=getgrgid(gid)) == NULL)
4046 return NT_STATUS_ACCESS_DENIED;
4048 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4050 sid_copy(&info_sid, get_global_sam_sid());
4051 sid_append_rid(&info_sid, r_u->rid);
4052 sid_to_string(sid_string, &info_sid);
4054 /* add the group to the mapping table */
4055 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
4056 return NT_STATUS_ACCESS_DENIED;
4058 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4059 return NT_STATUS_NO_MEMORY;
4061 /* get a (unique) handle. open a policy on it. */
4062 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4063 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4065 return NT_STATUS_OK;
4068 /*********************************************************************
4069 _samr_query_groupinfo
4071 sends the name/comment pair of a domain group
4072 level 1 send also the number of users of that group
4073 *********************************************************************/
4075 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4077 DOM_SID group_sid;
4078 GROUP_MAP map;
4079 uid_t *uid=NULL;
4080 int num_uids=0;
4081 GROUP_INFO_CTR *ctr;
4082 uint32 acc_granted;
4084 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4085 return NT_STATUS_INVALID_HANDLE;
4087 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4088 return r_u->status;
4091 if (!get_domain_group_from_sid(group_sid, &map))
4092 return NT_STATUS_INVALID_HANDLE;
4094 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4095 if (ctr==NULL)
4096 return NT_STATUS_NO_MEMORY;
4098 switch (q_u->switch_level) {
4099 case 1:
4100 ctr->switch_value1 = 1;
4101 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4102 return NT_STATUS_NO_SUCH_GROUP;
4103 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4104 SAFE_FREE(uid);
4105 break;
4106 case 3:
4107 ctr->switch_value1 = 3;
4108 init_samr_group_info3(&ctr->group.info3);
4109 break;
4110 case 4:
4111 ctr->switch_value1 = 4;
4112 init_samr_group_info4(&ctr->group.info4, map.comment);
4113 break;
4114 default:
4115 return NT_STATUS_INVALID_INFO_CLASS;
4118 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4120 return NT_STATUS_OK;
4123 /*********************************************************************
4124 _samr_set_groupinfo
4126 update a domain group's comment.
4127 *********************************************************************/
4129 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4131 DOM_SID group_sid;
4132 GROUP_MAP map;
4133 GROUP_INFO_CTR *ctr;
4134 uint32 acc_granted;
4136 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4137 return NT_STATUS_INVALID_HANDLE;
4139 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4140 return r_u->status;
4143 if (!get_domain_group_from_sid(group_sid, &map))
4144 return NT_STATUS_NO_SUCH_GROUP;
4146 ctr=q_u->ctr;
4148 switch (ctr->switch_value1) {
4149 case 1:
4150 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4151 break;
4152 case 4:
4153 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4154 break;
4155 default:
4156 return NT_STATUS_INVALID_INFO_CLASS;
4159 if(!pdb_update_group_mapping_entry(&map)) {
4160 return NT_STATUS_NO_SUCH_GROUP;
4163 return NT_STATUS_OK;
4166 /*********************************************************************
4167 _samr_set_aliasinfo
4169 update an alias's comment.
4170 *********************************************************************/
4172 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4174 DOM_SID group_sid;
4175 GROUP_MAP map;
4176 ALIAS_INFO_CTR *ctr;
4177 uint32 acc_granted;
4179 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4180 return NT_STATUS_INVALID_HANDLE;
4182 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4183 return r_u->status;
4186 if (!get_local_group_from_sid(group_sid, &map))
4187 return NT_STATUS_NO_SUCH_GROUP;
4189 ctr=&q_u->ctr;
4191 switch (ctr->switch_value1) {
4192 case 3:
4193 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4194 break;
4195 default:
4196 return NT_STATUS_INVALID_INFO_CLASS;
4199 if(!pdb_update_group_mapping_entry(&map)) {
4200 return NT_STATUS_NO_SUCH_GROUP;
4203 return NT_STATUS_OK;
4206 /*********************************************************************
4207 _samr_get_dom_pwinfo
4208 *********************************************************************/
4210 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4212 /* Perform access check. Since this rpc does not require a
4213 policy handle it will not be caught by the access checks on
4214 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4216 if (!pipe_access_check(p)) {
4217 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4218 r_u->status = NT_STATUS_ACCESS_DENIED;
4219 return r_u->status;
4222 /* Actually, returning zeros here works quite well :-). */
4224 return NT_STATUS_OK;
4227 /*********************************************************************
4228 _samr_open_group
4229 *********************************************************************/
4231 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4233 DOM_SID sid;
4234 DOM_SID info_sid;
4235 GROUP_MAP map;
4236 struct samr_info *info;
4237 SEC_DESC *psd = NULL;
4238 uint32 acc_granted;
4239 uint32 des_access;
4240 size_t sd_size;
4241 NTSTATUS status;
4242 fstring sid_string;
4244 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4245 return NT_STATUS_INVALID_HANDLE;
4247 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4248 return status;
4251 /*check if access can be granted as requested by client. */
4252 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4253 se_map_generic(&des_access,&grp_generic_mapping);
4254 if (!NT_STATUS_IS_OK(status =
4255 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4256 des_access, &acc_granted, "_samr_open_group"))) {
4257 return status;
4261 /* this should not be hard-coded like this */
4262 if (!sid_equal(&sid, get_global_sam_sid()))
4263 return NT_STATUS_ACCESS_DENIED;
4265 sid_copy(&info_sid, get_global_sam_sid());
4266 sid_append_rid(&info_sid, q_u->rid_group);
4267 sid_to_string(sid_string, &info_sid);
4269 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4270 return NT_STATUS_NO_MEMORY;
4272 info->acc_granted = acc_granted;
4274 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4276 /* check if that group really exists */
4277 if (!get_domain_group_from_sid(info->sid, &map))
4278 return NT_STATUS_NO_SUCH_GROUP;
4280 /* get a (unique) handle. open a policy on it. */
4281 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4282 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4284 return NT_STATUS_OK;
4287 /*********************************************************************
4288 _samr_remove_user_foreign_domain
4289 *********************************************************************/
4291 NTSTATUS _samr_remove_user_foreign_domain(pipes_struct *p,
4292 SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN *q_u,
4293 SAMR_R_REMOVE_USER_FOREIGN_DOMAIN *r_u)
4295 DOM_SID user_sid, dom_sid;
4296 SAM_ACCOUNT *sam_pass=NULL;
4297 uint32 acc_granted;
4299 sid_copy( &user_sid, &q_u->sid.sid );
4301 DEBUG(5,("_samr_remove_user_foreign_domain: removing user [%s]\n",
4302 sid_string_static(&user_sid)));
4304 /* Find the policy handle. Open a policy on it. */
4306 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4307 return NT_STATUS_INVALID_HANDLE;
4309 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted,
4310 STD_RIGHT_DELETE_ACCESS, "_samr_remove_user_foreign_domain")))
4312 return r_u->status;
4315 if ( !sid_check_is_in_our_domain(&user_sid) ) {
4316 DEBUG(5,("_samr_remove_user_foreign_domain: user not is our domain!\n"));
4317 return NT_STATUS_NO_SUCH_USER;
4320 /* check if the user exists before trying to delete */
4322 pdb_init_sam(&sam_pass);
4324 if ( !pdb_getsampwsid(sam_pass, &user_sid) ) {
4326 DEBUG(5,("_samr_remove_user_foreign_domain:User %s doesn't exist.\n",
4327 sid_string_static(&user_sid)));
4329 pdb_free_sam(&sam_pass);
4331 return NT_STATUS_NO_SUCH_USER;
4335 * delete the unix side
4337 * note: we don't check if the delete really happened
4338 * as the script is not necessary present
4339 * and maybe the sysadmin doesn't want to delete the unix side
4342 smb_delete_user(pdb_get_username(sam_pass));
4344 /* and delete the samba side */
4346 if ( !pdb_delete_sam_account(sam_pass) ) {
4348 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
4349 pdb_free_sam(&sam_pass);
4351 return NT_STATUS_CANNOT_DELETE;
4354 pdb_free_sam(&sam_pass);
4356 return NT_STATUS_OK;
4359 /*******************************************************************
4360 _samr_unknown_2e
4361 ********************************************************************/
4363 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4365 struct samr_info *info = NULL;
4366 SAM_UNK_CTR *ctr;
4367 uint32 min_pass_len,pass_hist,flag;
4368 time_t u_expire, u_min_age;
4369 NTTIME nt_expire, nt_min_age;
4371 time_t u_lock_duration, u_reset_time;
4372 NTTIME nt_lock_duration, nt_reset_time;
4373 uint32 lockout;
4375 time_t u_logout;
4376 NTTIME nt_logout;
4378 uint32 num_users=0, num_groups=0, num_aliases=0;
4380 uint32 account_policy_temp;
4382 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4383 return NT_STATUS_NO_MEMORY;
4385 ZERO_STRUCTP(ctr);
4387 r_u->status = NT_STATUS_OK;
4389 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4391 /* find the policy handle. open a policy on it. */
4392 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4393 return NT_STATUS_INVALID_HANDLE;
4395 switch (q_u->switch_value) {
4396 case 0x01:
4397 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4398 min_pass_len = account_policy_temp;
4400 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4401 pass_hist = account_policy_temp;
4403 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4404 flag = account_policy_temp;
4406 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4407 u_expire = account_policy_temp;
4409 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4410 u_min_age = account_policy_temp;
4412 unix_to_nt_time_abs(&nt_expire, u_expire);
4413 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4415 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4416 flag, nt_expire, nt_min_age);
4417 break;
4418 case 0x02:
4419 become_root();
4420 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4421 unbecome_root();
4422 if (!NT_STATUS_IS_OK(r_u->status)) {
4423 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4424 return r_u->status;
4426 num_users=info->disp_info.num_user_account;
4427 free_samr_db(info);
4429 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4430 if (NT_STATUS_IS_ERR(r_u->status)) {
4431 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4432 return r_u->status;
4434 num_groups=info->disp_info.num_group_account;
4435 free_samr_db(info);
4437 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4438 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4439 num_users, num_groups, num_aliases);
4440 break;
4441 case 0x03:
4442 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4443 u_logout = account_policy_temp;
4445 unix_to_nt_time_abs(&nt_logout, u_logout);
4447 init_unk_info3(&ctr->info.inf3, nt_logout);
4448 break;
4449 case 0x05:
4450 init_unk_info5(&ctr->info.inf5, global_myname());
4451 break;
4452 case 0x06:
4453 init_unk_info6(&ctr->info.inf6);
4454 break;
4455 case 0x07:
4456 init_unk_info7(&ctr->info.inf7);
4457 break;
4458 case 0x0c:
4459 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4460 u_lock_duration = account_policy_temp;
4462 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4463 u_reset_time = account_policy_temp;
4465 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4466 lockout = account_policy_temp;
4468 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4469 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4471 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4472 break;
4473 default:
4474 return NT_STATUS_INVALID_INFO_CLASS;
4477 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4479 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4481 return r_u->status;
4484 /*******************************************************************
4485 _samr_
4486 ********************************************************************/
4488 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4490 time_t u_expire, u_min_age;
4491 time_t u_logout;
4492 time_t u_lock_duration, u_reset_time;
4494 r_u->status = NT_STATUS_OK;
4496 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4498 /* find the policy handle. open a policy on it. */
4499 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4500 return NT_STATUS_INVALID_HANDLE;
4502 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4504 switch (q_u->switch_value) {
4505 case 0x01:
4506 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4507 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4509 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4510 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4511 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4512 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4513 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4514 break;
4515 case 0x02:
4516 break;
4517 case 0x03:
4518 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4519 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4520 break;
4521 case 0x05:
4522 break;
4523 case 0x06:
4524 break;
4525 case 0x07:
4526 break;
4527 case 0x0c:
4528 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4529 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4531 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4532 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4533 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4534 break;
4535 default:
4536 return NT_STATUS_INVALID_INFO_CLASS;
4539 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4541 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4543 return r_u->status;