get rid of some sompiler warnings on IRIX
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_samr_nt.c
bloba338b5eb4d8f02a9497b9c545e42394e042e9f05
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.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 * This is the implementation of the SAMR code.
31 #include "includes.h"
33 #undef DBGC_CLASS
34 #define DBGC_CLASS DBGC_RPC_SRV
36 extern DOM_SID global_sid_Builtin;
38 extern rid_name domain_group_rids[];
39 extern rid_name domain_alias_rids[];
40 extern rid_name builtin_alias_rids[];
43 typedef struct _disp_info {
44 BOOL user_dbloaded;
45 uint32 num_user_account;
46 SAM_ACCOUNT *disp_user_info;
47 BOOL group_dbloaded;
48 uint32 num_group_account;
49 DOMAIN_GRP *disp_group_info;
50 } DISP_INFO;
52 struct samr_info {
53 /* for use by the \PIPE\samr policy */
54 DOM_SID sid;
55 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
56 uint32 acc_granted;
57 uint16 acb_mask;
58 BOOL all_machines;
59 DISP_INFO disp_info;
61 TALLOC_CTX *mem_ctx;
64 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
65 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
66 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
67 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
68 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
70 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
72 /*******************************************************************
73 Checks if access to an object should be granted, and returns that
74 level of access for further checks.
75 ********************************************************************/
77 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
78 uint32 *acc_granted, const char *debug)
80 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
82 if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
83 *acc_granted = des_access;
84 if (geteuid() == sec_initial_uid()) {
85 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
86 debug, des_access));
87 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
88 status = NT_STATUS_OK;
90 else {
91 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
92 debug, des_access));
95 return status;
98 /*******************************************************************
99 Checks if access to a function can be granted
100 ********************************************************************/
102 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
104 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
105 debug, acc_granted, acc_required));
106 if ((acc_granted & acc_required) != acc_required) {
107 if (geteuid() == sec_initial_uid()) {
108 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
109 debug, acc_granted, acc_required));
110 DEBUGADD(4,("but overwritten by euid == 0\n"));
111 return NT_STATUS_OK;
113 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
114 debug, acc_granted, acc_required));
115 return NT_STATUS_ACCESS_DENIED;
117 return NT_STATUS_OK;
121 /*******************************************************************
122 Create a samr_info struct.
123 ********************************************************************/
125 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
127 struct samr_info *info;
128 fstring sid_str;
129 TALLOC_CTX *mem_ctx;
131 if (psid) {
132 sid_to_string(sid_str, psid);
133 } else {
134 fstrcpy(sid_str,"(NULL)");
137 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
139 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
140 return NULL;
142 ZERO_STRUCTP(info);
143 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
144 if (psid) {
145 sid_copy( &info->sid, psid);
146 } else {
147 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
149 info->mem_ctx = mem_ctx;
150 return info;
153 /*******************************************************************
154 Function to free the per handle data.
155 ********************************************************************/
157 static void free_samr_users(struct samr_info *info)
159 int i;
161 if (info->disp_info.user_dbloaded){
162 for (i=0; i<info->disp_info.num_user_account; i++) {
163 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
164 /* Not really a free, actually a 'clear' */
165 pdb_free_sam(&sam);
168 info->disp_info.user_dbloaded=False;
169 info->disp_info.num_user_account=0;
172 /*******************************************************************
173 Function to free the per handle data.
174 ********************************************************************/
176 static void free_samr_db(struct samr_info *info)
178 /* Groups are talloced */
180 free_samr_users(info);
182 info->disp_info.group_dbloaded=False;
183 info->disp_info.num_group_account=0;
186 static void free_samr_info(void *ptr)
188 struct samr_info *info=(struct samr_info *) ptr;
190 free_samr_db(info);
191 talloc_destroy(info->mem_ctx);
194 /*******************************************************************
195 Ensure password info is never given out. Paranioa... JRA.
196 ********************************************************************/
198 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
201 if (!sam_pass)
202 return;
204 /* These now zero out the old password */
206 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
207 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
211 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
213 SAM_ACCOUNT *pwd = NULL;
214 SAM_ACCOUNT *pwd_array = NULL;
215 NTSTATUS nt_status = NT_STATUS_OK;
216 TALLOC_CTX *mem_ctx = info->mem_ctx;
218 DEBUG(10,("load_sampwd_entries\n"));
220 /* if the snapshoot is already loaded, return */
221 if ((info->disp_info.user_dbloaded==True)
222 && (info->acb_mask == acb_mask)
223 && (info->all_machines == all_machines)) {
224 DEBUG(10,("load_sampwd_entries: already in memory\n"));
225 return NT_STATUS_OK;
228 free_samr_users(info);
230 if (!pdb_setsampwent(False)) {
231 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
232 return NT_STATUS_ACCESS_DENIED;
235 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
236 && pdb_getsampwent(pwd) == True; pwd=NULL) {
238 if (all_machines) {
239 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
240 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
241 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
242 pdb_free_sam(&pwd);
243 continue;
245 } else {
246 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
247 pdb_free_sam(&pwd);
248 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
249 continue;
253 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
254 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
256 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
257 pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info,
258 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
260 if (pwd_array==NULL)
261 return NT_STATUS_NO_MEMORY;
263 info->disp_info.disp_user_info=pwd_array;
266 /* Copy the SAM_ACCOUNT into the array */
267 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
269 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
271 info->disp_info.num_user_account++;
274 pdb_endsampwent();
276 /* the snapshoot is in memory, we're ready to enumerate fast */
278 info->acb_mask = acb_mask;
279 info->all_machines = all_machines;
280 info->disp_info.user_dbloaded=True;
282 DEBUG(10,("load_sampwd_entries: done\n"));
284 return nt_status;
287 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
289 GROUP_MAP *map=NULL;
290 DOMAIN_GRP *grp_array = NULL;
291 uint32 group_entries = 0;
292 uint32 i;
293 TALLOC_CTX *mem_ctx = info->mem_ctx;
295 DEBUG(10,("load_group_domain_entries\n"));
297 /* if the snapshoot is already loaded, return */
298 if (info->disp_info.group_dbloaded==True) {
299 DEBUG(10,("load_group_domain_entries: already in memory\n"));
300 return NT_STATUS_OK;
304 become_root();
306 if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED)) {
307 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
308 return NT_STATUS_NO_MEMORY;
311 unbecome_root();
313 info->disp_info.num_group_account=group_entries;
315 grp_array=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
316 if (group_entries!=0 && grp_array==NULL) {
317 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
318 SAFE_FREE(map);
319 return NT_STATUS_NO_MEMORY;
322 info->disp_info.disp_group_info=grp_array;
324 for (i=0; i<group_entries; i++) {
325 fstrcpy(grp_array[i].name, map[i].nt_name);
326 fstrcpy(grp_array[i].comment, map[i].comment);
327 sid_split_rid(&map[i].sid, &grp_array[i].rid);
328 grp_array[i].attr=SID_NAME_DOM_GRP;
331 SAFE_FREE(map);
333 /* the snapshoot is in memory, we're ready to enumerate fast */
335 info->disp_info.group_dbloaded=True;
337 DEBUG(10,("load_group_domain_entries: done\n"));
339 return NT_STATUS_OK;
343 /*******************************************************************
344 _samr_close_hnd
345 ********************************************************************/
347 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
349 r_u->status = NT_STATUS_OK;
351 /* close the policy handle */
352 if (!close_policy_hnd(p, &q_u->pol))
353 return NT_STATUS_OBJECT_NAME_INVALID;
355 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
357 return r_u->status;
360 /*******************************************************************
361 samr_reply_open_domain
362 ********************************************************************/
364 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
366 struct samr_info *info;
367 SEC_DESC *psd = NULL;
368 uint32 acc_granted;
369 uint32 des_access = q_u->flags;
370 size_t sd_size;
371 NTSTATUS status;
373 r_u->status = NT_STATUS_OK;
375 /* find the connection policy handle. */
376 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
377 return NT_STATUS_INVALID_HANDLE;
379 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
380 return status;
383 /*check if access can be granted as requested by client. */
384 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
385 se_map_generic(&des_access,&dom_generic_mapping);
387 if (!NT_STATUS_IS_OK(status =
388 access_check_samr_object(psd, p->pipe_user.nt_user_token,
389 des_access, &acc_granted, "_samr_open_domain"))) {
390 return status;
393 /* associate the domain SID with the (unique) handle. */
394 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
395 return NT_STATUS_NO_MEMORY;
396 info->acc_granted = acc_granted;
398 /* get a (unique) handle. open a policy on it. */
399 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
400 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
402 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
404 return r_u->status;
407 /*******************************************************************
408 _samr_get_usrdom_pwinfo
409 ********************************************************************/
411 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
413 struct samr_info *info = NULL;
415 r_u->status = NT_STATUS_OK;
417 /* find the policy handle. open a policy on it. */
418 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
419 return NT_STATUS_INVALID_HANDLE;
421 if (!sid_check_is_in_our_domain(&info->sid))
422 return NT_STATUS_OBJECT_TYPE_MISMATCH;
424 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
426 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
429 * NT sometimes return NT_STATUS_ACCESS_DENIED
430 * I don't know yet why.
433 return r_u->status;
436 /*******************************************************************
437 samr_make_dom_obj_sd
438 ********************************************************************/
440 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
442 extern DOM_SID global_sid_World;
443 DOM_SID adm_sid;
444 DOM_SID act_sid;
446 SEC_ACE ace[3];
447 SEC_ACCESS mask;
449 SEC_ACL *psa = NULL;
451 sid_copy(&adm_sid, &global_sid_Builtin);
452 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
454 sid_copy(&act_sid, &global_sid_Builtin);
455 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
457 /*basic access for every one*/
458 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
459 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
461 /*full access for builtin aliases Administrators and Account Operators*/
462 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
463 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
464 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
466 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
467 return NT_STATUS_NO_MEMORY;
469 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
470 return NT_STATUS_NO_MEMORY;
472 return NT_STATUS_OK;
475 /*******************************************************************
476 samr_make_usr_obj_sd
477 ********************************************************************/
479 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
481 extern DOM_SID global_sid_World;
482 DOM_SID adm_sid;
483 DOM_SID act_sid;
485 SEC_ACE ace[4];
486 SEC_ACCESS mask;
488 SEC_ACL *psa = NULL;
490 sid_copy(&adm_sid, &global_sid_Builtin);
491 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
493 sid_copy(&act_sid, &global_sid_Builtin);
494 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
496 /*basic access for every one*/
497 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
498 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
500 /*full access for builtin aliases Administrators and Account Operators*/
501 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
502 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
503 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
505 /*extended access for the user*/
506 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
507 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
509 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
510 return NT_STATUS_NO_MEMORY;
512 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
513 return NT_STATUS_NO_MEMORY;
515 return NT_STATUS_OK;
518 /*******************************************************************
519 samr_make_grp_obj_sd
520 ********************************************************************/
522 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
524 extern DOM_SID global_sid_World;
525 DOM_SID adm_sid;
526 DOM_SID act_sid;
528 SEC_ACE ace[3];
529 SEC_ACCESS mask;
531 SEC_ACL *psa = NULL;
533 sid_copy(&adm_sid, &global_sid_Builtin);
534 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
536 sid_copy(&act_sid, &global_sid_Builtin);
537 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
539 /*basic access for every one*/
540 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
541 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
543 /*full access for builtin aliases Administrators and Account Operators*/
544 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
545 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
546 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
548 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
549 return NT_STATUS_NO_MEMORY;
551 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
552 return NT_STATUS_NO_MEMORY;
554 return NT_STATUS_OK;
557 /*******************************************************************
558 samr_make_ali_obj_sd
559 ********************************************************************/
561 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
563 extern DOM_SID global_sid_World;
564 DOM_SID adm_sid;
565 DOM_SID act_sid;
567 SEC_ACE ace[3];
568 SEC_ACCESS mask;
570 SEC_ACL *psa = NULL;
572 sid_copy(&adm_sid, &global_sid_Builtin);
573 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
575 sid_copy(&act_sid, &global_sid_Builtin);
576 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
578 /*basic access for every one*/
579 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
580 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
582 /*full access for builtin aliases Administrators and Account Operators*/
583 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
584 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
585 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
587 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
588 return NT_STATUS_NO_MEMORY;
590 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, sd_size)) == NULL)
591 return NT_STATUS_NO_MEMORY;
593 return NT_STATUS_OK;
596 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
598 struct samr_info *info = NULL;
600 /* find the policy handle. open a policy on it. */
601 if (!find_policy_by_hnd(p, pol, (void **)&info))
602 return False;
604 if (!info)
605 return False;
607 *sid = info->sid;
608 *acc_granted = info->acc_granted;
609 return True;
612 /*******************************************************************
613 _samr_set_sec_obj
614 ********************************************************************/
616 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
618 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
619 return NT_STATUS_NOT_IMPLEMENTED;
623 /*******************************************************************
624 _samr_query_sec_obj
625 ********************************************************************/
627 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
629 DOM_SID pol_sid;
630 fstring str_sid;
631 SEC_DESC * psd = NULL;
632 size_t sd_size;
633 uint32 acc_granted;
635 r_u->status = NT_STATUS_OK;
637 /* Get the SID. */
638 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
639 return NT_STATUS_INVALID_HANDLE;
643 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
645 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
647 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
648 if (pol_sid.sid_rev_num == 0)
650 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
651 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
653 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
656 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
657 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
659 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
661 /* TODO: Builtin probably needs a different SD with restricted write access*/
662 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
663 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
665 else if (sid_check_is_in_our_domain(&pol_sid) ||
666 sid_check_is_in_builtin(&pol_sid))
668 /* TODO: different SDs have to be generated for aliases groups and users.
669 Currently all three get a default user SD */
670 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
671 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
673 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
675 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
676 return NT_STATUS_NO_MEMORY;
678 if (NT_STATUS_IS_OK(r_u->status))
679 r_u->ptr = 1;
681 return r_u->status;
684 /*******************************************************************
685 makes a SAM_ENTRY / UNISTR2* structure from a user list.
686 ********************************************************************/
688 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
689 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
690 DOM_SID *domain_sid)
692 uint32 i;
693 SAM_ENTRY *sam;
694 UNISTR2 *uni_name;
695 SAM_ACCOUNT *pwd = NULL;
696 UNISTR2 uni_temp_name;
697 const char *temp_name;
698 const DOM_SID *user_sid;
699 uint32 user_rid;
700 fstring user_sid_string;
701 fstring domain_sid_string;
703 *sam_pp = NULL;
704 *uni_name_pp = NULL;
706 if (num_entries == 0)
707 return NT_STATUS_OK;
709 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
711 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
713 if (sam == NULL || uni_name == NULL) {
714 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
715 return NT_STATUS_NO_MEMORY;
718 for (i = 0; i < num_entries; i++) {
719 pwd = &disp_user_info[i+start_idx];
720 temp_name = pdb_get_username(pwd);
721 init_unistr2(&uni_temp_name, temp_name, strlen(temp_name)+1);
722 user_sid = pdb_get_user_sid(pwd);
724 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
725 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
726 "the domain sid %s. Failing operation.\n",
727 temp_name,
728 sid_to_string(user_sid_string, user_sid),
729 sid_to_string(domain_sid_string, domain_sid)));
730 return NT_STATUS_UNSUCCESSFUL;
733 init_sam_entry(&sam[i], uni_temp_name.uni_str_len, user_rid);
734 copy_unistr2(&uni_name[i], &uni_temp_name);
737 *sam_pp = sam;
738 *uni_name_pp = uni_name;
739 return NT_STATUS_OK;
742 /*******************************************************************
743 samr_reply_enum_dom_users
744 ********************************************************************/
746 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
747 SAMR_R_ENUM_DOM_USERS *r_u)
749 struct samr_info *info = NULL;
750 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
751 int num_account;
752 uint32 enum_context=q_u->start_idx;
753 uint32 max_size=q_u->max_size;
754 uint32 temp_size;
755 enum remote_arch_types ra_type = get_remote_arch();
756 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
757 uint32 max_entries = max_sam_entries;
758 DOM_SID domain_sid;
760 r_u->status = NT_STATUS_OK;
762 /* find the policy handle. open a policy on it. */
763 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
764 return NT_STATUS_INVALID_HANDLE;
766 domain_sid = info->sid;
768 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
769 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
770 "_samr_enum_dom_users"))) {
771 return r_u->status;
774 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
776 become_root();
777 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
778 unbecome_root();
780 if (!NT_STATUS_IS_OK(r_u->status))
781 return r_u->status;
783 num_account = info->disp_info.num_user_account;
785 if (enum_context > num_account) {
786 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
787 return NT_STATUS_OK;
790 /* verify we won't overflow */
791 if (max_entries > num_account-enum_context) {
792 max_entries = num_account-enum_context;
793 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
796 /* calculate the size and limit on the number of entries we will return */
797 temp_size=max_entries*struct_size;
799 if (temp_size>max_size) {
800 max_entries=MIN((max_size/struct_size),max_entries);;
801 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
805 * Note from JRA. total_entries is not being used here. Currently if there is a
806 * large user base then it looks like NT will enumerate until get_sampwd_entries
807 * returns False due to num_entries being zero. This will cause an access denied
808 * return. I don't think this is right and needs further investigation. Note that
809 * this is also the same in the TNG code (I don't think that has been tested with
810 * a very large user list as MAX_SAM_ENTRIES is set to 600).
812 * I also think that one of the 'num_entries' return parameters is probably
813 * the "max entries" parameter - but in the TNG code they're all currently set to the same
814 * value (again I think this is wrong).
817 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
818 max_entries, enum_context,
819 info->disp_info.disp_user_info,
820 &domain_sid);
822 if (!NT_STATUS_IS_OK(r_u->status))
823 return r_u->status;
825 if (enum_context+max_entries < num_account)
826 r_u->status = STATUS_MORE_ENTRIES;
828 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
830 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
832 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
834 return r_u->status;
837 /*******************************************************************
838 makes a SAM_ENTRY / UNISTR2* structure from a group list.
839 ********************************************************************/
841 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
842 uint32 num_sam_entries, DOMAIN_GRP *grp)
844 uint32 i;
845 SAM_ENTRY *sam;
846 UNISTR2 *uni_name;
848 *sam_pp = NULL;
849 *uni_name_pp = NULL;
851 if (num_sam_entries == 0)
852 return;
854 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
856 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
858 if (sam == NULL || uni_name == NULL) {
859 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
860 return;
863 for (i = 0; i < num_sam_entries; i++) {
865 * JRA. I think this should include the null. TNG does not.
867 int len = strlen(grp[i].name)+1;
869 init_sam_entry(&sam[i], len, grp[i].rid);
870 init_unistr2(&uni_name[i], grp[i].name, len);
873 *sam_pp = sam;
874 *uni_name_pp = uni_name;
877 /*******************************************************************
878 Get the group entries - similar to get_sampwd_entries().
879 ********************************************************************/
881 static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
882 uint32 *p_num_entries, uint32 max_entries)
884 fstring sid_str;
885 uint32 num_entries = 0;
886 int i;
887 GROUP_MAP smap;
888 GROUP_MAP *map = NULL;
890 sid_to_string(sid_str, sid);
891 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
893 *p_num_entries = 0;
895 /* well-known aliases */
896 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
898 pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED);
900 if (num_entries != 0) {
901 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
902 if (*d_grp==NULL)
903 return NT_STATUS_NO_MEMORY;
905 for(i=0; i<num_entries && i<max_entries; i++) {
906 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
907 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
911 SAFE_FREE(map);
913 } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
914 struct sys_grent *glist;
915 struct sys_grent *grp;
916 gid_t winbind_gid_low, winbind_gid_high;
917 BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
919 /* local aliases */
920 /* we return the UNIX groups here. This seems to be the right */
921 /* thing to do, since NT member servers return their local */
922 /* groups in the same situation. */
924 /* use getgrent_list() to retrieve the list of groups to avoid
925 * problems with getgrent possible infinite loop by internal
926 * libc grent structures overwrites by called functions */
927 grp = glist = getgrent_list();
928 if (grp == NULL)
929 return NT_STATUS_NO_MEMORY;
931 for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
932 uint32 trid;
934 if(!pdb_getgrgid(&smap, grp->gr_gid))
935 continue;
937 if (smap.sid_name_use!=SID_NAME_ALIAS) {
938 continue;
941 sid_split_rid(&smap.sid, &trid);
943 if (!sid_equal(sid, &smap.sid))
944 continue;
946 /* Don't return winbind groups as they are not local! */
947 if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
948 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
949 continue;
952 /* Don't return user private groups... */
954 if (Get_Pwnam(smap.nt_name) != 0) {
955 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
956 continue;
959 for( i = 0; i < num_entries; i++)
960 if ( (*d_grp)[i].rid == trid )
961 break;
963 if ( i < num_entries ) {
964 continue; /* rid was there, dup! */
967 /* JRA - added this for large group db enumeration... */
969 if (start_idx > 0) {
970 /* skip the requested number of entries.
971 not very efficient, but hey...
973 start_idx--;
974 continue;
977 *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
978 if (*d_grp==NULL) {
979 grent_free(glist);
980 return NT_STATUS_NO_MEMORY;
983 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
984 (*d_grp)[num_entries].rid = trid;
985 num_entries++;
986 DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
989 grent_free(glist);
992 *p_num_entries = num_entries;
994 DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
996 if (num_entries >= max_entries)
997 return STATUS_MORE_ENTRIES;
998 return NT_STATUS_OK;
1001 /*******************************************************************
1002 Get the group entries - similar to get_sampwd_entries().
1003 ********************************************************************/
1005 static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
1006 uint32 *p_num_entries, uint32 max_entries)
1008 GROUP_MAP *map=NULL;
1009 int i;
1010 uint32 group_entries = 0;
1011 uint32 num_entries = 0;
1013 *p_num_entries = 0;
1015 /* access checks for the users were performed higher up. become/unbecome_root()
1016 needed for some passdb backends to enumerate groups */
1018 become_root();
1019 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
1020 unbecome_root();
1022 num_entries=group_entries-start_idx;
1024 /* limit the number of entries */
1025 if (num_entries>max_entries) {
1026 DEBUG(5,("Limiting to %d entries\n", max_entries));
1027 num_entries=max_entries;
1030 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
1031 if (num_entries!=0 && *d_grp==NULL){
1032 SAFE_FREE(map);
1033 return NT_STATUS_NO_MEMORY;
1036 for (i=0; i<num_entries; i++) {
1037 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
1038 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
1039 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
1040 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
1043 SAFE_FREE(map);
1045 *p_num_entries = num_entries;
1047 return NT_STATUS_OK;
1050 /*******************************************************************
1051 samr_reply_enum_dom_groups
1052 ********************************************************************/
1054 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1056 DOMAIN_GRP *grp=NULL;
1057 uint32 num_entries;
1058 DOM_SID sid;
1059 uint32 acc_granted;
1061 r_u->status = NT_STATUS_OK;
1063 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1064 return NT_STATUS_INVALID_HANDLE;
1066 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
1067 return r_u->status;
1070 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1072 /* the domain group array is being allocated in the function below */
1073 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))) {
1074 return r_u->status;
1077 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1079 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
1081 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1083 return r_u->status;
1087 /*******************************************************************
1088 samr_reply_enum_dom_aliases
1089 ********************************************************************/
1091 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1093 DOMAIN_GRP *grp=NULL;
1094 uint32 num_entries = 0;
1095 fstring sid_str;
1096 DOM_SID sid;
1097 NTSTATUS status;
1098 uint32 acc_granted;
1100 r_u->status = NT_STATUS_OK;
1102 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1103 return NT_STATUS_INVALID_HANDLE;
1105 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1106 return r_u->status;
1109 sid_to_string(sid_str, &sid);
1110 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1112 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1113 &num_entries, MAX_SAM_ENTRIES);
1114 if (NT_STATUS_IS_ERR(status)) return status;
1116 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1118 /*safe_free(grp);*/
1120 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1122 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1124 return r_u->status;
1127 /*******************************************************************
1128 samr_reply_query_dispinfo
1129 ********************************************************************/
1131 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1132 SAMR_R_QUERY_DISPINFO *r_u)
1134 struct samr_info *info = NULL;
1135 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1137 uint32 max_entries=q_u->max_entries;
1138 uint32 enum_context=q_u->start_idx;
1139 uint32 max_size=q_u->max_size;
1141 SAM_DISPINFO_CTR *ctr;
1142 uint32 temp_size=0, total_data_size=0;
1143 NTSTATUS disp_ret;
1144 uint32 num_account = 0;
1145 enum remote_arch_types ra_type = get_remote_arch();
1146 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1147 DOM_SID domain_sid;
1149 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1150 r_u->status = NT_STATUS_OK;
1152 /* find the policy handle. open a policy on it. */
1153 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1154 return NT_STATUS_INVALID_HANDLE;
1156 domain_sid = info->sid;
1159 * calculate how many entries we will return.
1160 * based on
1161 * - the number of entries the client asked
1162 * - our limit on that
1163 * - the starting point (enumeration context)
1164 * - the buffer size the client will accept
1168 * We are a lot more like W2K. Instead of reading the SAM
1169 * each time to find the records we need to send back,
1170 * we read it once and link that copy to the sam handle.
1171 * For large user list (over the MAX_SAM_ENTRIES)
1172 * it's a definitive win.
1173 * second point to notice: between enumerations
1174 * our sam is now the same as it's a snapshoot.
1175 * third point: got rid of the static SAM_USER_21 struct
1176 * no more intermediate.
1177 * con: it uses much more memory, as a full copy is stored
1178 * in memory.
1180 * If you want to change it, think twice and think
1181 * of the second point , that's really important.
1183 * JFM, 12/20/2001
1186 /* Get what we need from the password database */
1187 switch (q_u->switch_level) {
1188 case 0x1:
1189 /* When playing with usrmgr, this is necessary
1190 if you want immediate refresh after editing
1191 a user. I would like to do this after the
1192 setuserinfo2, but we do not have access to
1193 the domain handle in that call, only to the
1194 user handle. Where else does this hurt?
1195 -- Volker
1197 #if 0
1198 /* We cannot do this here - it kills performace. JRA. */
1199 free_samr_users(info);
1200 #endif
1201 case 0x2:
1202 case 0x4:
1203 become_root();
1204 /* Level 2 is for all machines, otherwise only 'normal' users */
1205 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1206 unbecome_root();
1207 if (!NT_STATUS_IS_OK(r_u->status)) {
1208 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1209 return r_u->status;
1211 num_account = info->disp_info.num_user_account;
1212 break;
1213 case 0x3:
1214 case 0x5:
1215 r_u->status = load_group_domain_entries(info, &info->sid);
1216 if (!NT_STATUS_IS_OK(r_u->status))
1217 return r_u->status;
1218 num_account = info->disp_info.num_group_account;
1219 break;
1220 default:
1221 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1222 return NT_STATUS_INVALID_INFO_CLASS;
1225 /* first limit the number of entries we will return */
1226 if(max_entries > max_sam_entries) {
1227 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1228 max_entries = max_sam_entries;
1231 if (enum_context > num_account) {
1232 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1233 return NT_STATUS_NO_MORE_ENTRIES;
1236 /* verify we won't overflow */
1237 if (max_entries > num_account-enum_context) {
1238 max_entries = num_account-enum_context;
1239 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1242 /* calculate the size and limit on the number of entries we will return */
1243 temp_size=max_entries*struct_size;
1245 if (temp_size>max_size) {
1246 max_entries=MIN((max_size/struct_size),max_entries);;
1247 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1250 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1251 return NT_STATUS_NO_MEMORY;
1253 ZERO_STRUCTP(ctr);
1255 /* Now create reply structure */
1256 switch (q_u->switch_level) {
1257 case 0x1:
1258 if (max_entries) {
1259 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1260 return NT_STATUS_NO_MEMORY;
1262 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1263 info->disp_info.disp_user_info, &domain_sid);
1264 if (!NT_STATUS_IS_OK(disp_ret))
1265 return disp_ret;
1266 break;
1267 case 0x2:
1268 if (max_entries) {
1269 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1270 return NT_STATUS_NO_MEMORY;
1272 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1273 info->disp_info.disp_user_info, &domain_sid);
1274 if (!NT_STATUS_IS_OK(disp_ret))
1275 return disp_ret;
1276 break;
1277 case 0x3:
1278 if (max_entries) {
1279 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1280 return NT_STATUS_NO_MEMORY;
1282 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1283 if (!NT_STATUS_IS_OK(disp_ret))
1284 return disp_ret;
1285 break;
1286 case 0x4:
1287 if (max_entries) {
1288 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1289 return NT_STATUS_NO_MEMORY;
1291 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1292 if (!NT_STATUS_IS_OK(disp_ret))
1293 return disp_ret;
1294 break;
1295 case 0x5:
1296 if (max_entries) {
1297 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1298 return NT_STATUS_NO_MEMORY;
1300 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1301 if (!NT_STATUS_IS_OK(disp_ret))
1302 return disp_ret;
1303 break;
1305 default:
1306 ctr->sam.info = NULL;
1307 return NT_STATUS_INVALID_INFO_CLASS;
1310 /* calculate the total size */
1311 total_data_size=num_account*struct_size;
1313 if (enum_context+max_entries < num_account)
1314 r_u->status = STATUS_MORE_ENTRIES;
1316 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1318 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1320 return r_u->status;
1324 /*******************************************************************
1325 samr_reply_query_aliasinfo
1326 ********************************************************************/
1328 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1330 DOM_SID sid;
1331 GROUP_MAP map;
1332 uint32 acc_granted;
1334 r_u->status = NT_STATUS_OK;
1336 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1338 /* find the policy handle. open a policy on it. */
1339 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1340 return NT_STATUS_INVALID_HANDLE;
1341 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1342 return r_u->status;
1345 if (!sid_check_is_in_our_domain(&sid) &&
1346 !sid_check_is_in_builtin(&sid))
1347 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1349 if (!pdb_getgrsid(&map, sid))
1350 return NT_STATUS_NO_SUCH_ALIAS;
1352 switch (q_u->switch_level) {
1353 case 1:
1354 r_u->ptr = 1;
1355 r_u->ctr.switch_value1 = 1;
1356 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1357 break;
1358 case 3:
1359 r_u->ptr = 1;
1360 r_u->ctr.switch_value1 = 3;
1361 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1362 break;
1363 default:
1364 return NT_STATUS_INVALID_INFO_CLASS;
1367 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1369 return r_u->status;
1372 #if 0
1373 /*******************************************************************
1374 samr_reply_lookup_ids
1375 ********************************************************************/
1377 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1379 uint32 rid[MAX_SAM_ENTRIES];
1380 int num_rids = q_u->num_sids1;
1382 r_u->status = NT_STATUS_OK;
1384 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1386 if (num_rids > MAX_SAM_ENTRIES) {
1387 num_rids = MAX_SAM_ENTRIES;
1388 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1391 #if 0
1392 int i;
1393 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1395 for (i = 0; i < num_rids && status == 0; i++)
1397 struct sam_passwd *sam_pass;
1398 fstring user_name;
1401 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1402 q_u->uni_user_name[i].uni_str_len));
1404 /* find the user account */
1405 become_root();
1406 sam_pass = get_smb21pwd_entry(user_name, 0);
1407 unbecome_root();
1409 if (sam_pass == NULL)
1411 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1412 rid[i] = 0;
1414 else
1416 rid[i] = sam_pass->user_rid;
1419 #endif
1421 num_rids = 1;
1422 rid[0] = BUILTIN_ALIAS_RID_USERS;
1424 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1426 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1428 return r_u->status;
1430 #endif
1432 /*******************************************************************
1433 _samr_lookup_names
1434 ********************************************************************/
1436 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1438 uint32 rid[MAX_SAM_ENTRIES];
1439 uint32 local_rid;
1440 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1441 enum SID_NAME_USE local_type;
1442 int i;
1443 int num_rids = q_u->num_names2;
1444 DOM_SID pol_sid;
1445 fstring sid_str;
1446 uint32 acc_granted;
1448 r_u->status = NT_STATUS_OK;
1450 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1452 ZERO_ARRAY(rid);
1453 ZERO_ARRAY(type);
1455 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1456 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1457 return r_u->status;
1460 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1461 return r_u->status;
1464 if (num_rids > MAX_SAM_ENTRIES) {
1465 num_rids = MAX_SAM_ENTRIES;
1466 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1469 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1471 become_root(); /* local_lookup_name can require root privs */
1473 for (i = 0; i < num_rids; i++) {
1474 fstring name;
1475 DOM_SID sid;
1476 int ret;
1478 r_u->status = NT_STATUS_NONE_MAPPED;
1480 rid [i] = 0xffffffff;
1481 type[i] = SID_NAME_UNKNOWN;
1483 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1486 * we are only looking for a name
1487 * the SID we get back can be outside
1488 * the scope of the pol_sid
1490 * in clear: it prevents to reply to domain\group: yes
1491 * when only builtin\group exists.
1493 * a cleaner code is to add the sid of the domain we're looking in
1494 * to the local_lookup_name function.
1497 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1498 sid_split_rid(&sid, &local_rid);
1500 if (sid_equal(&sid, &pol_sid)) {
1501 rid[i]=local_rid;
1502 type[i]=local_type;
1503 r_u->status = NT_STATUS_OK;
1508 unbecome_root();
1510 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1512 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1514 return r_u->status;
1517 /*******************************************************************
1518 _samr_chgpasswd_user
1519 ********************************************************************/
1521 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1523 fstring user_name;
1524 fstring wks;
1526 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1528 r_u->status = NT_STATUS_OK;
1530 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1531 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1533 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1536 * Pass the user through the NT -> unix user mapping
1537 * function.
1540 (void)map_username(user_name);
1543 * UNIX username case mangling not required, pass_oem_change
1544 * is case insensitive.
1547 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1548 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1550 init_samr_r_chgpasswd_user(r_u, r_u->status);
1552 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1554 return r_u->status;
1557 /*******************************************************************
1558 makes a SAMR_R_LOOKUP_RIDS structure.
1559 ********************************************************************/
1561 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1562 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1564 uint32 i;
1565 UNIHDR *hdr_name=NULL;
1566 UNISTR2 *uni_name=NULL;
1568 *pp_uni_name = NULL;
1569 *pp_hdr_name = NULL;
1571 if (num_names != 0) {
1572 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1573 if (hdr_name == NULL)
1574 return False;
1576 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1577 if (uni_name == NULL)
1578 return False;
1581 for (i = 0; i < num_names; i++) {
1582 int len = names[i] != NULL ? strlen(names[i]) : 0;
1583 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1584 init_uni_hdr(&hdr_name[i], len);
1585 init_unistr2(&uni_name[i], names[i], len);
1588 *pp_uni_name = uni_name;
1589 *pp_hdr_name = hdr_name;
1591 return True;
1594 /*******************************************************************
1595 _samr_lookup_rids
1596 ********************************************************************/
1598 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1600 fstring group_names[MAX_SAM_ENTRIES];
1601 uint32 *group_attrs = NULL;
1602 UNIHDR *hdr_name = NULL;
1603 UNISTR2 *uni_name = NULL;
1604 DOM_SID pol_sid;
1605 int num_rids = q_u->num_rids1;
1606 int i;
1607 uint32 acc_granted;
1609 r_u->status = NT_STATUS_OK;
1611 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1613 /* find the policy handle. open a policy on it. */
1614 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1615 return NT_STATUS_INVALID_HANDLE;
1617 if (num_rids > MAX_SAM_ENTRIES) {
1618 num_rids = MAX_SAM_ENTRIES;
1619 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1622 if (num_rids) {
1623 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1624 return NT_STATUS_NO_MEMORY;
1627 r_u->status = NT_STATUS_NONE_MAPPED;
1629 become_root(); /* lookup_sid can require root privs */
1631 for (i = 0; i < num_rids; i++) {
1632 fstring tmpname;
1633 fstring domname;
1634 DOM_SID sid;
1635 enum SID_NAME_USE type;
1637 group_attrs[i] = SID_NAME_UNKNOWN;
1638 *group_names[i] = '\0';
1640 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1641 sid_copy(&sid, &pol_sid);
1642 sid_append_rid(&sid, q_u->rid[i]);
1644 if (lookup_sid(&sid, domname, tmpname, &type)) {
1645 r_u->status = NT_STATUS_OK;
1646 group_attrs[i] = (uint32)type;
1647 fstrcpy(group_names[i],tmpname);
1648 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1653 unbecome_root();
1655 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1656 return NT_STATUS_NO_MEMORY;
1658 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1660 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1662 return r_u->status;
1665 /*******************************************************************
1666 _api_samr_open_user. Safe - gives out no passwd info.
1667 ********************************************************************/
1669 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1671 SAM_ACCOUNT *sampass=NULL;
1672 DOM_SID sid;
1673 POLICY_HND domain_pol = q_u->domain_pol;
1674 POLICY_HND *user_pol = &r_u->user_pol;
1675 struct samr_info *info = NULL;
1676 SEC_DESC *psd = NULL;
1677 uint32 acc_granted;
1678 uint32 des_access = q_u->access_mask;
1679 size_t sd_size;
1680 BOOL ret;
1681 NTSTATUS nt_status;
1683 r_u->status = NT_STATUS_OK;
1685 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1686 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1687 return NT_STATUS_INVALID_HANDLE;
1689 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1690 return nt_status;
1693 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1694 if (!NT_STATUS_IS_OK(nt_status)) {
1695 return nt_status;
1698 /* append the user's RID to it */
1699 if (!sid_append_rid(&sid, q_u->user_rid))
1700 return NT_STATUS_NO_SUCH_USER;
1702 /* check if access can be granted as requested by client. */
1703 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1704 se_map_generic(&des_access, &usr_generic_mapping);
1705 if (!NT_STATUS_IS_OK(nt_status =
1706 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1707 des_access, &acc_granted, "_samr_open_user"))) {
1708 return nt_status;
1711 become_root();
1712 ret=pdb_getsampwsid(sampass, &sid);
1713 unbecome_root();
1715 /* check that the SID exists in our domain. */
1716 if (ret == False) {
1717 return NT_STATUS_NO_SUCH_USER;
1720 pdb_free_sam(&sampass);
1722 /* associate the user's SID and access bits with the new handle. */
1723 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1724 return NT_STATUS_NO_MEMORY;
1725 info->acc_granted = acc_granted;
1727 /* get a (unique) handle. open a policy on it. */
1728 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1729 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1731 return r_u->status;
1734 /*************************************************************************
1735 get_user_info_10. Safe. Only gives out acb bits.
1736 *************************************************************************/
1738 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1740 SAM_ACCOUNT *smbpass=NULL;
1741 BOOL ret;
1742 NTSTATUS nt_status;
1744 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1746 if (!NT_STATUS_IS_OK(nt_status)) {
1747 return nt_status;
1750 become_root();
1751 ret = pdb_getsampwsid(smbpass, user_sid);
1752 unbecome_root();
1754 if (ret==False) {
1755 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1756 return NT_STATUS_NO_SUCH_USER;
1759 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1761 ZERO_STRUCTP(id10);
1762 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1764 pdb_free_sam(&smbpass);
1766 return NT_STATUS_OK;
1769 /*************************************************************************
1770 get_user_info_12. OK - this is the killer as it gives out password info.
1771 Ensure that this is only allowed on an encrypted connection with a root
1772 user. JRA.
1773 *************************************************************************/
1775 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1777 SAM_ACCOUNT *smbpass=NULL;
1778 BOOL ret;
1779 NTSTATUS nt_status;
1781 if (!p->ntlmssp_auth_validated)
1782 return NT_STATUS_ACCESS_DENIED;
1784 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1785 return NT_STATUS_ACCESS_DENIED;
1788 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1791 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1793 if (!NT_STATUS_IS_OK(nt_status)) {
1794 return nt_status;
1797 ret = pdb_getsampwsid(smbpass, user_sid);
1799 if (ret == False) {
1800 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1801 pdb_free_sam(&smbpass);
1802 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1805 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1807 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1808 pdb_free_sam(&smbpass);
1809 return NT_STATUS_ACCOUNT_DISABLED;
1812 ZERO_STRUCTP(id12);
1813 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1815 pdb_free_sam(&smbpass);
1817 return NT_STATUS_OK;
1820 /*************************************************************************
1821 get_user_info_20
1822 *************************************************************************/
1824 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1826 SAM_ACCOUNT *sampass=NULL;
1827 BOOL ret;
1829 pdb_init_sam_talloc(mem_ctx, &sampass);
1831 become_root();
1832 ret = pdb_getsampwsid(sampass, user_sid);
1833 unbecome_root();
1835 if (ret == False) {
1836 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1837 return NT_STATUS_NO_SUCH_USER;
1840 samr_clear_sam_passwd(sampass);
1842 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1844 ZERO_STRUCTP(id20);
1845 init_sam_user_info20A(id20, sampass);
1847 pdb_free_sam(&sampass);
1849 return NT_STATUS_OK;
1852 /*************************************************************************
1853 get_user_info_21
1854 *************************************************************************/
1856 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1857 DOM_SID *user_sid, DOM_SID *domain_sid)
1859 SAM_ACCOUNT *sampass=NULL;
1860 BOOL ret;
1861 NTSTATUS nt_status;
1863 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1864 if (!NT_STATUS_IS_OK(nt_status)) {
1865 return nt_status;
1868 become_root();
1869 ret = pdb_getsampwsid(sampass, user_sid);
1870 unbecome_root();
1872 if (ret == False) {
1873 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1874 return NT_STATUS_NO_SUCH_USER;
1877 samr_clear_sam_passwd(sampass);
1879 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1881 ZERO_STRUCTP(id21);
1882 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1884 pdb_free_sam(&sampass);
1886 return NT_STATUS_OK;
1889 /*******************************************************************
1890 _samr_query_userinfo
1891 ********************************************************************/
1893 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1895 SAM_USERINFO_CTR *ctr;
1896 struct samr_info *info = NULL;
1897 DOM_SID domain_sid;
1898 uint32 rid;
1900 r_u->status=NT_STATUS_OK;
1902 /* search for the handle */
1903 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1904 return NT_STATUS_INVALID_HANDLE;
1906 domain_sid = info->sid;
1908 sid_split_rid(&domain_sid, &rid);
1910 if (!sid_check_is_in_our_domain(&info->sid))
1911 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1913 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1915 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1916 if (!ctr)
1917 return NT_STATUS_NO_MEMORY;
1919 ZERO_STRUCTP(ctr);
1921 /* ok! user info levels (lots: see MSDEV help), off we go... */
1922 ctr->switch_value = q_u->switch_value;
1924 switch (q_u->switch_value) {
1925 case 0x10:
1926 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1927 if (ctr->info.id10 == NULL)
1928 return NT_STATUS_NO_MEMORY;
1930 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1931 return r_u->status;
1932 break;
1934 #if 0
1935 /* whoops - got this wrong. i think. or don't understand what's happening. */
1936 case 0x11:
1938 NTTIME expire;
1939 info = (void *)&id11;
1941 expire.low = 0xffffffff;
1942 expire.high = 0x7fffffff;
1944 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1945 sizeof
1946 (*ctr->
1947 info.
1948 id11));
1949 ZERO_STRUCTP(ctr->info.id11);
1950 init_sam_user_info11(ctr->info.id11, &expire,
1951 "BROOKFIELDS$", /* name */
1952 0x03ef, /* user rid */
1953 0x201, /* group rid */
1954 0x0080); /* acb info */
1956 break;
1958 #endif
1960 case 0x12:
1961 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1962 if (ctr->info.id12 == NULL)
1963 return NT_STATUS_NO_MEMORY;
1965 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1966 return r_u->status;
1967 break;
1969 case 20:
1970 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1971 if (ctr->info.id20 == NULL)
1972 return NT_STATUS_NO_MEMORY;
1973 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1974 return r_u->status;
1975 break;
1977 case 21:
1978 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1979 if (ctr->info.id21 == NULL)
1980 return NT_STATUS_NO_MEMORY;
1981 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1982 &info->sid, &domain_sid)))
1983 return r_u->status;
1984 break;
1986 default:
1987 return NT_STATUS_INVALID_INFO_CLASS;
1990 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1992 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1994 return r_u->status;
1997 /*******************************************************************
1998 samr_reply_query_usergroups
1999 ********************************************************************/
2001 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
2003 SAM_ACCOUNT *sam_pass=NULL;
2004 DOM_SID sid;
2005 DOM_GID *gids = NULL;
2006 int num_groups = 0;
2007 uint32 acc_granted;
2008 BOOL ret;
2011 * from the SID in the request:
2012 * we should send back the list of DOMAIN GROUPS
2013 * the user is a member of
2015 * and only the DOMAIN GROUPS
2016 * no ALIASES !!! neither aliases of the domain
2017 * nor aliases of the builtin SID
2019 * JFM, 12/2/2001
2022 r_u->status = NT_STATUS_OK;
2024 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2026 /* find the policy handle. open a policy on it. */
2027 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
2028 return NT_STATUS_INVALID_HANDLE;
2030 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2031 return r_u->status;
2034 if (!sid_check_is_in_our_domain(&sid))
2035 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2037 pdb_init_sam(&sam_pass);
2039 become_root();
2040 ret = pdb_getsampwsid(sam_pass, &sid);
2041 unbecome_root();
2043 if (ret == False) {
2044 pdb_free_sam(&sam_pass);
2045 return NT_STATUS_NO_SUCH_USER;
2048 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
2049 pdb_free_sam(&sam_pass);
2050 return NT_STATUS_NO_SUCH_GROUP;
2053 /* construct the response. lkclXXXX: gids are not copied! */
2054 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2056 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2058 pdb_free_sam(&sam_pass);
2060 return r_u->status;
2063 /*******************************************************************
2064 _samr_query_dom_info
2065 ********************************************************************/
2067 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2069 struct samr_info *info = NULL;
2070 SAM_UNK_CTR *ctr;
2071 uint32 min_pass_len,pass_hist,flag;
2072 time_t u_expire, u_min_age;
2073 NTTIME nt_expire, nt_min_age;
2075 time_t u_lock_duration, u_reset_time;
2076 NTTIME nt_lock_duration, nt_reset_time;
2077 uint32 lockout;
2079 time_t u_logout;
2080 NTTIME nt_logout;
2082 uint32 account_policy_temp;
2084 uint32 num_users=0, num_groups=0, num_aliases=0;
2086 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2087 return NT_STATUS_NO_MEMORY;
2089 ZERO_STRUCTP(ctr);
2091 r_u->status = NT_STATUS_OK;
2093 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2095 /* find the policy handle. open a policy on it. */
2096 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2097 return NT_STATUS_INVALID_HANDLE;
2099 switch (q_u->switch_value) {
2100 case 0x01:
2102 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2103 min_pass_len = account_policy_temp;
2105 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2106 pass_hist = account_policy_temp;
2108 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2109 flag = account_policy_temp;
2111 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2112 u_expire = account_policy_temp;
2114 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2115 u_min_age = account_policy_temp;
2117 unix_to_nt_time_abs(&nt_expire, u_expire);
2118 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2120 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2121 flag, nt_expire, nt_min_age);
2122 break;
2123 case 0x02:
2124 become_root();
2125 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2126 unbecome_root();
2127 if (!NT_STATUS_IS_OK(r_u->status)) {
2128 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2129 return r_u->status;
2131 num_users=info->disp_info.num_user_account;
2132 free_samr_db(info);
2134 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2135 if (!NT_STATUS_IS_OK(r_u->status)) {
2136 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2137 return r_u->status;
2139 num_groups=info->disp_info.num_group_account;
2140 free_samr_db(info);
2142 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2143 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2144 num_users, num_groups, num_aliases);
2145 break;
2146 case 0x03:
2147 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2148 unix_to_nt_time_abs(&nt_logout, u_logout);
2150 init_unk_info3(&ctr->info.inf3, nt_logout);
2151 break;
2152 case 0x05:
2153 init_unk_info5(&ctr->info.inf5, global_myname());
2154 break;
2155 case 0x06:
2156 init_unk_info6(&ctr->info.inf6);
2157 break;
2158 case 0x07:
2159 init_unk_info7(&ctr->info.inf7);
2160 break;
2161 case 0x0c:
2162 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2163 u_lock_duration = account_policy_temp;
2165 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2166 u_reset_time = account_policy_temp;
2168 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2169 lockout = account_policy_temp;
2171 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2172 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2174 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2175 break;
2176 default:
2177 return NT_STATUS_INVALID_INFO_CLASS;
2180 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2182 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2184 return r_u->status;
2187 /*******************************************************************
2188 _api_samr_create_user
2189 Create an account, can be either a normal user or a machine.
2190 This funcion will need to be updated for bdc/domain trusts.
2191 ********************************************************************/
2193 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2195 SAM_ACCOUNT *sam_pass=NULL;
2196 fstring account;
2197 DOM_SID sid;
2198 pstring add_script;
2199 POLICY_HND dom_pol = q_u->domain_pol;
2200 UNISTR2 user_account = q_u->uni_name;
2201 uint16 acb_info = q_u->acb_info;
2202 POLICY_HND *user_pol = &r_u->user_pol;
2203 struct samr_info *info = NULL;
2204 BOOL ret;
2205 NTSTATUS nt_status;
2206 struct passwd *pw;
2207 uint32 acc_granted;
2208 SEC_DESC *psd;
2209 size_t sd_size;
2210 uint32 new_rid = 0;
2211 /* check this, when giving away 'add computer to domain' privs */
2212 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2214 /* Get the domain SID stored in the domain policy */
2215 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2216 return NT_STATUS_INVALID_HANDLE;
2218 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2219 return nt_status;
2222 /* find the account: tell the caller if it exists.
2223 lkclXXXX i have *no* idea if this is a problem or not
2224 or even if you are supposed to construct a different
2225 reply if the account already exists...
2228 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2229 strlower_m(account);
2231 pdb_init_sam(&sam_pass);
2233 become_root();
2234 ret = pdb_getsampwnam(sam_pass, account);
2235 unbecome_root();
2236 if (ret == True) {
2237 /* this account exists: say so */
2238 pdb_free_sam(&sam_pass);
2239 return NT_STATUS_USER_EXISTS;
2242 pdb_free_sam(&sam_pass);
2245 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2246 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2247 * that only people with write access to the smbpasswd file will be able
2248 * to create a user. JRA.
2252 * add the user in the /etc/passwd file or the unix authority system.
2253 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2254 * a) local_password_change() checks for us if the /etc/passwd account really exists
2255 * b) smb_create_user() would return an error if the account already exists
2256 * and as it could return an error also if it can't create the account, it would be tricky.
2258 * So we go the easy way, only check after if the account exists.
2259 * JFM (2/3/2001), to clear any possible bad understanding (-:
2261 * We now have seperate script paramaters for adding users/machines so we
2262 * now have some sainity-checking to match.
2265 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2268 * we used to have code here that made sure the acb_info flags
2269 * matched with the users named (e.g. an account flags as a machine
2270 * trust account ended in '$'). It has been ifdef'd out for a long
2271 * time, so I replaced it with this comment. --jerry
2274 /* the passdb lookup has failed; check to see if we need to run the
2275 add user/machine script */
2277 pw = Get_Pwnam(account);
2279 /*********************************************************************
2280 * HEADS UP! If we have to create a new user account, we have to get
2281 * a new RID from somewhere. This used to be done by the passdb
2282 * backend. It has been moved into idmap now. Since idmap is now
2283 * wrapped up behind winbind, this means you have to run winbindd if you
2284 * want new accounts to get a new RID when "enable rid algorithm = no".
2285 * Tough. We now have a uniform way of allocating RIDs regardless
2286 * of what ever passdb backend people may use.
2287 * --jerry (2003-07-10)
2288 *********************************************************************/
2290 if ( !pw ) {
2292 * we can't check both the ending $ and the acb_info.
2294 * UserManager creates trust accounts (ending in $,
2295 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2296 * JFM, 11/29/2001
2298 if (account[strlen(account)-1] == '$')
2299 pstrcpy(add_script, lp_addmachine_script());
2300 else
2301 pstrcpy(add_script, lp_adduser_script());
2303 if (*add_script) {
2304 int add_ret;
2305 all_string_sub(add_script, "%u", account, sizeof(account));
2306 add_ret = smbrun(add_script,NULL);
2307 DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2309 else /* no add user script -- ask winbindd to do it */
2311 if ( !winbind_create_user( account, &new_rid ) ) {
2312 DEBUG(3,("_api_samr_create_user: winbind_create_user(%s) failed\n",
2313 account));
2319 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2321 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2322 return nt_status;
2324 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2326 if (!pdb_add_sam_account(sam_pass)) {
2327 pdb_free_sam(&sam_pass);
2328 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2329 account));
2330 return NT_STATUS_ACCESS_DENIED;
2333 /* Get the user's SID */
2334 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2336 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2337 se_map_generic(&des_access, &usr_generic_mapping);
2338 if (!NT_STATUS_IS_OK(nt_status =
2339 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2340 des_access, &acc_granted, "_samr_create_user"))) {
2341 return nt_status;
2344 /* associate the user's SID with the new handle. */
2345 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2346 pdb_free_sam(&sam_pass);
2347 return NT_STATUS_NO_MEMORY;
2350 ZERO_STRUCTP(info);
2351 info->sid = sid;
2352 info->acc_granted = acc_granted;
2354 /* get a (unique) handle. open a policy on it. */
2355 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2356 pdb_free_sam(&sam_pass);
2357 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2360 r_u->user_rid=pdb_get_user_rid(sam_pass);
2362 r_u->access_granted = acc_granted;
2364 pdb_free_sam(&sam_pass);
2366 return NT_STATUS_OK;
2369 /*******************************************************************
2370 samr_reply_connect_anon
2371 ********************************************************************/
2373 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2375 struct samr_info *info = NULL;
2376 uint32 des_access = q_u->access_mask;
2378 /* Access check */
2380 if (!pipe_access_check(p)) {
2381 DEBUG(3, ("access denied to samr_connect_anon\n"));
2382 r_u->status = NT_STATUS_ACCESS_DENIED;
2383 return r_u->status;
2386 /* set up the SAMR connect_anon response */
2388 r_u->status = NT_STATUS_OK;
2390 /* associate the user's SID with the new handle. */
2391 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2392 return NT_STATUS_NO_MEMORY;
2394 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2395 was observed from a win98 client trying to enumerate users (when configured
2396 user level access control on shares) --jerry */
2398 se_map_generic( &des_access, &sam_generic_mapping );
2399 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2401 info->status = q_u->unknown_0;
2403 /* get a (unique) handle. open a policy on it. */
2404 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2405 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2407 return r_u->status;
2410 /*******************************************************************
2411 samr_reply_connect
2412 ********************************************************************/
2414 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2416 struct samr_info *info = NULL;
2417 SEC_DESC *psd = NULL;
2418 uint32 acc_granted;
2419 uint32 des_access = q_u->access_mask;
2420 size_t sd_size;
2421 NTSTATUS nt_status;
2424 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2426 /* Access check */
2428 if (!pipe_access_check(p)) {
2429 DEBUG(3, ("access denied to samr_connect\n"));
2430 r_u->status = NT_STATUS_ACCESS_DENIED;
2431 return r_u->status;
2434 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2435 se_map_generic(&des_access, &sam_generic_mapping);
2436 if (!NT_STATUS_IS_OK(nt_status =
2437 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2438 des_access, &acc_granted, "_samr_connect"))) {
2439 return nt_status;
2442 r_u->status = NT_STATUS_OK;
2444 /* associate the user's SID and access granted with the new handle. */
2445 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2446 return NT_STATUS_NO_MEMORY;
2448 info->acc_granted = acc_granted;
2449 info->status = q_u->access_mask;
2451 /* get a (unique) handle. open a policy on it. */
2452 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2453 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2455 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2457 return r_u->status;
2460 /*******************************************************************
2461 samr_connect4
2462 ********************************************************************/
2464 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2466 struct samr_info *info = NULL;
2467 SEC_DESC *psd = NULL;
2468 uint32 acc_granted;
2469 uint32 des_access = q_u->access_mask;
2470 size_t sd_size;
2471 NTSTATUS nt_status;
2474 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2476 /* Access check */
2478 if (!pipe_access_check(p)) {
2479 DEBUG(3, ("access denied to samr_connect4\n"));
2480 r_u->status = NT_STATUS_ACCESS_DENIED;
2481 return r_u->status;
2484 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2485 se_map_generic(&des_access, &sam_generic_mapping);
2486 if (!NT_STATUS_IS_OK(nt_status =
2487 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2488 des_access, &acc_granted, "_samr_connect"))) {
2489 return nt_status;
2492 r_u->status = NT_STATUS_OK;
2494 /* associate the user's SID and access granted with the new handle. */
2495 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2496 return NT_STATUS_NO_MEMORY;
2498 info->acc_granted = acc_granted;
2499 info->status = q_u->access_mask;
2501 /* get a (unique) handle. open a policy on it. */
2502 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2503 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2505 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2507 return r_u->status;
2510 /**********************************************************************
2511 api_samr_lookup_domain
2512 **********************************************************************/
2514 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2516 struct samr_info *info;
2517 fstring domain_name;
2518 DOM_SID sid;
2520 r_u->status = NT_STATUS_OK;
2522 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2523 return NT_STATUS_INVALID_HANDLE;
2525 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2526 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2528 return r_u->status;
2531 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2533 ZERO_STRUCT(sid);
2535 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2536 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2539 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2541 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2543 return r_u->status;
2546 /******************************************************************
2547 makes a SAMR_R_ENUM_DOMAINS structure.
2548 ********************************************************************/
2550 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2551 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2553 uint32 i;
2554 SAM_ENTRY *sam;
2555 UNISTR2 *uni_name;
2557 DEBUG(5, ("make_enum_domains\n"));
2559 *pp_sam = NULL;
2560 *pp_uni_name = NULL;
2562 if (num_sam_entries == 0)
2563 return True;
2565 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2566 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2568 if (sam == NULL || uni_name == NULL)
2569 return False;
2571 for (i = 0; i < num_sam_entries; i++) {
2572 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2574 init_sam_entry(&sam[i], len, 0);
2575 init_unistr2(&uni_name[i], doms[i], len);
2578 *pp_sam = sam;
2579 *pp_uni_name = uni_name;
2581 return True;
2584 /**********************************************************************
2585 api_samr_enum_domains
2586 **********************************************************************/
2588 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2590 struct samr_info *info;
2591 uint32 num_entries = 2;
2592 fstring dom[2];
2593 const char *name;
2595 r_u->status = NT_STATUS_OK;
2597 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2598 return NT_STATUS_INVALID_HANDLE;
2600 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2601 return r_u->status;
2604 name = get_global_sam_name();
2606 fstrcpy(dom[0],name);
2607 strupper_m(dom[0]);
2608 fstrcpy(dom[1],"Builtin");
2610 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2611 return NT_STATUS_NO_MEMORY;
2613 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2615 return r_u->status;
2618 /*******************************************************************
2619 api_samr_open_alias
2620 ********************************************************************/
2622 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2624 DOM_SID sid;
2625 POLICY_HND domain_pol = q_u->dom_pol;
2626 uint32 alias_rid = q_u->rid_alias;
2627 POLICY_HND *alias_pol = &r_u->pol;
2628 struct samr_info *info = NULL;
2629 SEC_DESC *psd = NULL;
2630 uint32 acc_granted;
2631 uint32 des_access = q_u->access_mask;
2632 size_t sd_size;
2633 NTSTATUS status;
2635 r_u->status = NT_STATUS_OK;
2637 /* find the domain policy and get the SID / access bits stored in the domain policy */
2638 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2639 return NT_STATUS_INVALID_HANDLE;
2641 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2642 return status;
2645 /* append the alias' RID to it */
2646 if (!sid_append_rid(&sid, alias_rid))
2647 return NT_STATUS_NO_SUCH_USER;
2649 /*check if access can be granted as requested by client. */
2650 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2651 se_map_generic(&des_access,&ali_generic_mapping);
2652 if (!NT_STATUS_IS_OK(status =
2653 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2654 des_access, &acc_granted, "_samr_open_alias"))) {
2655 return status;
2659 * we should check if the rid really exist !!!
2660 * JFM.
2663 /* associate the user's SID with the new handle. */
2664 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2665 return NT_STATUS_NO_MEMORY;
2667 info->acc_granted = acc_granted;
2669 /* get a (unique) handle. open a policy on it. */
2670 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2671 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2673 return r_u->status;
2676 /*******************************************************************
2677 set_user_info_10
2678 ********************************************************************/
2680 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2682 SAM_ACCOUNT *pwd =NULL;
2683 BOOL ret;
2685 pdb_init_sam(&pwd);
2687 ret = pdb_getsampwsid(pwd, sid);
2689 if(ret==False) {
2690 pdb_free_sam(&pwd);
2691 return False;
2694 if (id10 == NULL) {
2695 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2696 pdb_free_sam(&pwd);
2697 return False;
2700 /* FIX ME: check if the value is really changed --metze */
2701 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2702 pdb_free_sam(&pwd);
2703 return False;
2706 if(!pdb_update_sam_account(pwd)) {
2707 pdb_free_sam(&pwd);
2708 return False;
2711 pdb_free_sam(&pwd);
2713 return True;
2716 /*******************************************************************
2717 set_user_info_12
2718 ********************************************************************/
2720 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2722 SAM_ACCOUNT *pwd = NULL;
2724 pdb_init_sam(&pwd);
2726 if(!pdb_getsampwsid(pwd, sid)) {
2727 pdb_free_sam(&pwd);
2728 return False;
2731 if (id12 == NULL) {
2732 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2733 pdb_free_sam(&pwd);
2734 return False;
2737 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2738 pdb_free_sam(&pwd);
2739 return False;
2741 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2742 pdb_free_sam(&pwd);
2743 return False;
2745 if (!pdb_set_pass_changed_now (pwd)) {
2746 pdb_free_sam(&pwd);
2747 return False;
2750 if(!pdb_update_sam_account(pwd)) {
2751 pdb_free_sam(&pwd);
2752 return False;
2755 pdb_free_sam(&pwd);
2756 return True;
2759 /*******************************************************************
2760 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2761 ********************************************************************/
2762 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2764 struct group *grp;
2765 gid_t gid;
2767 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2768 &gid))) {
2769 DEBUG(2,("Could not get gid for primary group of "
2770 "user %s\n", pdb_get_username(sampass)));
2771 return False;
2774 grp = getgrgid(gid);
2776 if (grp == NULL) {
2777 DEBUG(2,("Could not find primary group %lu for "
2778 "user %s\n", (unsigned long)gid,
2779 pdb_get_username(sampass)));
2780 return False;
2783 if (smb_set_primary_group(grp->gr_name,
2784 pdb_get_username(sampass)) != 0) {
2785 DEBUG(2,("Could not set primary group for user %s to "
2786 "%s\n",
2787 pdb_get_username(sampass), grp->gr_name));
2788 return False;
2791 return True;
2795 /*******************************************************************
2796 set_user_info_21
2797 ********************************************************************/
2799 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2801 SAM_ACCOUNT *pwd = NULL;
2803 if (id21 == NULL) {
2804 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2805 return False;
2808 pdb_init_sam(&pwd);
2810 if (!pdb_getsampwsid(pwd, sid)) {
2811 pdb_free_sam(&pwd);
2812 return False;
2815 copy_id21_to_sam_passwd(pwd, id21);
2818 * The funny part about the previous two calls is
2819 * that pwd still has the password hashes from the
2820 * passdb entry. These have not been updated from
2821 * id21. I don't know if they need to be set. --jerry
2824 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2825 set_unix_primary_group(pwd);
2827 /* write the change out */
2828 if(!pdb_update_sam_account(pwd)) {
2829 pdb_free_sam(&pwd);
2830 return False;
2833 pdb_free_sam(&pwd);
2835 return True;
2838 /*******************************************************************
2839 set_user_info_23
2840 ********************************************************************/
2842 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2844 SAM_ACCOUNT *pwd = NULL;
2845 pstring plaintext_buf;
2846 uint32 len;
2847 uint16 acct_ctrl;
2849 if (id23 == NULL) {
2850 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2851 return False;
2854 pdb_init_sam(&pwd);
2856 if (!pdb_getsampwsid(pwd, sid)) {
2857 pdb_free_sam(&pwd);
2858 return False;
2861 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2862 pdb_get_username(pwd)));
2864 acct_ctrl = pdb_get_acct_ctrl(pwd);
2866 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
2867 pdb_free_sam(&pwd);
2868 return False;
2871 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2872 pdb_free_sam(&pwd);
2873 return False;
2876 copy_id23_to_sam_passwd(pwd, id23);
2878 /* if it's a trust account, don't update /etc/passwd */
2879 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2880 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2881 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2882 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2883 } else {
2884 /* update the UNIX password */
2885 if (lp_unix_password_sync() )
2886 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2887 pdb_free_sam(&pwd);
2888 return False;
2892 ZERO_STRUCT(plaintext_buf);
2894 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2895 set_unix_primary_group(pwd);
2897 if(!pdb_update_sam_account(pwd)) {
2898 pdb_free_sam(&pwd);
2899 return False;
2902 pdb_free_sam(&pwd);
2904 return True;
2907 /*******************************************************************
2908 set_user_info_pw
2909 ********************************************************************/
2911 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2913 SAM_ACCOUNT *pwd = NULL;
2914 uint32 len;
2915 pstring plaintext_buf;
2916 uint16 acct_ctrl;
2918 pdb_init_sam(&pwd);
2920 if (!pdb_getsampwsid(pwd, sid)) {
2921 pdb_free_sam(&pwd);
2922 return False;
2925 DEBUG(5, ("Attempting administrator password change for user %s\n",
2926 pdb_get_username(pwd)));
2928 acct_ctrl = pdb_get_acct_ctrl(pwd);
2930 ZERO_STRUCT(plaintext_buf);
2932 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) {
2933 pdb_free_sam(&pwd);
2934 return False;
2937 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2938 pdb_free_sam(&pwd);
2939 return False;
2942 /* if it's a trust account, don't update /etc/passwd */
2943 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2944 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2945 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2946 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2947 } else {
2948 /* update the UNIX password */
2949 if (lp_unix_password_sync()) {
2950 if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
2951 pdb_free_sam(&pwd);
2952 return False;
2957 ZERO_STRUCT(plaintext_buf);
2959 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2961 /* update the SAMBA password */
2962 if(!pdb_update_sam_account(pwd)) {
2963 pdb_free_sam(&pwd);
2964 return False;
2967 pdb_free_sam(&pwd);
2969 return True;
2972 /*******************************************************************
2973 samr_reply_set_userinfo
2974 ********************************************************************/
2976 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2978 DOM_SID sid;
2979 POLICY_HND *pol = &q_u->pol;
2980 uint16 switch_value = q_u->switch_value;
2981 SAM_USERINFO_CTR *ctr = q_u->ctr;
2982 uint32 acc_granted;
2983 uint32 acc_required;
2985 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2987 r_u->status = NT_STATUS_OK;
2989 /* find the policy handle. open a policy on it. */
2990 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2991 return NT_STATUS_INVALID_HANDLE;
2993 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2994 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2995 return r_u->status;
2998 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3000 if (ctr == NULL) {
3001 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3002 return NT_STATUS_INVALID_INFO_CLASS;
3005 /* ok! user info levels (lots: see MSDEV help), off we go... */
3006 switch (switch_value) {
3007 case 0x12:
3008 if (!set_user_info_12(ctr->info.id12, &sid))
3009 return NT_STATUS_ACCESS_DENIED;
3010 break;
3012 case 24:
3013 SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
3015 dump_data(100, (char *)ctr->info.id24->pass, 516);
3017 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3018 return NT_STATUS_ACCESS_DENIED;
3019 break;
3021 case 25:
3022 #if 0
3024 * Currently we don't really know how to unmarshall
3025 * the level 25 struct, and the password encryption
3026 * is different. This is a placeholder for when we
3027 * do understand it. In the meantime just return INVALID
3028 * info level and W2K SP2 drops down to level 23... JRA.
3031 SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
3033 dump_data(100, (char *)ctr->info.id25->pass, 532);
3035 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3036 return NT_STATUS_ACCESS_DENIED;
3037 break;
3038 #endif
3039 return NT_STATUS_INVALID_INFO_CLASS;
3041 case 23:
3042 SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
3044 dump_data(100, (char *)ctr->info.id23->pass, 516);
3046 if (!set_user_info_23(ctr->info.id23, &sid))
3047 return NT_STATUS_ACCESS_DENIED;
3048 break;
3050 default:
3051 return NT_STATUS_INVALID_INFO_CLASS;
3054 return r_u->status;
3057 /*******************************************************************
3058 samr_reply_set_userinfo2
3059 ********************************************************************/
3061 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3063 DOM_SID sid;
3064 SAM_USERINFO_CTR *ctr = q_u->ctr;
3065 POLICY_HND *pol = &q_u->pol;
3066 uint16 switch_value = q_u->switch_value;
3067 uint32 acc_granted;
3068 uint32 acc_required;
3070 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3072 r_u->status = NT_STATUS_OK;
3074 /* find the policy handle. open a policy on it. */
3075 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3076 return NT_STATUS_INVALID_HANDLE;
3078 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3079 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3080 return r_u->status;
3083 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3085 if (ctr == NULL) {
3086 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3087 return NT_STATUS_INVALID_INFO_CLASS;
3090 switch_value=ctr->switch_value;
3092 /* ok! user info levels (lots: see MSDEV help), off we go... */
3093 switch (switch_value) {
3094 case 21:
3095 if (!set_user_info_21(ctr->info.id21, &sid))
3096 return NT_STATUS_ACCESS_DENIED;
3097 break;
3098 case 16:
3099 if (!set_user_info_10(ctr->info.id10, &sid))
3100 return NT_STATUS_ACCESS_DENIED;
3101 break;
3102 case 18:
3103 /* Used by AS/U JRA. */
3104 if (!set_user_info_12(ctr->info.id12, &sid))
3105 return NT_STATUS_ACCESS_DENIED;
3106 break;
3107 default:
3108 return NT_STATUS_INVALID_INFO_CLASS;
3111 return r_u->status;
3114 /*********************************************************************
3115 _samr_query_aliasmem
3116 *********************************************************************/
3118 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3120 int num_groups = 0, tmp_num_groups=0;
3121 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3122 struct samr_info *info = NULL;
3123 int i,j;
3125 NTSTATUS ntstatus1;
3126 NTSTATUS ntstatus2;
3128 /* until i see a real useraliases query, we fack one up */
3130 /* I have seen one, JFM 2/12/2001 */
3132 * Explanation of what this call does:
3133 * for all the SID given in the request:
3134 * return a list of alias (local groups)
3135 * that have those SID as members.
3137 * and that's the alias in the domain specified
3138 * in the policy_handle
3140 * if the policy handle is on an incorrect sid
3141 * for example a user's sid
3142 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3145 r_u->status = NT_STATUS_OK;
3147 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3149 /* find the policy handle. open a policy on it. */
3150 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3151 return NT_STATUS_INVALID_HANDLE;
3153 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3154 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3156 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3157 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3158 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3159 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3163 if (!sid_check_is_domain(&info->sid) &&
3164 !sid_check_is_builtin(&info->sid))
3165 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3168 for (i=0; i<q_u->num_sids1; i++) {
3170 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3173 * if there is an error, we just continue as
3174 * it can be an unfound user or group
3176 if (!NT_STATUS_IS_OK(r_u->status)) {
3177 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3178 continue;
3181 if (tmp_num_groups==0) {
3182 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3183 continue;
3186 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3187 if (new_rids==NULL) {
3188 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3189 return NT_STATUS_NO_MEMORY;
3191 rids=new_rids;
3193 for (j=0; j<tmp_num_groups; j++)
3194 rids[j+num_groups]=tmp_rids[j];
3196 safe_free(tmp_rids);
3198 num_groups+=tmp_num_groups;
3201 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3202 return NT_STATUS_OK;
3205 /*********************************************************************
3206 _samr_query_aliasmem
3207 *********************************************************************/
3209 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3211 int i;
3213 GROUP_MAP map;
3214 int num_uids = 0;
3215 DOM_SID2 *sid;
3216 uid_t *uid=NULL;
3218 DOM_SID alias_sid;
3219 DOM_SID als_sid;
3220 uint32 alias_rid;
3221 fstring alias_sid_str;
3222 DOM_SID temp_sid;
3224 SAM_ACCOUNT *sam_user = NULL;
3225 BOOL check;
3226 uint32 acc_granted;
3228 /* find the policy handle. open a policy on it. */
3229 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3230 return NT_STATUS_INVALID_HANDLE;
3232 if (!NT_STATUS_IS_OK(r_u->status =
3233 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3234 return r_u->status;
3237 sid_copy(&als_sid, &alias_sid);
3238 sid_to_string(alias_sid_str, &alias_sid);
3239 sid_split_rid(&alias_sid, &alias_rid);
3241 DEBUG(10, ("sid is %s\n", alias_sid_str));
3243 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3244 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3245 if(!get_builtin_group_from_sid(als_sid, &map))
3246 return NT_STATUS_NO_SUCH_ALIAS;
3247 } else {
3248 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3249 DEBUG(10, ("lookup on Server SID\n"));
3250 if(!get_local_group_from_sid(als_sid, &map))
3251 return NT_STATUS_NO_SUCH_ALIAS;
3255 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3256 return NT_STATUS_NO_SUCH_ALIAS;
3258 DEBUG(10, ("sid is %s\n", alias_sid_str));
3259 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
3260 if (num_uids!=0 && sid == NULL)
3261 return NT_STATUS_NO_MEMORY;
3263 for (i = 0; i < num_uids; i++) {
3264 struct passwd *pass;
3265 uint32 rid;
3267 sid_copy(&temp_sid, get_global_sam_sid());
3269 pass = getpwuid_alloc(uid[i]);
3270 if (!pass) continue;
3272 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3273 passwd_free(&pass);
3274 continue;
3277 become_root();
3278 check = pdb_getsampwnam(sam_user, pass->pw_name);
3279 unbecome_root();
3281 if (check != True) {
3282 pdb_free_sam(&sam_user);
3283 passwd_free(&pass);
3284 continue;
3287 rid = pdb_get_user_rid(sam_user);
3288 if (rid == 0) {
3289 pdb_free_sam(&sam_user);
3290 passwd_free(&pass);
3291 continue;
3294 pdb_free_sam(&sam_user);
3295 passwd_free(&pass);
3297 sid_append_rid(&temp_sid, rid);
3299 init_dom_sid2(&sid[i], &temp_sid);
3302 DEBUG(10, ("sid is %s\n", alias_sid_str));
3303 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3305 return NT_STATUS_OK;
3308 /*********************************************************************
3309 _samr_query_groupmem
3310 *********************************************************************/
3312 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3314 int num_uids = 0;
3315 int i;
3316 DOM_SID group_sid;
3317 uint32 group_rid;
3318 fstring group_sid_str;
3319 uid_t *uid=NULL;
3321 GROUP_MAP map;
3323 uint32 *rid=NULL;
3324 uint32 *attr=NULL;
3326 SAM_ACCOUNT *sam_user = NULL;
3327 BOOL check;
3328 uint32 acc_granted;
3330 /* find the policy handle. open a policy on it. */
3331 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3332 return NT_STATUS_INVALID_HANDLE;
3334 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3335 return r_u->status;
3338 /* todo: change to use sid_compare_front */
3340 sid_split_rid(&group_sid, &group_rid);
3341 sid_to_string(group_sid_str, &group_sid);
3342 DEBUG(10, ("sid is %s\n", group_sid_str));
3344 /* can we get a query for an SID outside our domain ? */
3345 if (!sid_equal(&group_sid, get_global_sam_sid()))
3346 return NT_STATUS_NO_SUCH_GROUP;
3348 sid_append_rid(&group_sid, group_rid);
3349 DEBUG(10, ("lookup on Domain SID\n"));
3351 if(!get_domain_group_from_sid(group_sid, &map))
3352 return NT_STATUS_NO_SUCH_GROUP;
3354 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3355 return NT_STATUS_NO_SUCH_GROUP;
3357 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3358 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3360 if (num_uids!=0 && (rid==NULL || attr==NULL))
3361 return NT_STATUS_NO_MEMORY;
3363 for (i=0; i<num_uids; i++) {
3364 struct passwd *pass;
3365 uint32 urid;
3367 pass = getpwuid_alloc(uid[i]);
3368 if (!pass) continue;
3370 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3371 passwd_free(&pass);
3372 continue;
3375 become_root();
3376 check = pdb_getsampwnam(sam_user, pass->pw_name);
3377 unbecome_root();
3379 if (check != True) {
3380 pdb_free_sam(&sam_user);
3381 passwd_free(&pass);
3382 continue;
3385 urid = pdb_get_user_rid(sam_user);
3386 if (urid == 0) {
3387 pdb_free_sam(&sam_user);
3388 passwd_free(&pass);
3389 continue;
3392 pdb_free_sam(&sam_user);
3393 passwd_free(&pass);
3395 rid[i] = urid;
3396 attr[i] = SID_NAME_USER;
3399 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3401 return NT_STATUS_OK;
3404 /*********************************************************************
3405 _samr_add_aliasmem
3406 *********************************************************************/
3408 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3410 DOM_SID alias_sid;
3411 fstring alias_sid_str;
3412 uid_t uid;
3413 struct passwd *pwd;
3414 struct group *grp;
3415 fstring grp_name;
3416 GROUP_MAP map;
3417 NTSTATUS ret;
3418 SAM_ACCOUNT *sam_user = NULL;
3419 BOOL check;
3420 uint32 acc_granted;
3422 /* Find the policy handle. Open a policy on it. */
3423 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3424 return NT_STATUS_INVALID_HANDLE;
3426 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3427 return r_u->status;
3430 sid_to_string(alias_sid_str, &alias_sid);
3431 DEBUG(10, ("sid is %s\n", alias_sid_str));
3433 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3434 DEBUG(10, ("adding member on Server SID\n"));
3435 if(!get_local_group_from_sid(alias_sid, &map))
3436 return NT_STATUS_NO_SUCH_ALIAS;
3438 } else {
3439 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3440 DEBUG(10, ("adding member on BUILTIN SID\n"));
3441 if( !get_local_group_from_sid(alias_sid, &map))
3442 return NT_STATUS_NO_SUCH_ALIAS;
3444 } else
3445 return NT_STATUS_NO_SUCH_ALIAS;
3448 ret = pdb_init_sam(&sam_user);
3449 if (!NT_STATUS_IS_OK(ret))
3450 return ret;
3452 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3454 if (check != True) {
3455 pdb_free_sam(&sam_user);
3456 return NT_STATUS_NO_SUCH_USER;
3459 /* check a real user exist before we run the script to add a user to a group */
3460 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3461 pdb_free_sam(&sam_user);
3462 return NT_STATUS_NO_SUCH_USER;
3465 pdb_free_sam(&sam_user);
3467 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3468 return NT_STATUS_NO_SUCH_USER;
3471 if ((grp=getgrgid(map.gid)) == NULL) {
3472 passwd_free(&pwd);
3473 return NT_STATUS_NO_SUCH_ALIAS;
3476 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3477 fstrcpy(grp_name, grp->gr_name);
3479 /* if the user is already in the group */
3480 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3481 passwd_free(&pwd);
3482 return NT_STATUS_MEMBER_IN_ALIAS;
3486 * ok, the group exist, the user exist, the user is not in the group,
3487 * we can (finally) add it to the group !
3489 smb_add_user_group(grp_name, pwd->pw_name);
3491 /* check if the user has been added then ... */
3492 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3493 passwd_free(&pwd);
3494 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3497 passwd_free(&pwd);
3498 return NT_STATUS_OK;
3501 /*********************************************************************
3502 _samr_del_aliasmem
3503 *********************************************************************/
3505 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3507 DOM_SID alias_sid;
3508 fstring alias_sid_str;
3509 struct group *grp;
3510 fstring grp_name;
3511 GROUP_MAP map;
3512 SAM_ACCOUNT *sam_pass=NULL;
3513 uint32 acc_granted;
3515 /* Find the policy handle. Open a policy on it. */
3516 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3517 return NT_STATUS_INVALID_HANDLE;
3519 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3520 return r_u->status;
3523 sid_to_string(alias_sid_str, &alias_sid);
3524 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3526 if (!sid_check_is_in_our_domain(&alias_sid) &&
3527 !sid_check_is_in_builtin(&alias_sid)) {
3528 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3529 return NT_STATUS_NO_SUCH_ALIAS;
3532 if( !get_local_group_from_sid(alias_sid, &map))
3533 return NT_STATUS_NO_SUCH_ALIAS;
3535 if ((grp=getgrgid(map.gid)) == NULL)
3536 return NT_STATUS_NO_SUCH_ALIAS;
3538 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3539 fstrcpy(grp_name, grp->gr_name);
3541 /* check if the user exists before trying to remove it from the group */
3542 pdb_init_sam(&sam_pass);
3543 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3544 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3545 pdb_free_sam(&sam_pass);
3546 return NT_STATUS_NO_SUCH_USER;
3549 /* if the user is not in the group */
3550 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3551 pdb_free_sam(&sam_pass);
3552 return NT_STATUS_MEMBER_IN_ALIAS;
3555 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3557 /* check if the user has been removed then ... */
3558 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3559 pdb_free_sam(&sam_pass);
3560 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3563 pdb_free_sam(&sam_pass);
3564 return NT_STATUS_OK;
3567 /*********************************************************************
3568 _samr_add_groupmem
3569 *********************************************************************/
3571 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3573 DOM_SID group_sid;
3574 DOM_SID user_sid;
3575 fstring group_sid_str;
3576 uid_t uid;
3577 struct passwd *pwd;
3578 struct group *grp;
3579 fstring grp_name;
3580 GROUP_MAP map;
3581 NTSTATUS ret;
3582 SAM_ACCOUNT *sam_user=NULL;
3583 BOOL check;
3584 uint32 acc_granted;
3586 /* Find the policy handle. Open a policy on it. */
3587 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3588 return NT_STATUS_INVALID_HANDLE;
3590 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3591 return r_u->status;
3594 sid_to_string(group_sid_str, &group_sid);
3595 DEBUG(10, ("sid is %s\n", group_sid_str));
3597 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3598 return NT_STATUS_NO_SUCH_GROUP;
3600 DEBUG(10, ("lookup on Domain SID\n"));
3602 if(!get_domain_group_from_sid(group_sid, &map))
3603 return NT_STATUS_NO_SUCH_GROUP;
3605 sid_copy(&user_sid, get_global_sam_sid());
3606 sid_append_rid(&user_sid, q_u->rid);
3608 ret = pdb_init_sam(&sam_user);
3609 if (!NT_STATUS_IS_OK(ret))
3610 return ret;
3612 check = pdb_getsampwsid(sam_user, &user_sid);
3614 if (check != True) {
3615 pdb_free_sam(&sam_user);
3616 return NT_STATUS_NO_SUCH_USER;
3619 /* check a real user exist before we run the script to add a user to a group */
3620 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3621 pdb_free_sam(&sam_user);
3622 return NT_STATUS_NO_SUCH_USER;
3625 pdb_free_sam(&sam_user);
3627 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3628 return NT_STATUS_NO_SUCH_USER;
3631 if ((grp=getgrgid(map.gid)) == NULL) {
3632 passwd_free(&pwd);
3633 return NT_STATUS_NO_SUCH_GROUP;
3636 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3637 fstrcpy(grp_name, grp->gr_name);
3639 /* if the user is already in the group */
3640 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3641 passwd_free(&pwd);
3642 return NT_STATUS_MEMBER_IN_GROUP;
3646 * ok, the group exist, the user exist, the user is not in the group,
3648 * we can (finally) add it to the group !
3651 smb_add_user_group(grp_name, pwd->pw_name);
3653 /* check if the user has been added then ... */
3654 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3655 passwd_free(&pwd);
3656 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3659 passwd_free(&pwd);
3660 return NT_STATUS_OK;
3663 /*********************************************************************
3664 _samr_del_groupmem
3665 *********************************************************************/
3667 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3669 DOM_SID group_sid;
3670 DOM_SID user_sid;
3671 SAM_ACCOUNT *sam_pass=NULL;
3672 GROUP_MAP map;
3673 fstring grp_name;
3674 struct group *grp;
3675 uint32 acc_granted;
3678 * delete the group member named q_u->rid
3679 * who is a member of the sid associated with the handle
3680 * the rid is a user's rid as the group is a domain group.
3683 /* Find the policy handle. Open a policy on it. */
3684 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3685 return NT_STATUS_INVALID_HANDLE;
3687 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3688 return r_u->status;
3691 if (!sid_check_is_in_our_domain(&group_sid))
3692 return NT_STATUS_NO_SUCH_GROUP;
3694 sid_copy(&user_sid, get_global_sam_sid());
3695 sid_append_rid(&user_sid, q_u->rid);
3697 if (!get_domain_group_from_sid(group_sid, &map))
3698 return NT_STATUS_NO_SUCH_GROUP;
3700 if ((grp=getgrgid(map.gid)) == NULL)
3701 return NT_STATUS_NO_SUCH_GROUP;
3703 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3704 fstrcpy(grp_name, grp->gr_name);
3706 /* check if the user exists before trying to remove it from the group */
3707 pdb_init_sam(&sam_pass);
3708 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3709 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3710 pdb_free_sam(&sam_pass);
3711 return NT_STATUS_NO_SUCH_USER;
3714 /* if the user is not in the group */
3715 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3716 pdb_free_sam(&sam_pass);
3717 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3720 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3722 /* check if the user has been removed then ... */
3723 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3724 pdb_free_sam(&sam_pass);
3725 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3728 pdb_free_sam(&sam_pass);
3729 return NT_STATUS_OK;
3733 /****************************************************************************
3734 Delete a UNIX user on demand.
3735 ****************************************************************************/
3737 static int smb_delete_user(const char *unix_user)
3739 pstring del_script;
3740 int ret;
3742 /* try winbindd first since it is impossible to determine where
3743 a user came from via NSS. Try the delete user script if this fails
3744 meaning the user did not exist in winbindd's list of accounts */
3746 if ( winbind_delete_user( unix_user ) ) {
3747 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3748 return 0;
3752 /* fall back to 'delete user script' */
3754 pstrcpy(del_script, lp_deluser_script());
3755 if (! *del_script)
3756 return -1;
3757 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3758 ret = smbrun(del_script,NULL);
3759 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3761 return ret;
3764 /*********************************************************************
3765 _samr_delete_dom_user
3766 *********************************************************************/
3768 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3770 DOM_SID user_sid;
3771 SAM_ACCOUNT *sam_pass=NULL;
3772 uint32 acc_granted;
3774 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3776 /* Find the policy handle. Open a policy on it. */
3777 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3778 return NT_STATUS_INVALID_HANDLE;
3780 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3781 return r_u->status;
3784 if (!sid_check_is_in_our_domain(&user_sid))
3785 return NT_STATUS_CANNOT_DELETE;
3787 /* check if the user exists before trying to delete */
3788 pdb_init_sam(&sam_pass);
3789 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3790 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3791 pdb_free_sam(&sam_pass);
3792 return NT_STATUS_NO_SUCH_USER;
3795 /* delete the unix side */
3797 * note: we don't check if the delete really happened
3798 * as the script is not necessary present
3799 * and maybe the sysadmin doesn't want to delete the unix side
3801 smb_delete_user(pdb_get_username(sam_pass));
3803 /* and delete the samba side */
3804 if (!pdb_delete_sam_account(sam_pass)) {
3805 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3806 pdb_free_sam(&sam_pass);
3807 return NT_STATUS_CANNOT_DELETE;
3810 pdb_free_sam(&sam_pass);
3812 if (!close_policy_hnd(p, &q_u->user_pol))
3813 return NT_STATUS_OBJECT_NAME_INVALID;
3815 return NT_STATUS_OK;
3818 /*********************************************************************
3819 _samr_delete_dom_group
3820 *********************************************************************/
3822 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3824 DOM_SID group_sid;
3825 DOM_SID dom_sid;
3826 uint32 group_rid;
3827 fstring group_sid_str;
3828 gid_t gid;
3829 struct group *grp;
3830 GROUP_MAP map;
3831 uint32 acc_granted;
3833 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3835 /* Find the policy handle. Open a policy on it. */
3836 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3837 return NT_STATUS_INVALID_HANDLE;
3839 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3840 return r_u->status;
3843 sid_copy(&dom_sid, &group_sid);
3844 sid_to_string(group_sid_str, &dom_sid);
3845 sid_split_rid(&dom_sid, &group_rid);
3847 DEBUG(10, ("sid is %s\n", group_sid_str));
3849 /* we check if it's our SID before deleting */
3850 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3851 return NT_STATUS_NO_SUCH_GROUP;
3853 DEBUG(10, ("lookup on Domain SID\n"));
3855 if(!get_domain_group_from_sid(group_sid, &map))
3856 return NT_STATUS_NO_SUCH_GROUP;
3858 gid=map.gid;
3860 /* check if group really exists */
3861 if ( (grp=getgrgid(gid)) == NULL)
3862 return NT_STATUS_NO_SUCH_GROUP;
3864 /* we can delete the UNIX group */
3865 smb_delete_group(grp->gr_name);
3867 /* check if the group has been successfully deleted */
3868 if ( (grp=getgrgid(gid)) != NULL)
3869 return NT_STATUS_ACCESS_DENIED;
3871 if(!pdb_delete_group_mapping_entry(group_sid))
3872 return NT_STATUS_ACCESS_DENIED;
3874 if (!close_policy_hnd(p, &q_u->group_pol))
3875 return NT_STATUS_OBJECT_NAME_INVALID;
3877 return NT_STATUS_OK;
3880 /*********************************************************************
3881 _samr_delete_dom_alias
3882 *********************************************************************/
3884 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3886 DOM_SID alias_sid;
3887 DOM_SID dom_sid;
3888 uint32 alias_rid;
3889 fstring alias_sid_str;
3890 gid_t gid;
3891 struct group *grp;
3892 GROUP_MAP map;
3893 uint32 acc_granted;
3895 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3897 /* Find the policy handle. Open a policy on it. */
3898 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3899 return NT_STATUS_INVALID_HANDLE;
3901 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3902 return r_u->status;
3905 sid_copy(&dom_sid, &alias_sid);
3906 sid_to_string(alias_sid_str, &dom_sid);
3907 sid_split_rid(&dom_sid, &alias_rid);
3909 DEBUG(10, ("sid is %s\n", alias_sid_str));
3911 /* we check if it's our SID before deleting */
3912 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3913 return NT_STATUS_NO_SUCH_ALIAS;
3915 DEBUG(10, ("lookup on Local SID\n"));
3917 if(!get_local_group_from_sid(alias_sid, &map))
3918 return NT_STATUS_NO_SUCH_ALIAS;
3920 gid=map.gid;
3922 /* check if group really exists */
3923 if ( (grp=getgrgid(gid)) == NULL)
3924 return NT_STATUS_NO_SUCH_ALIAS;
3926 /* we can delete the UNIX group */
3927 smb_delete_group(grp->gr_name);
3929 /* check if the group has been successfully deleted */
3930 if ( (grp=getgrgid(gid)) != NULL)
3931 return NT_STATUS_ACCESS_DENIED;
3933 /* don't check if we removed it as it could be an un-mapped group */
3934 pdb_delete_group_mapping_entry(alias_sid);
3936 if (!close_policy_hnd(p, &q_u->alias_pol))
3937 return NT_STATUS_OBJECT_NAME_INVALID;
3939 return NT_STATUS_OK;
3942 /*********************************************************************
3943 _samr_create_dom_group
3944 *********************************************************************/
3946 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3948 DOM_SID dom_sid;
3949 DOM_SID info_sid;
3950 fstring name;
3951 fstring sid_string;
3952 struct group *grp;
3953 struct samr_info *info;
3954 uint32 acc_granted;
3955 gid_t gid;
3957 /* Find the policy handle. Open a policy on it. */
3958 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3959 return NT_STATUS_INVALID_HANDLE;
3961 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3962 return r_u->status;
3965 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3966 return NT_STATUS_ACCESS_DENIED;
3968 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3970 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3972 /* check if group already exist */
3973 if ((grp=getgrnam(name)) != NULL)
3974 return NT_STATUS_GROUP_EXISTS;
3976 /* we can create the UNIX group */
3977 if (smb_create_group(name, &gid) != 0)
3978 return NT_STATUS_ACCESS_DENIED;
3980 /* check if the group has been successfully created */
3981 if ((grp=getgrgid(gid)) == NULL)
3982 return NT_STATUS_ACCESS_DENIED;
3984 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3986 /* add the group to the mapping table */
3987 sid_copy(&info_sid, get_global_sam_sid());
3988 sid_append_rid(&info_sid, r_u->rid);
3989 sid_to_string(sid_string, &info_sid);
3991 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3992 return NT_STATUS_ACCESS_DENIED;
3994 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3995 return NT_STATUS_NO_MEMORY;
3997 /* get a (unique) handle. open a policy on it. */
3998 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3999 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4001 return NT_STATUS_OK;
4004 /*********************************************************************
4005 _samr_create_dom_alias
4006 *********************************************************************/
4008 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4010 DOM_SID dom_sid;
4011 DOM_SID info_sid;
4012 fstring name;
4013 fstring sid_string;
4014 struct group *grp;
4015 struct samr_info *info;
4016 uint32 acc_granted;
4017 gid_t gid;
4019 /* Find the policy handle. Open a policy on it. */
4020 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4021 return NT_STATUS_INVALID_HANDLE;
4023 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4024 return r_u->status;
4027 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4028 return NT_STATUS_ACCESS_DENIED;
4030 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
4032 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4034 /* check if group already exists */
4035 if ( (grp=getgrnam(name)) != NULL)
4036 return NT_STATUS_GROUP_EXISTS;
4038 /* we can create the UNIX group */
4039 if (smb_create_group(name, &gid) != 0)
4040 return NT_STATUS_ACCESS_DENIED;
4042 /* check if the group has been successfully created */
4043 if ((grp=getgrgid(gid)) == NULL)
4044 return NT_STATUS_ACCESS_DENIED;
4046 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4048 sid_copy(&info_sid, get_global_sam_sid());
4049 sid_append_rid(&info_sid, r_u->rid);
4050 sid_to_string(sid_string, &info_sid);
4052 /* add the group to the mapping table */
4053 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
4054 return NT_STATUS_ACCESS_DENIED;
4056 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4057 return NT_STATUS_NO_MEMORY;
4059 /* get a (unique) handle. open a policy on it. */
4060 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4061 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4063 return NT_STATUS_OK;
4066 /*********************************************************************
4067 _samr_query_groupinfo
4069 sends the name/comment pair of a domain group
4070 level 1 send also the number of users of that group
4071 *********************************************************************/
4073 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4075 DOM_SID group_sid;
4076 GROUP_MAP map;
4077 uid_t *uid=NULL;
4078 int num_uids=0;
4079 GROUP_INFO_CTR *ctr;
4080 uint32 acc_granted;
4082 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4083 return NT_STATUS_INVALID_HANDLE;
4085 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4086 return r_u->status;
4089 if (!get_domain_group_from_sid(group_sid, &map))
4090 return NT_STATUS_INVALID_HANDLE;
4092 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4093 if (ctr==NULL)
4094 return NT_STATUS_NO_MEMORY;
4096 switch (q_u->switch_level) {
4097 case 1:
4098 ctr->switch_value1 = 1;
4099 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4100 return NT_STATUS_NO_SUCH_GROUP;
4101 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4102 SAFE_FREE(uid);
4103 break;
4104 case 3:
4105 ctr->switch_value1 = 3;
4106 init_samr_group_info3(&ctr->group.info3);
4107 break;
4108 case 4:
4109 ctr->switch_value1 = 4;
4110 init_samr_group_info4(&ctr->group.info4, map.comment);
4111 break;
4112 default:
4113 return NT_STATUS_INVALID_INFO_CLASS;
4116 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4118 return NT_STATUS_OK;
4121 /*********************************************************************
4122 _samr_set_groupinfo
4124 update a domain group's comment.
4125 *********************************************************************/
4127 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4129 DOM_SID group_sid;
4130 GROUP_MAP map;
4131 GROUP_INFO_CTR *ctr;
4132 uint32 acc_granted;
4134 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4135 return NT_STATUS_INVALID_HANDLE;
4137 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4138 return r_u->status;
4141 if (!get_domain_group_from_sid(group_sid, &map))
4142 return NT_STATUS_NO_SUCH_GROUP;
4144 ctr=q_u->ctr;
4146 switch (ctr->switch_value1) {
4147 case 1:
4148 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4149 break;
4150 case 4:
4151 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4152 break;
4153 default:
4154 return NT_STATUS_INVALID_INFO_CLASS;
4157 if(!pdb_update_group_mapping_entry(&map)) {
4158 return NT_STATUS_NO_SUCH_GROUP;
4161 return NT_STATUS_OK;
4164 /*********************************************************************
4165 _samr_set_aliasinfo
4167 update an alias's comment.
4168 *********************************************************************/
4170 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4172 DOM_SID group_sid;
4173 GROUP_MAP map;
4174 ALIAS_INFO_CTR *ctr;
4175 uint32 acc_granted;
4177 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4178 return NT_STATUS_INVALID_HANDLE;
4180 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4181 return r_u->status;
4184 if (!get_local_group_from_sid(group_sid, &map))
4185 return NT_STATUS_NO_SUCH_GROUP;
4187 ctr=&q_u->ctr;
4189 switch (ctr->switch_value1) {
4190 case 3:
4191 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4192 break;
4193 default:
4194 return NT_STATUS_INVALID_INFO_CLASS;
4197 if(!pdb_update_group_mapping_entry(&map)) {
4198 return NT_STATUS_NO_SUCH_GROUP;
4201 return NT_STATUS_OK;
4204 /*********************************************************************
4205 _samr_get_dom_pwinfo
4206 *********************************************************************/
4208 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4210 /* Perform access check. Since this rpc does not require a
4211 policy handle it will not be caught by the access checks on
4212 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4214 if (!pipe_access_check(p)) {
4215 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4216 r_u->status = NT_STATUS_ACCESS_DENIED;
4217 return r_u->status;
4220 /* Actually, returning zeros here works quite well :-). */
4222 return NT_STATUS_OK;
4225 /*********************************************************************
4226 _samr_open_group
4227 *********************************************************************/
4229 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4231 DOM_SID sid;
4232 DOM_SID info_sid;
4233 GROUP_MAP map;
4234 struct samr_info *info;
4235 SEC_DESC *psd = NULL;
4236 uint32 acc_granted;
4237 uint32 des_access;
4238 size_t sd_size;
4239 NTSTATUS status;
4240 fstring sid_string;
4242 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4243 return NT_STATUS_INVALID_HANDLE;
4245 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4246 return status;
4249 /*check if access can be granted as requested by client. */
4250 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4251 se_map_generic(&des_access,&grp_generic_mapping);
4252 if (!NT_STATUS_IS_OK(status =
4253 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4254 des_access, &acc_granted, "_samr_open_group"))) {
4255 return status;
4259 /* this should not be hard-coded like this */
4260 if (!sid_equal(&sid, get_global_sam_sid()))
4261 return NT_STATUS_ACCESS_DENIED;
4263 sid_copy(&info_sid, get_global_sam_sid());
4264 sid_append_rid(&info_sid, q_u->rid_group);
4265 sid_to_string(sid_string, &info_sid);
4267 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4268 return NT_STATUS_NO_MEMORY;
4270 info->acc_granted = acc_granted;
4272 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4274 /* check if that group really exists */
4275 if (!get_domain_group_from_sid(info->sid, &map))
4276 return NT_STATUS_NO_SUCH_GROUP;
4278 /* get a (unique) handle. open a policy on it. */
4279 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4280 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4282 return NT_STATUS_OK;
4285 /*********************************************************************
4286 _samr_unknown_2d
4287 *********************************************************************/
4289 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
4291 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
4292 return NT_STATUS_NOT_IMPLEMENTED;
4295 /*******************************************************************
4296 _samr_unknown_2e
4297 ********************************************************************/
4299 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4301 struct samr_info *info = NULL;
4302 SAM_UNK_CTR *ctr;
4303 uint32 min_pass_len,pass_hist,flag;
4304 time_t u_expire, u_min_age;
4305 NTTIME nt_expire, nt_min_age;
4307 time_t u_lock_duration, u_reset_time;
4308 NTTIME nt_lock_duration, nt_reset_time;
4309 uint32 lockout;
4311 time_t u_logout;
4312 NTTIME nt_logout;
4314 uint32 num_users=0, num_groups=0, num_aliases=0;
4316 uint32 account_policy_temp;
4318 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4319 return NT_STATUS_NO_MEMORY;
4321 ZERO_STRUCTP(ctr);
4323 r_u->status = NT_STATUS_OK;
4325 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4327 /* find the policy handle. open a policy on it. */
4328 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4329 return NT_STATUS_INVALID_HANDLE;
4331 switch (q_u->switch_value) {
4332 case 0x01:
4333 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4334 min_pass_len = account_policy_temp;
4336 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4337 pass_hist = account_policy_temp;
4339 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4340 flag = account_policy_temp;
4342 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4343 u_expire = account_policy_temp;
4345 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4346 u_min_age = account_policy_temp;
4348 unix_to_nt_time_abs(&nt_expire, u_expire);
4349 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4351 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4352 flag, nt_expire, nt_min_age);
4353 break;
4354 case 0x02:
4355 become_root();
4356 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4357 unbecome_root();
4358 if (!NT_STATUS_IS_OK(r_u->status)) {
4359 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4360 return r_u->status;
4362 num_users=info->disp_info.num_user_account;
4363 free_samr_db(info);
4365 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4366 if (NT_STATUS_IS_ERR(r_u->status)) {
4367 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4368 return r_u->status;
4370 num_groups=info->disp_info.num_group_account;
4371 free_samr_db(info);
4373 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4374 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4375 num_users, num_groups, num_aliases);
4376 break;
4377 case 0x03:
4378 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4379 u_logout = account_policy_temp;
4381 unix_to_nt_time_abs(&nt_logout, u_logout);
4383 init_unk_info3(&ctr->info.inf3, nt_logout);
4384 break;
4385 case 0x05:
4386 init_unk_info5(&ctr->info.inf5, global_myname());
4387 break;
4388 case 0x06:
4389 init_unk_info6(&ctr->info.inf6);
4390 break;
4391 case 0x07:
4392 init_unk_info7(&ctr->info.inf7);
4393 break;
4394 case 0x0c:
4395 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4396 u_lock_duration = account_policy_temp;
4398 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4399 u_reset_time = account_policy_temp;
4401 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4402 lockout = account_policy_temp;
4404 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4405 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4407 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4408 break;
4409 default:
4410 return NT_STATUS_INVALID_INFO_CLASS;
4413 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4415 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4417 return r_u->status;
4420 /*******************************************************************
4421 _samr_
4422 ********************************************************************/
4424 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4426 time_t u_expire, u_min_age;
4427 time_t u_logout;
4428 time_t u_lock_duration, u_reset_time;
4430 r_u->status = NT_STATUS_OK;
4432 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4434 /* find the policy handle. open a policy on it. */
4435 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4436 return NT_STATUS_INVALID_HANDLE;
4438 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4440 switch (q_u->switch_value) {
4441 case 0x01:
4442 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4443 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4445 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4446 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4447 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4448 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4449 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4450 break;
4451 case 0x02:
4452 break;
4453 case 0x03:
4454 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4455 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4456 break;
4457 case 0x05:
4458 break;
4459 case 0x06:
4460 break;
4461 case 0x07:
4462 break;
4463 case 0x0c:
4464 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4465 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4467 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4468 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4469 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4470 break;
4471 default:
4472 return NT_STATUS_INVALID_INFO_CLASS;
4475 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4477 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4479 return r_u->status;