fix restart option (noticed by Stanford K. Baldwin)
[Samba.git] / source / rpc_server / srv_samr_nt.c
blob2ce5ed74274314fa25331143c8ca455991995959
1 /*
2 * Unix SMB/Netbios implementation.
3 * Version 1.9.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1997,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7 * Copyright (C) Paul Ashton 1997.
8 * Copyright (C) Marc Jacobsen 1999.
9 * Copyright (C) Jeremy Allison 2001-2002.
10 * Copyright (C) Jean François Micouleau 1998-2001.
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 extern fstring global_myworkgroup;
34 extern pstring global_myname;
35 extern DOM_SID global_sam_sid;
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[];
42 typedef struct _disp_info {
43 BOOL user_dbloaded;
44 uint32 num_user_account;
45 DISP_USER_INFO *disp_user_info;
46 BOOL group_dbloaded;
47 uint32 num_group_account;
48 DISP_GROUP_INFO *disp_group_info;
49 } DISP_INFO;
51 struct samr_info {
52 /* for use by the \PIPE\samr policy */
53 DOM_SID sid;
54 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
55 DISP_INFO disp_info;
58 /*******************************************************************
59 Create a samr_info struct.
60 ********************************************************************/
62 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
64 struct samr_info *info;
65 fstring sid_str;
67 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
68 return NULL;
70 ZERO_STRUCTP(info);
71 if (psid) {
72 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_to_string(sid_str, psid) ));
73 sid_copy( &info->sid, psid);
74 } else {
75 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
77 return info;
80 /*******************************************************************
81 Function to free the per handle data.
82 ********************************************************************/
84 static void free_samr_db(struct samr_info *info)
86 int i;
88 if (info->disp_info.group_dbloaded) {
89 for (i=0; i<info->disp_info.num_group_account; i++)
90 SAFE_FREE(info->disp_info.disp_group_info[i].grp);
92 SAFE_FREE(info->disp_info.disp_group_info);
95 if (info->disp_info.user_dbloaded){
96 for (i=0; i<info->disp_info.num_user_account; i++)
97 pdb_free_sam(info->disp_info.disp_user_info[i].sam);
99 SAFE_FREE(info->disp_info.disp_user_info);
102 info->disp_info.user_dbloaded=False;
103 info->disp_info.group_dbloaded=False;
104 info->disp_info.num_group_account=0;
105 info->disp_info.num_user_account=0;
108 /*******************************************************************
109 Function to free the per handle data.
110 ********************************************************************/
112 static void free_samr_info(void *ptr)
114 struct samr_info *info=(struct samr_info *) ptr;
116 free_samr_db(info);
117 SAFE_FREE(info);
120 /*******************************************************************
121 Ensure password info is never given out. Paranioa... JRA.
122 ********************************************************************/
124 static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
126 int i;
128 if (!pass)
129 return;
131 for (i = 0; i < num_entries; i++) {
132 memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
133 memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
137 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
139 if (!sam_pass)
140 return;
142 if (sam_pass->lm_pw)
143 memset(sam_pass->lm_pw, '\0', 16);
144 if (sam_pass->nt_pw)
145 memset(sam_pass->nt_pw, '\0', 16);
148 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask)
150 SAM_ACCOUNT *pwd = NULL;
151 DISP_USER_INFO *pwd_array = NULL;
153 DEBUG(10,("load_sampwd_entries\n"));
155 /* if the snapshoot is already loaded, return */
156 if (info->disp_info.user_dbloaded==True) {
157 DEBUG(10,("load_sampwd_entries: already in memory\n"));
158 return NT_STATUS_OK;
161 if (!pdb_setsampwent(False)) {
162 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
163 return NT_STATUS_ACCESS_DENIED;
166 for (pdb_init_sam(&pwd); pdb_getsampwent(pwd) == True; pwd=NULL, pdb_init_sam(&pwd) ) {
168 if (acb_mask != 0 && !(pwd->acct_ctrl & acb_mask)) {
169 pdb_free_sam(pwd);
170 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
171 continue;
174 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
175 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
177 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
178 pwd_array=(DISP_USER_INFO *)Realloc(info->disp_info.disp_user_info,
179 (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
181 if (pwd_array==NULL)
182 return NT_STATUS_NO_MEMORY;
184 info->disp_info.disp_user_info=pwd_array;
187 /* link the SAM_ACCOUNT to the array */
188 info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
190 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
192 info->disp_info.num_user_account++;
195 pdb_endsampwent();
197 /* the snapshoot is in memory, we're ready to enumerate fast */
199 info->disp_info.user_dbloaded=True;
201 DEBUG(12,("load_sampwd_entries: done\n"));
203 return NT_STATUS_OK;
207 * This is a really ugly hack to make this interface work in the 2.2.x code. JRA.
208 * Return a malloced map so we can free it.
211 static int setup_fake_group_map(GROUP_MAP **ret_map)
213 static GROUP_MAP static_map[2];
214 static BOOL group_map_init;
215 extern DOM_SID global_sam_sid;
217 *ret_map = (GROUP_MAP *)malloc(sizeof(GROUP_MAP)*2);
218 if (!ret_map)
219 return 2;
221 if (group_map_init) {
222 memcpy( *ret_map, &static_map[0], sizeof(GROUP_MAP)*2);
223 return sizeof(static_map)/sizeof(GROUP_MAP);
226 group_map_init = True;
228 static_map[0].gid = (gid_t)-1;
229 sid_copy(&static_map[0].sid, &global_sam_sid);
230 sid_append_rid(&static_map[0].sid, DOMAIN_GROUP_RID_ADMINS);
231 static_map[0].sid_name_use = SID_NAME_DOM_GRP;
232 fstrcpy(static_map[0].nt_name, "Domain Admins");
233 fstrcpy(static_map[0].comment, "Administrators for the domain");
234 static_map[0].privilege = 0;
236 static_map[1].gid = (gid_t)-1;
237 sid_copy(&static_map[1].sid, &global_sam_sid);
238 sid_append_rid(&static_map[1].sid, DOMAIN_GROUP_RID_USERS);
239 static_map[1].sid_name_use = SID_NAME_DOM_GRP;
240 fstrcpy(static_map[1].nt_name, "Domain Users");
241 fstrcpy(static_map[1].comment, "Users in the domain");
242 static_map[1].privilege = 0;
244 memcpy( *ret_map, &static_map[0], sizeof(GROUP_MAP)*2);
245 return sizeof(static_map)/sizeof(GROUP_MAP);
248 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
250 GROUP_MAP *map;
251 DISP_GROUP_INFO *grp_array = NULL;
252 uint32 group_entries = 0;
253 uint32 i;
255 DEBUG(10,("load_group_domain_entries\n"));
257 /* if the snapshoot is already loaded, return */
258 if (info->disp_info.group_dbloaded==True) {
259 DEBUG(10,("load_group_domain_entries: already in memory\n"));
260 return NT_STATUS_OK;
264 * This is a really ugly hack to make this interface work in the 2.2.x code. JRA.
267 group_entries = setup_fake_group_map(&map);
269 info->disp_info.num_group_account=group_entries;
271 grp_array=(DISP_GROUP_INFO *)malloc(info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
273 if (group_entries!=0 && grp_array==NULL) {
274 return NT_STATUS_NO_MEMORY;
277 info->disp_info.disp_group_info=grp_array;
279 for (i=0; i<group_entries; i++) {
281 grp_array[i].grp=(DOMAIN_GRP *)malloc(sizeof(DOMAIN_GRP));
283 fstrcpy(grp_array[i].grp->name, map[i].nt_name);
284 fstrcpy(grp_array[i].grp->comment, map[i].comment);
285 sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
286 grp_array[i].grp->attr=SID_NAME_DOM_GRP;
289 SAFE_FREE(map);
291 /* the snapshoot is in memory, we're ready to enumerate fast */
293 info->disp_info.group_dbloaded=True;
295 DEBUG(12,("load_group_domain_entries: done\n"));
297 return NT_STATUS_OK;
300 /*******************************************************************
301 This next function should be replaced with something that
302 dynamically returns the correct user info..... JRA.
303 ********************************************************************/
305 static NTSTATUS get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
306 int *total_entries, int *num_entries,
307 int max_num_entries, uint16 acb_mask)
309 SAM_ACCOUNT *pwd = NULL;
310 BOOL not_finished = True;
312 (*num_entries) = 0;
313 (*total_entries) = 0;
315 if (pw_buf == NULL)
316 return NT_STATUS_NO_MEMORY;
318 pdb_init_sam(&pwd);
320 if (!pdb_setsampwent(False)) {
321 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
322 pdb_free_sam(pwd);
323 return NT_STATUS_ACCESS_DENIED;
326 while (((not_finished = pdb_getsampwent(pwd)) != False)
327 && (*num_entries) < max_num_entries)
329 int user_name_len;
331 if (start_idx > 0) {
333 pdb_reset_sam(pwd);
335 /* skip the requested number of entries.
336 not very efficient, but hey... */
337 start_idx--;
338 continue;
341 user_name_len = strlen(pdb_get_username(pwd))+1;
342 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
343 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
344 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
345 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
347 /* Now check if the NT compatible password is available. */
348 if (pdb_get_nt_passwd(pwd))
349 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
351 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
353 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
354 (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
356 if (acb_mask == 0 || (pwd->acct_ctrl & acb_mask)) {
357 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
358 (*num_entries)++;
359 } else {
360 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
363 (*total_entries)++;
365 pdb_reset_sam(pwd);
369 pdb_endsampwent();
370 pdb_free_sam(pwd);
372 if (not_finished)
373 return STATUS_MORE_ENTRIES;
374 else
375 return NT_STATUS_OK;
378 /*******************************************************************
379 _samr_close_hnd
380 ********************************************************************/
382 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
384 r_u->status = NT_STATUS_OK;
386 /* close the policy handle */
387 if (!close_policy_hnd(p, &q_u->pol))
388 return NT_STATUS_OBJECT_NAME_INVALID;
390 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
392 return r_u->status;
395 /*******************************************************************
396 samr_reply_open_domain
397 ********************************************************************/
399 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
401 struct samr_info *info;
403 r_u->status = NT_STATUS_OK;
405 /* find the connection policy handle. */
406 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
407 return NT_STATUS_INVALID_HANDLE;
409 /* associate the domain SID with the (unique) handle. */
410 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
411 return NT_STATUS_NO_MEMORY;
413 /* get a (unique) handle. open a policy on it. */
414 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
415 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
417 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
419 return r_u->status;
422 static uint32 get_lsa_policy_samr_rid(struct samr_info *info)
424 if (!info) {
425 DEBUG(3,("Error getting policy\n"));
426 return 0xffffffff;
429 return info->sid.sub_auths[info->sid.num_auths-1];
432 /*******************************************************************
433 _samr_get_usrdom_pwinfo
434 ********************************************************************/
436 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
438 struct samr_info *info = NULL;
440 r_u->status = NT_STATUS_OK;
442 /* find the policy handle. open a policy on it. */
443 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info)) {
444 return NT_STATUS_INVALID_HANDLE;
447 /* find the user's rid */
448 if (get_lsa_policy_samr_rid(info) == 0xffffffff) {
449 return NT_STATUS_OBJECT_TYPE_MISMATCH;
452 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
454 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
456 return r_u->status;
459 /*******************************************************************
460 samr_make_usr_obj_sd
461 ********************************************************************/
463 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
465 extern DOM_SID global_sid_Builtin;
466 extern DOM_SID global_sid_World;
467 DOM_SID adm_sid;
468 DOM_SID act_sid;
470 SEC_ACE ace[4];
471 SEC_ACCESS mask;
473 SEC_ACL *psa = NULL;
474 SEC_DESC *psd = NULL;
475 size_t sd_size;
477 sid_copy(&adm_sid, &global_sid_Builtin);
478 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
480 sid_copy(&act_sid, &global_sid_Builtin);
481 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
483 init_sec_access(&mask, 0x2035b);
484 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
486 init_sec_access(&mask, 0xf07ff);
487 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
488 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
490 init_sec_access(&mask,0x20044);
491 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
493 if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
494 return NT_STATUS_NO_MEMORY;
496 if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
497 return NT_STATUS_NO_MEMORY;
499 if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
500 return NT_STATUS_NO_MEMORY;
502 return NT_STATUS_OK;
505 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
507 struct samr_info *info = NULL;
509 /* find the policy handle. open a policy on it. */
510 if (!find_policy_by_hnd(p, pol, (void **)&info))
511 return False;
513 if (!info)
514 return False;
516 *sid = info->sid;
517 return True;
520 /*******************************************************************
521 _samr_query_sec_obj
522 ********************************************************************/
524 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
526 DOM_SID pol_sid;
528 r_u->status = NT_STATUS_OK;
530 /* Get the SID. */
532 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
533 return NT_STATUS_INVALID_HANDLE;
535 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
537 if (NT_STATUS_IS_OK(r_u->status))
538 r_u->ptr = 1;
540 return r_u->status;
543 /*******************************************************************
544 makes a SAM_ENTRY / UNISTR2* structure from a user list.
545 ********************************************************************/
547 static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
548 uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
550 uint32 i;
551 SAM_ENTRY *sam;
552 UNISTR2 *uni_name;
554 *sam_pp = NULL;
555 *uni_name_pp = NULL;
557 if (num_sam_entries == 0)
558 return;
560 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
562 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
564 if (sam == NULL || uni_name == NULL) {
565 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
566 return;
569 for (i = 0; i < num_sam_entries; i++) {
570 int len = pass[i].uni_user_name.uni_str_len;
572 init_sam_entry(&sam[i], len, pass[i].user_rid);
573 copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
576 *sam_pp = sam;
577 *uni_name_pp = uni_name;
580 /*******************************************************************
581 samr_reply_enum_dom_users
582 ********************************************************************/
584 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
586 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
587 int num_entries = 0;
588 int total_entries = 0;
590 r_u->status = NT_STATUS_OK;
592 /* find the policy handle. open a policy on it. */
593 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
594 return NT_STATUS_INVALID_HANDLE;
596 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
598 become_root();
599 r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
600 MAX_SAM_ENTRIES, q_u->acb_mask);
601 unbecome_root();
603 if (NT_STATUS_IS_ERR(r_u->status))
604 return r_u->status;
606 samr_clear_passwd_fields(pass, num_entries);
609 * Note from JRA. total_entries is not being used here. Currently if there is a
610 * large user base then it looks like NT will enumerate until get_sampwd_entries
611 * returns False due to num_entries being zero. This will cause an access denied
612 * return. I don't think this is right and needs further investigation. Note that
613 * this is also the same in the TNG code (I don't think that has been tested with
614 * a very large user list as MAX_SAM_ENTRIES is set to 600).
616 * I also think that one of the 'num_entries' return parameters is probably
617 * the "max entries" parameter - but in the TNG code they're all currently set to the same
618 * value (again I think this is wrong).
621 make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
623 init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
625 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
627 return r_u->status;
630 /*******************************************************************
631 makes a SAM_ENTRY / UNISTR2* structure from a group list.
632 ********************************************************************/
634 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
635 uint32 num_sam_entries, DOMAIN_GRP *grp)
637 uint32 i;
638 SAM_ENTRY *sam;
639 UNISTR2 *uni_name;
641 *sam_pp = NULL;
642 *uni_name_pp = NULL;
644 if (num_sam_entries == 0)
645 return;
647 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
649 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
651 if (sam == NULL || uni_name == NULL) {
652 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
653 return;
656 for (i = 0; i < num_sam_entries; i++) {
658 * JRA. I think this should include the null. TNG does not.
660 int len = strlen(unix_to_dos_static(grp[i].name))+1;
662 init_sam_entry(&sam[i], len, grp[i].rid);
663 init_unistr2(&uni_name[i], unix_to_dos_static(grp[i].name), len);
666 *sam_pp = sam;
667 *uni_name_pp = uni_name;
670 /*******************************************************************
671 Get the group entries - similar to get_sampwd_entries().
672 ********************************************************************/
674 static NTSTATUS get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
675 uint32 *p_num_entries, uint32 max_entries)
677 fstring sid_str;
678 fstring sam_sid_str;
679 uint32 num_entries = 0;
681 sid_to_string(sid_str, sid);
682 sid_to_string(sam_sid_str, &global_sam_sid);
684 *p_num_entries = 0;
686 /* well-known aliases */
687 if (strequal(sid_str, "S-1-5-32")) {
688 const char *alias_name;
689 while (!lp_hide_local_users() &&
690 num_entries < max_entries &&
691 ((alias_name = builtin_alias_rids[num_entries].name) != NULL)) {
693 fstrcpy(d_grp[num_entries].name, alias_name);
694 d_grp[num_entries].rid = builtin_alias_rids[num_entries].rid;
696 num_entries++;
698 } else if (strequal(sid_str, sam_sid_str) && !lp_hide_local_users()) {
699 fstring name;
700 char *sep;
701 struct sys_grent *glist;
702 struct sys_grent *grp;
704 sep = lp_winbind_separator();
706 /* local aliases */
707 /* we return the UNIX groups here. This seems to be the right */
708 /* thing to do, since NT member servers return their local */
709 /* groups in the same situation. */
711 /* use getgrent_list() to retrieve the list of groups to avoid
712 * problems with getgrent possible infinite loop by internal
713 * libc grent structures overwrites by called functions */
714 grp = glist = getgrent_list();
715 if (grp == NULL)
716 return NT_STATUS_NO_MEMORY;
718 for (;(num_entries < max_entries) && (grp != NULL); grp = grp->next) {
719 int i;
720 uint32 trid;
722 fstrcpy(name,grp->gr_name);
723 DEBUG(10,("get_group_alias_entries: got group %s\n", name ));
725 /* Don't return winbind groups as they are not local! */
727 if (strchr(name, *sep) != NULL) {
728 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", name ));
729 continue;
732 /* Don't return user private groups... */
733 if (Get_Pwnam(name, False) != 0) {
734 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", name ));
735 continue;
738 trid = pdb_gid_to_group_rid(grp->gr_gid);
739 for( i = 0; i < num_entries; i++)
740 if ( d_grp[i].rid == trid )
741 break;
743 if ( i < num_entries )
744 continue; /* rid was there, dup! */
746 /* JRA - added this for large group db enumeration... */
748 if (start_idx > 0) {
749 /* skip the requested number of entries.
750 not very efficient, but hey...
752 start_idx--;
753 continue;
756 fstrcpy(d_grp[num_entries].name, name);
757 d_grp[num_entries].rid = trid;
758 num_entries++;
761 grent_free(glist);
764 *p_num_entries = num_entries;
766 if (num_entries >= max_entries)
767 return STATUS_MORE_ENTRIES;
768 return NT_STATUS_OK;
771 /*******************************************************************
772 Get the group entries - similar to get_sampwd_entries().
773 ********************************************************************/
775 static NTSTATUS get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
776 uint32 *p_num_entries, uint32 max_entries)
778 fstring sid_str;
779 fstring sam_sid_str;
780 uint32 num_entries = 0;
781 fstring name="Domain Admins";
782 fstring comment="Just to make it work !";
784 sid_to_string(sid_str, sid);
785 sid_to_string(sam_sid_str, &global_sam_sid);
787 *p_num_entries = 0;
789 fstrcpy(d_grp[0].name, name);
790 fstrcpy(d_grp[0].comment, comment);
791 d_grp[0].rid = DOMAIN_GROUP_RID_ADMINS;
792 d_grp[0].attr=SID_NAME_DOM_GRP;
794 fstrcpy(d_grp[1].name, "Domain Users");
795 fstrcpy(d_grp[1].comment, "Just to make it work !");
796 d_grp[1].rid = DOMAIN_GROUP_RID_USERS;
797 d_grp[1].attr=SID_NAME_DOM_GRP;
799 num_entries = 2;
801 *p_num_entries = num_entries;
803 return NT_STATUS_OK;
806 /*******************************************************************
807 samr_reply_enum_dom_groups
808 Only reply with one group - domain admins. This must be fixed for
809 a real PDC. JRA.
810 ********************************************************************/
812 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
814 DOMAIN_GRP grp[2];
815 uint32 num_entries;
816 DOM_SID sid;
818 r_u->status = NT_STATUS_OK;
820 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
821 return NT_STATUS_INVALID_HANDLE;
823 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
825 get_group_domain_entries(grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
827 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
829 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
831 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
833 return r_u->status;
837 /*******************************************************************
838 samr_reply_enum_dom_aliases
839 ********************************************************************/
841 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
843 DOMAIN_GRP grp[MAX_SAM_ENTRIES];
844 uint32 num_entries = 0;
845 fstring sid_str;
846 DOM_SID sid;
848 r_u->status = NT_STATUS_OK;
850 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
851 return NT_STATUS_INVALID_HANDLE;
853 sid_to_string(sid_str, &sid);
854 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
856 r_u->status = get_group_alias_entries(grp, &sid, q_u->start_idx,
857 &num_entries, MAX_SAM_ENTRIES);
858 if (NT_STATUS_IS_ERR(r_u->status))
859 return r_u->status;
861 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
863 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
865 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
867 return r_u->status;
870 /*******************************************************************
871 samr_reply_query_dispinfo
872 ********************************************************************/
873 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
875 struct samr_info *info = NULL;
876 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
877 uint16 acb_mask;
879 uint32 max_entries=q_u->max_entries;
880 uint32 enum_context=q_u->start_idx;
881 uint32 max_size=q_u->max_size;
883 SAM_DISPINFO_CTR *ctr;
884 uint32 temp_size=0, total_data_size=0;
885 NTSTATUS disp_ret;
886 uint32 num_account = 0;
887 enum remote_arch_types ra_type = get_remote_arch();
888 int max_sam_entries;
890 max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
892 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
893 r_u->status = NT_STATUS_OK;
895 /* find the policy handle. open a policy on it. */
896 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
897 return NT_STATUS_INVALID_HANDLE;
900 * calculate how many entries we will return.
901 * based on
902 * - the number of entries the client asked
903 * - our limit on that
904 * - the starting point (enumeration context)
905 * - the buffer size the client will accept
909 * We are a lot more like W2K. Instead of reading the SAM
910 * each time to find the records we need to send back,
911 * we read it once and link that copy to the sam handle.
912 * For large user list (over the MAX_SAM_ENTRIES)
913 * it's a definitive win.
914 * second point to notice: between enumerations
915 * our sam is now the same as it's a snapshoot.
916 * third point: got rid of the static SAM_USER_21 struct
917 * no more intermediate.
918 * con: it uses much more memory, as a full copy is stored
919 * in memory.
921 * If you want to change it, think twice and think
922 * of the second point , that's really important.
924 * JFM, 12/20/2001
927 /* Get what we need from the password database */
929 if (q_u->switch_level==2)
930 acb_mask = ACB_WSTRUST;
931 else
932 acb_mask = ACB_NORMAL;
934 /* Get what we need from the password database */
935 switch (q_u->switch_level) {
936 case 0x1:
937 case 0x2:
938 case 0x4:
939 become_root();
940 r_u->status=load_sampwd_entries(info, acb_mask);
941 unbecome_root();
942 if (NT_STATUS_IS_ERR(r_u->status)) {
943 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
944 return r_u->status;
946 num_account = info->disp_info.num_user_account;
947 break;
948 case 0x3:
949 case 0x5:
950 r_u->status = load_group_domain_entries(info, &info->sid);
951 if (NT_STATUS_IS_ERR(r_u->status))
952 return r_u->status;
953 num_account = info->disp_info.num_group_account;
954 break;
955 default:
956 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
957 return NT_STATUS_INVALID_INFO_CLASS;
960 /* first limit the number of entries we will return */
961 if(max_entries > max_sam_entries) {
962 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
963 max_entries = max_sam_entries;
966 if (enum_context > num_account) {
967 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
968 return NT_STATUS_OK;
971 /* verify we won't overflow */
972 if (max_entries > num_account-enum_context) {
973 max_entries = num_account-enum_context;
974 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
977 /* calculate the size and limit on the number of entries we will return */
978 temp_size=max_entries*struct_size;
980 if (temp_size>max_size) {
981 max_entries=MIN((max_size/struct_size),max_entries);
982 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
985 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
986 return NT_STATUS_NO_MEMORY;
988 ZERO_STRUCTP(ctr);
990 /* Now create reply structure */
991 switch (q_u->switch_level) {
992 case 0x1:
993 if (max_entries) {
994 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
995 return NT_STATUS_NO_MEMORY;
997 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, info->disp_info.disp_user_info);
998 if (NT_STATUS_IS_ERR(disp_ret))
999 return disp_ret;
1000 break;
1001 case 0x2:
1002 if (max_entries) {
1003 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1004 return NT_STATUS_NO_MEMORY;
1006 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, info->disp_info.disp_user_info);
1007 if (NT_STATUS_IS_ERR(disp_ret))
1008 return disp_ret;
1009 break;
1010 case 0x3:
1011 if (max_entries) {
1012 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1013 return NT_STATUS_NO_MEMORY;
1015 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1016 if (NT_STATUS_IS_ERR(disp_ret))
1017 return disp_ret;
1018 break;
1019 case 0x4:
1020 if (max_entries) {
1021 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1022 return NT_STATUS_NO_MEMORY;
1024 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1025 if (NT_STATUS_IS_ERR(disp_ret))
1026 return disp_ret;
1027 break;
1028 case 0x5:
1029 if (max_entries) {
1030 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1031 return NT_STATUS_NO_MEMORY;
1033 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1034 if (NT_STATUS_IS_ERR(disp_ret))
1035 return disp_ret;
1036 break;
1038 default:
1039 ctr->sam.info = NULL;
1040 return NT_STATUS_INVALID_INFO_CLASS;
1043 /* calculate the total size */
1044 total_data_size=num_account*struct_size;
1046 if (enum_context+max_entries < num_account)
1047 r_u->status = STATUS_MORE_ENTRIES;
1049 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1051 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1053 return r_u->status;
1057 /*******************************************************************
1058 samr_reply_query_aliasinfo
1059 ********************************************************************/
1061 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1063 fstring alias_desc = "Local Unix group";
1064 fstring alias="";
1065 enum SID_NAME_USE type;
1066 uint32 alias_rid;
1067 struct samr_info *info = NULL;
1069 r_u->status = NT_STATUS_OK;
1071 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1073 /* find the policy handle. open a policy on it. */
1074 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1075 return NT_STATUS_INVALID_HANDLE;
1077 alias_rid = get_lsa_policy_samr_rid(info);
1078 if(alias_rid == 0xffffffff)
1079 return NT_STATUS_NO_SUCH_ALIAS;
1081 if(!local_lookup_rid(alias_rid, alias, &type))
1082 return NT_STATUS_NO_SUCH_ALIAS;
1084 switch (q_u->switch_level) {
1085 case 3:
1086 r_u->ptr = 1;
1087 r_u->ctr.switch_value1 = 3;
1088 init_samr_alias_info3(&r_u->ctr.alias.info3, alias_desc);
1089 break;
1090 default:
1091 return NT_STATUS_INVALID_INFO_CLASS;
1094 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1096 return r_u->status;
1099 #if 0
1100 /*******************************************************************
1101 samr_reply_lookup_ids
1102 ********************************************************************/
1104 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1106 uint32 rid[MAX_SAM_ENTRIES];
1107 int num_rids = q_u->num_sids1;
1109 r_u->status = NT_STATUS_OK;
1111 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1113 if (num_rids > MAX_SAM_ENTRIES) {
1114 num_rids = MAX_SAM_ENTRIES;
1115 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1118 #if 0
1119 int i;
1120 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1122 for (i = 0; i < num_rids && status == 0; i++)
1124 struct sam_passwd *sam_pass;
1125 fstring user_name;
1128 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1129 q_u->uni_user_name[i].uni_str_len));
1131 /* find the user account */
1132 become_root();
1133 sam_pass = get_smb21pwd_entry(user_name, 0);
1134 unbecome_root();
1136 if (sam_pass == NULL)
1138 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1139 rid[i] = 0;
1141 else
1143 rid[i] = sam_pass->user_rid;
1146 #endif
1148 num_rids = 1;
1149 rid[0] = BUILTIN_ALIAS_RID_USERS;
1151 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1153 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1155 return r_u->status;
1157 #endif
1159 /*******************************************************************
1160 _samr_lookup_names
1161 ********************************************************************/
1163 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1165 uint32 rid[MAX_SAM_ENTRIES];
1166 uint32 local_rid;
1167 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1168 enum SID_NAME_USE local_type;
1169 int i;
1170 int num_rids = q_u->num_names2;
1171 DOM_SID pol_sid;
1172 fstring sid_str;
1174 r_u->status = NT_STATUS_OK;
1176 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1178 ZERO_ARRAY(rid);
1179 ZERO_ARRAY(type);
1181 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
1182 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1183 return r_u->status;
1186 if (num_rids > MAX_SAM_ENTRIES) {
1187 num_rids = MAX_SAM_ENTRIES;
1188 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1191 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1193 for (i = 0; i < num_rids; i++) {
1194 fstring name;
1195 DOM_SID sid;
1197 r_u->status = NT_STATUS_NONE_MAPPED;
1199 rid [i] = 0xffffffff;
1200 type[i] = SID_NAME_UNKNOWN;
1202 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer, q_u->uni_name[i].uni_str_len));
1205 * we are only looking for a name
1206 * the SID we get back can be outside
1207 * the scope of the pol_sid
1209 * in clear: it prevents to reply to domain\group: yes
1210 * when only builtin\group exists.
1212 * a cleaner code is to add the sid of the domain we're looking in
1213 * to the local_lookup_name function.
1216 if(local_lookup_name(global_myname, name, &sid, &local_type)) {
1217 sid_split_rid(&sid, &local_rid);
1219 if (sid_equal(&sid, &pol_sid)) {
1220 rid[i]=local_rid;
1221 type[i]=local_type;
1222 r_u->status = NT_STATUS_OK;
1227 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1229 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1231 return r_u->status;
1234 /*******************************************************************
1235 _samr_chgpasswd_user
1236 ********************************************************************/
1238 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1240 fstring user_name;
1241 fstring wks;
1243 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1245 r_u->status = NT_STATUS_OK;
1247 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1248 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1250 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1253 * Pass the user through the NT -> unix user mapping
1254 * function.
1257 (void)map_username(user_name);
1260 * Do any UNIX username case mangling.
1262 (void)Get_Pwnam( user_name, True);
1264 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1265 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1266 r_u->status = NT_STATUS_WRONG_PASSWORD;
1268 init_samr_r_chgpasswd_user(r_u, r_u->status);
1270 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1272 return r_u->status;
1275 /*******************************************************************
1276 makes a SAMR_R_LOOKUP_RIDS structure.
1277 ********************************************************************/
1279 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1280 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1282 uint32 i;
1283 UNIHDR *hdr_name = NULL;
1284 UNISTR2 *uni_name = NULL;
1286 *pp_uni_name = NULL;
1287 *pp_hdr_name = NULL;
1289 if (num_names != 0) {
1290 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1291 if (hdr_name == NULL)
1292 return False;
1294 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1295 if (uni_name == NULL)
1296 return False;
1299 for (i = 0; i < num_names; i++) {
1300 int len = names[i] != NULL ? strlen(names[i]) : 0;
1301 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1302 init_uni_hdr(&hdr_name[i], len);
1303 init_unistr2(&uni_name[i], names[i], len);
1306 *pp_uni_name = uni_name;
1307 *pp_hdr_name = hdr_name;
1309 return True;
1312 /*******************************************************************
1313 _samr_lookup_rids
1314 ********************************************************************/
1316 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1318 fstring group_names[MAX_SAM_ENTRIES];
1319 uint32 *group_attrs = NULL;
1320 UNIHDR *hdr_name = NULL;
1321 UNISTR2 *uni_name = NULL;
1322 DOM_SID pol_sid;
1323 int num_rids = q_u->num_rids1;
1324 int i;
1326 r_u->status = NT_STATUS_OK;
1328 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1330 /* find the policy handle. open a policy on it. */
1331 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
1332 return NT_STATUS_INVALID_HANDLE;
1334 if (num_rids > MAX_SAM_ENTRIES) {
1335 num_rids = MAX_SAM_ENTRIES;
1336 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1339 if (num_rids) {
1340 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1341 return NT_STATUS_NO_MEMORY;
1344 r_u->status = NT_STATUS_NONE_MAPPED;
1346 for (i = 0; i < num_rids; i++) {
1347 fstring tmpname;
1348 fstring domname;
1349 DOM_SID sid;
1350 enum SID_NAME_USE type;
1352 group_attrs[i] = SID_NAME_UNKNOWN;
1353 *group_names[i] = '\0';
1355 if (sid_equal(&pol_sid, &global_sam_sid)) {
1356 sid_copy(&sid, &pol_sid);
1357 sid_append_rid(&sid, q_u->rid[i]);
1359 if (lookup_sid(&sid, domname, tmpname, &type)) {
1360 r_u->status = NT_STATUS_OK;
1361 group_attrs[i] = (uint32)type;
1362 fstrcpy(group_names[i],tmpname);
1367 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1368 return NT_STATUS_NO_MEMORY;
1370 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1372 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1374 return r_u->status;
1377 /*******************************************************************
1378 _api_samr_open_user. Safe - gives out no passwd info.
1379 ********************************************************************/
1381 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1383 SAM_ACCOUNT *sampass=NULL;
1384 DOM_SID sid;
1385 POLICY_HND domain_pol = q_u->domain_pol;
1386 uint32 user_rid = q_u->user_rid;
1387 POLICY_HND *user_pol = &r_u->user_pol;
1388 struct samr_info *info = NULL;
1389 BOOL ret;
1391 r_u->status = NT_STATUS_OK;
1393 /* find the domain policy handle. */
1394 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1395 return NT_STATUS_INVALID_HANDLE;
1397 pdb_init_sam(&sampass);
1399 become_root();
1400 ret=pdb_getsampwrid(sampass, user_rid);
1401 unbecome_root();
1403 /* check that the RID exists in our domain. */
1404 if (ret == False) {
1405 pdb_free_sam(sampass);
1406 return NT_STATUS_NO_SUCH_USER;
1409 samr_clear_sam_passwd(sampass);
1410 pdb_free_sam(sampass);
1412 /* Get the domain SID stored in the domain policy */
1413 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1414 return NT_STATUS_INVALID_HANDLE;
1416 /* append the user's RID to it */
1417 if(!sid_append_rid(&sid, user_rid))
1418 return NT_STATUS_NO_SUCH_USER;
1420 /* associate the user's SID with the new handle. */
1421 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1422 return NT_STATUS_NO_MEMORY;
1424 /* get a (unique) handle. open a policy on it. */
1425 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1426 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1428 return r_u->status;
1431 /*************************************************************************
1432 get_user_info_10. Safe. Only gives out acb bits.
1433 *************************************************************************/
1435 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1437 SAM_ACCOUNT *smbpass=NULL;
1438 BOOL ret;
1440 if (!pdb_rid_is_user(user_rid)) {
1441 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1442 return False;
1445 pdb_init_sam(&smbpass);
1447 become_root();
1448 ret = pdb_getsampwrid(smbpass, user_rid);
1449 unbecome_root();
1451 if (ret==False) {
1452 DEBUG(4,("User 0x%x not found\n", user_rid));
1453 pdb_free_sam(smbpass);
1454 return False;
1457 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1459 ZERO_STRUCTP(id10);
1460 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1462 samr_clear_sam_passwd(smbpass);
1463 pdb_free_sam(smbpass);
1465 return True;
1468 /*************************************************************************
1469 get_user_info_12. OK - this is the killer as it gives out password info.
1470 Ensure that this is only allowed on an encrypted connection with a root
1471 user. JRA.
1472 *************************************************************************/
1474 static NTSTATUS get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
1476 SAM_ACCOUNT *smbpass=NULL;
1477 BOOL ret;
1479 if (!p->ntlmssp_auth_validated)
1480 return NT_STATUS_ACCESS_DENIED;
1482 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1483 return NT_STATUS_ACCESS_DENIED;
1486 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1488 pdb_init_sam(&smbpass);
1490 ret = pdb_getsampwrid(smbpass, user_rid);
1492 if (ret == False) {
1493 DEBUG(4, ("User 0x%x not found\n", user_rid));
1494 pdb_free_sam(smbpass);
1495 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1498 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1500 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1501 pdb_free_sam(smbpass);
1502 return NT_STATUS_ACCOUNT_DISABLED;
1505 ZERO_STRUCTP(id12);
1506 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1508 pdb_free_sam(smbpass);
1510 return NT_STATUS_OK;
1513 #if 1 /* JRA - re-enabled... JERRY - why was this removed ? */
1514 /*************************************************************************
1515 get_user_info_20
1516 *************************************************************************/
1518 static BOOL get_user_info_20(SAM_USER_INFO_20 *id20, uint32 user_rid)
1520 SAM_ACCOUNT *sampass=NULL;
1521 BOOL ret;
1523 if (!pdb_rid_is_user(user_rid)) {
1524 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1525 return False;
1528 pdb_init_sam(&sampass);
1530 become_root();
1531 ret = pdb_getsampwrid(sampass, user_rid);
1532 unbecome_root();
1534 if (ret == False) {
1535 DEBUG(4,("User 0x%x not found\n", user_rid));
1536 pdb_free_sam(sampass);
1537 return False;
1540 samr_clear_sam_passwd(sampass);
1542 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1544 ZERO_STRUCTP(id20);
1545 init_sam_user_info20A(id20, sampass);
1547 pdb_free_sam(sampass);
1549 return True;
1551 #endif
1553 /*************************************************************************
1554 get_user_info_21
1555 *************************************************************************/
1557 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1559 SAM_ACCOUNT *sampass=NULL;
1560 BOOL ret;
1562 if (!pdb_rid_is_user(user_rid)) {
1563 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1564 return False;
1567 pdb_init_sam(&sampass);
1569 become_root();
1570 ret = pdb_getsampwrid(sampass, user_rid);
1571 unbecome_root();
1573 if (ret == False) {
1574 DEBUG(4,("User 0x%x not found\n", user_rid));
1575 pdb_free_sam(sampass);
1576 return False;
1579 samr_clear_sam_passwd(sampass);
1581 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1583 ZERO_STRUCTP(id21);
1584 init_sam_user_info21A(id21, sampass);
1586 pdb_free_sam(sampass);
1588 return True;
1591 /*******************************************************************
1592 _samr_query_userinfo
1593 ********************************************************************/
1595 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1597 SAM_USERINFO_CTR *ctr;
1598 uint32 rid = 0;
1599 struct samr_info *info = NULL;
1601 r_u->status=NT_STATUS_OK;
1603 /* search for the handle */
1604 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1605 return NT_STATUS_INVALID_HANDLE;
1607 /* find the user's rid */
1608 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1609 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1611 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
1613 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1614 if (!ctr)
1615 return NT_STATUS_NO_MEMORY;
1617 ZERO_STRUCTP(ctr);
1619 /* ok! user info levels (lots: see MSDEV help), off we go... */
1620 ctr->switch_value = q_u->switch_value;
1622 switch (q_u->switch_value) {
1623 case 0x10:
1624 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1625 if (ctr->info.id10 == NULL)
1626 return NT_STATUS_NO_MEMORY;
1628 if (!get_user_info_10(ctr->info.id10, rid))
1629 return NT_STATUS_NO_SUCH_USER;
1630 break;
1632 #if 0
1633 /* whoops - got this wrong. i think. or don't understand what's happening. */
1634 case 0x11:
1636 NTTIME expire;
1637 info = (void *)&id11;
1639 expire.low = 0xffffffff;
1640 expire.high = 0x7fffffff;
1642 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1643 sizeof
1644 (*ctr->
1645 info.
1646 id11));
1647 init_sam_user_info11(ctr->info.id11, &expire,
1648 "BROOKFIELDS$", /* name */
1649 0x03ef, /* user rid */
1650 0x201, /* group rid */
1651 0x0080); /* acb info */
1653 break;
1655 #endif
1657 case 0x12:
1658 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1659 if (ctr->info.id12 == NULL)
1660 return NT_STATUS_NO_MEMORY;
1662 if (NT_STATUS_IS_ERR(r_u->status = get_user_info_12(p, ctr->info.id12, rid)))
1663 return r_u->status;
1664 break;
1666 case 20:
1667 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1668 if (ctr->info.id20 == NULL)
1669 return NT_STATUS_NO_MEMORY;
1670 if (!get_user_info_20(ctr->info.id20, rid))
1671 return NT_STATUS_NO_SUCH_USER;
1672 break;
1674 case 21:
1675 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1676 if (ctr->info.id21 == NULL)
1677 return NT_STATUS_NO_MEMORY;
1678 if (!get_user_info_21(ctr->info.id21, rid))
1679 return NT_STATUS_NO_SUCH_USER;
1680 break;
1682 default:
1683 return NT_STATUS_INVALID_INFO_CLASS;
1686 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1688 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1690 return r_u->status;
1693 /*******************************************************************
1694 samr_reply_query_usergroups
1695 ********************************************************************/
1697 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1699 SAM_ACCOUNT *sam_pass=NULL;
1700 DOM_GID *gids = NULL;
1701 int num_groups = 0;
1702 pstring groups;
1703 uint32 rid;
1704 struct samr_info *info = NULL;
1705 BOOL ret;
1707 r_u->status = NT_STATUS_OK;
1709 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1711 /* find the policy handle. open a policy on it. */
1712 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1713 return NT_STATUS_INVALID_HANDLE;
1715 /* find the user's rid */
1716 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1717 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1719 pdb_init_sam(&sam_pass);
1721 become_root();
1722 ret = pdb_getsampwrid(sam_pass, rid);
1723 unbecome_root();
1725 if (ret == False) {
1726 samr_clear_sam_passwd(sam_pass);
1727 pdb_free_sam(sam_pass);
1728 return NT_STATUS_NO_SUCH_USER;
1731 get_domain_user_groups(groups, pdb_get_username(sam_pass));
1732 gids = NULL;
1733 num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
1735 /* construct the response. lkclXXXX: gids are not copied! */
1736 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1738 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1740 samr_clear_sam_passwd(sam_pass);
1741 pdb_free_sam(sam_pass);
1743 return r_u->status;
1746 /*******************************************************************
1747 _samr_query_dom_info
1748 ********************************************************************/
1750 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1752 struct samr_info *info = NULL;
1753 SAM_UNK_CTR *ctr;
1754 uint32 min_pass_len,pass_hist,flag;
1755 time_t u_expire, u_min_age;
1756 NTTIME nt_expire, nt_min_age;
1758 time_t u_lock_duration, u_reset_time;
1759 NTTIME nt_lock_duration, nt_reset_time;
1760 uint32 lockout;
1762 time_t u_logout;
1763 NTTIME nt_logout;
1765 uint32 num_users=0, num_groups=0, num_aliases=0;
1767 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
1768 return NT_STATUS_NO_MEMORY;
1770 ZERO_STRUCTP(ctr);
1772 r_u->status = NT_STATUS_OK;
1774 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1776 /* find the policy handle. open a policy on it. */
1777 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1778 return NT_STATUS_INVALID_HANDLE;
1780 switch (q_u->switch_value) {
1781 case 0x01:
1782 /* Use defaults until we merge with HEAD db. JRA */
1783 min_pass_len = MINPASSWDLENGTH; /* 5 chars minimum */
1784 pass_hist = 0; /* don't keep any old password */
1785 flag = 0; /* don't force user to logon */
1786 u_expire = MAX_PASSWORD_AGE; /* 21 days */
1787 u_min_age = 0; /* 0 days */
1789 unix_to_nt_time_abs(&nt_expire, u_expire);
1790 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1792 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
1793 flag, nt_expire, nt_min_age);
1794 break;
1795 case 0x02:
1796 become_root();
1797 r_u->status=load_sampwd_entries(info, ACB_NORMAL);
1798 unbecome_root();
1799 if (NT_STATUS_IS_ERR(r_u->status)) {
1800 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1801 return r_u->status;
1803 num_users=info->disp_info.num_user_account;
1804 free_samr_db(info);
1806 r_u->status=load_group_domain_entries(info, &global_sam_sid);
1807 if (NT_STATUS_IS_ERR(r_u->status)) {
1808 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
1809 return r_u->status;
1811 num_groups=info->disp_info.num_group_account;
1812 free_samr_db(info);
1814 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1815 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL),
1816 num_users, num_groups, num_aliases);
1817 break;
1818 case 0x03:
1819 /* Use defaults until we merge with HEAD db. JRA */
1820 u_logout = -1; /* don't force logout */
1821 unix_to_nt_time_abs(&nt_logout, u_logout);
1822 init_unk_info3(&ctr->info.inf3, nt_logout);
1823 break;
1824 case 0x05:
1825 init_unk_info5(&ctr->info.inf5, global_myname);
1826 break;
1827 case 0x06:
1828 init_unk_info6(&ctr->info.inf6);
1829 break;
1830 case 0x07:
1831 init_unk_info7(&ctr->info.inf7);
1832 break;
1833 case 0x0c:
1834 /* Use defaults until we merge with HEAD db. JRA */
1835 u_lock_duration = 0; /* lockout for 0 minutes */
1836 u_reset_time = 0; /* reset immediatly */
1837 lockout = 0; /* don't lockout */
1839 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
1840 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
1842 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
1843 break;
1844 default:
1845 return NT_STATUS_INVALID_INFO_CLASS;
1848 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
1850 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1852 return r_u->status;
1855 /*******************************************************************
1856 _api_samr_create_user
1857 Create an account, can be either a normal user or a machine.
1858 This funcion will need to be updated for bdc/domain trusts.
1859 ********************************************************************/
1861 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
1863 SAM_ACCOUNT *sam_pass=NULL;
1864 fstring mach_acct;
1865 pstring err_str;
1866 pstring msg_str;
1867 int local_flags=0;
1868 DOM_SID sid;
1869 pstring add_script;
1870 POLICY_HND dom_pol = q_u->domain_pol;
1871 UNISTR2 user_account = q_u->uni_name;
1872 uint16 acb_info = q_u->acb_info;
1873 POLICY_HND *user_pol = &r_u->user_pol;
1874 struct samr_info *info = NULL;
1875 BOOL ret;
1877 /* find the policy handle. open a policy on it. */
1878 if (!find_policy_by_hnd(p, &dom_pol, NULL))
1879 return NT_STATUS_INVALID_HANDLE;
1881 /* find the machine account: tell the caller if it exists.
1882 lkclXXXX i have *no* idea if this is a problem or not
1883 or even if you are supposed to construct a different
1884 reply if the account already exists...
1887 fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
1888 strlower(mach_acct);
1890 pdb_init_sam(&sam_pass);
1892 become_root();
1893 ret = pdb_getsampwnam(sam_pass, mach_acct);
1894 unbecome_root();
1895 if (ret == True) {
1896 /* machine account exists: say so */
1897 pdb_free_sam(sam_pass);
1898 return NT_STATUS_USER_EXISTS;
1901 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1902 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1905 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1906 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1907 * that only people with write access to the smbpasswd file will be able
1908 * to create a user. JRA.
1912 * add the user in the /etc/passwd file or the unix authority system.
1913 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1914 * a) local_password_change() checks for us if the /etc/passwd account really exists
1915 * b) smb_create_user() would return an error if the account already exists
1916 * and as it could return an error also if it can't create the account, it would be tricky.
1918 * So we go the easy way, only check after if the account exists.
1919 * JFM (2/3/2001), to clear any possible bad understanding (-:
1922 pstrcpy(add_script, lp_adduser_script());
1924 if(*add_script)
1925 smb_create_user(mach_acct, NULL);
1927 /* add the user in the smbpasswd file or the Samba authority database */
1928 if (!local_password_change(mach_acct, local_flags, NULL, err_str, sizeof(err_str), msg_str, sizeof(msg_str))) {
1929 DEBUG(0, ("%s\n", err_str));
1930 pdb_free_sam(sam_pass);
1931 return NT_STATUS_ACCESS_DENIED;
1934 become_root();
1935 ret = pdb_getsampwnam(sam_pass, mach_acct);
1936 unbecome_root();
1937 if (ret == False) {
1938 /* account doesn't exist: say so */
1939 pdb_free_sam(sam_pass);
1940 return NT_STATUS_ACCESS_DENIED;
1943 /* Get the domain SID stored in the domain policy */
1944 if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
1945 pdb_free_sam(sam_pass);
1946 return NT_STATUS_INVALID_HANDLE;
1949 /* append the user's RID to it */
1950 if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
1951 pdb_free_sam(sam_pass);
1952 return NT_STATUS_NO_SUCH_USER;
1955 /* associate the user's SID with the new handle. */
1957 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
1958 pdb_free_sam(sam_pass);
1959 return NT_STATUS_NO_MEMORY;
1962 /* get a (unique) handle. open a policy on it. */
1963 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
1964 pdb_free_sam(sam_pass);
1965 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1968 r_u->user_rid=sam_pass->user_rid;
1969 r_u->unknown_0 = 0x000703ff;
1971 pdb_free_sam(sam_pass);
1973 return NT_STATUS_OK;
1976 /*******************************************************************
1977 samr_reply_connect_anon
1978 ********************************************************************/
1980 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
1982 struct samr_info *info = NULL;
1984 /* set up the SAMR connect_anon response */
1986 r_u->status = NT_STATUS_OK;
1988 /* associate the user's SID with the new handle. */
1989 if ((info = get_samr_info_by_sid(NULL)) == NULL)
1990 return NT_STATUS_NO_MEMORY;
1992 info->status = q_u->unknown_0;
1994 /* get a (unique) handle. open a policy on it. */
1995 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
1996 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1998 return r_u->status;
2001 /*******************************************************************
2002 samr_reply_connect
2003 ********************************************************************/
2005 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2007 struct samr_info *info = NULL;
2009 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2011 r_u->status = NT_STATUS_OK;
2013 /* associate the user's SID with the new handle. */
2014 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2015 return NT_STATUS_NO_MEMORY;
2017 info->status = q_u->access_mask;
2019 /* get a (unique) handle. open a policy on it. */
2020 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2021 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2023 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2025 return r_u->status;
2028 /**********************************************************************
2029 api_samr_lookup_domain
2030 **********************************************************************/
2032 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2034 fstring domain_name;
2035 DOM_SID sid;
2037 r_u->status = NT_STATUS_OK;
2039 if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
2040 return NT_STATUS_INVALID_HANDLE;
2042 fstrcpy(domain_name, dos_unistrn2( q_u->uni_domain.buffer, q_u->uni_domain.uni_str_len));
2044 ZERO_STRUCT(sid);
2046 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2047 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2050 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2052 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2054 return r_u->status;
2057 /******************************************************************
2058 makes a SAMR_R_ENUM_DOMAINS structure.
2059 ********************************************************************/
2061 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2062 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2064 uint32 i;
2065 SAM_ENTRY *sam;
2066 UNISTR2 *uni_name;
2068 DEBUG(5, ("make_enum_domains\n"));
2070 *pp_sam = NULL;
2071 *pp_uni_name = NULL;
2073 if (num_sam_entries == 0)
2074 return True;
2076 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2077 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2079 if (sam == NULL || uni_name == NULL)
2080 return False;
2082 for (i = 0; i < num_sam_entries; i++) {
2083 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2085 init_sam_entry(&sam[i], len, 0);
2086 init_unistr2(&uni_name[i], doms[i], len);
2089 *pp_sam = sam;
2090 *pp_uni_name = uni_name;
2092 return True;
2095 /**********************************************************************
2096 api_samr_enum_domains
2097 **********************************************************************/
2099 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2101 uint32 num_entries = 2;
2102 fstring dom[2];
2103 char *name;
2105 r_u->status = NT_STATUS_OK;
2107 switch (lp_server_role()) {
2108 case ROLE_DOMAIN_PDC:
2109 case ROLE_DOMAIN_BDC:
2110 name = global_myworkgroup;
2111 break;
2112 default:
2113 name = global_myname;
2116 fstrcpy(dom[0],name);
2117 strupper(dom[0]);
2118 fstrcpy(dom[1],"Builtin");
2120 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2121 return NT_STATUS_NO_MEMORY;
2123 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2125 return r_u->status;
2128 /*******************************************************************
2129 api_samr_open_alias
2130 ********************************************************************/
2132 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2134 DOM_SID sid;
2135 POLICY_HND domain_pol = q_u->dom_pol;
2136 uint32 alias_rid = q_u->rid_alias;
2137 POLICY_HND *alias_pol = &r_u->pol;
2138 struct samr_info *info = NULL;
2140 r_u->status = NT_STATUS_OK;
2142 /* get the domain policy. */
2143 if (!find_policy_by_hnd(p, &domain_pol, NULL))
2144 return NT_STATUS_INVALID_HANDLE;
2146 /* Get the domain SID stored in the domain policy */
2147 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
2148 return NT_STATUS_INVALID_HANDLE;
2150 /* append the alias' RID to it */
2151 if(!sid_append_rid(&sid, alias_rid))
2152 return NT_STATUS_NO_SUCH_USER;
2155 * we should check if the rid really exist !!!
2156 * JFM.
2159 /* associate the user's SID with the new handle. */
2160 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2161 return NT_STATUS_NO_MEMORY;
2163 /* get a (unique) handle. open a policy on it. */
2164 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2165 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2167 return r_u->status;
2170 /*******************************************************************
2171 set_user_info_10
2172 ********************************************************************/
2174 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2176 SAM_ACCOUNT *pwd =NULL;
2177 BOOL ret;
2179 pdb_init_sam(&pwd);
2181 ret = pdb_getsampwrid(pwd, rid);
2183 if(ret==False) {
2184 pdb_free_sam(pwd);
2185 return False;
2188 if (id10 == NULL) {
2189 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2190 pdb_free_sam(pwd);
2191 return False;
2194 if (!pdb_set_acct_ctrl(pwd, id10->acb_info)) {
2195 pdb_free_sam(pwd);
2196 return False;
2199 if(!pdb_update_sam_account(pwd, True)) {
2200 pdb_free_sam(pwd);
2201 return False;
2204 pdb_free_sam(pwd);
2206 return True;
2209 /*******************************************************************
2210 set_user_info_12
2211 ********************************************************************/
2213 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2215 SAM_ACCOUNT *pwd = NULL;
2217 pdb_init_sam(&pwd);
2219 if(!pdb_getsampwrid(pwd, rid)) {
2220 pdb_free_sam(pwd);
2221 return False;
2224 if (id12 == NULL) {
2225 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2226 pdb_free_sam(pwd);
2227 return False;
2230 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd)) {
2231 pdb_free_sam(pwd);
2232 return False;
2234 if (!pdb_set_nt_passwd(pwd, id12->nt_pwd)) {
2235 pdb_free_sam(pwd);
2236 return False;
2239 if(!pdb_update_sam_account(pwd, True)) {
2240 pdb_free_sam(pwd);
2241 return False;
2244 pdb_free_sam(pwd);
2245 return True;
2248 /*******************************************************************
2249 set_user_info_21
2250 ********************************************************************/
2252 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
2254 SAM_ACCOUNT *pwd = NULL;
2255 BOOL result = True;
2257 if (id21 == NULL) {
2258 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2259 return False;
2262 pdb_init_sam(&pwd);
2264 if (!pdb_getsampwrid(pwd, rid)) {
2265 result = False;
2266 goto done;
2269 /* we make a copy so that we can modify stuff */
2270 copy_id21_to_sam_passwd(pwd, id21);
2273 * The funny part about the previous two calls is
2274 * that pwd still has the password hashes from the
2275 * passdb entry. These have not been updated from
2276 * id21. I don't know if they need to be set. --jerry
2279 /* write the change out */
2280 if(!pdb_update_sam_account(pwd, True)) {
2281 result = False;
2282 goto done;
2285 done:
2286 pdb_free_sam(pwd);
2287 return result;
2290 /*******************************************************************
2291 set_user_info_23
2292 ********************************************************************/
2294 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2296 SAM_ACCOUNT *pwd = NULL;
2297 uint8 nt_hash[16];
2298 uint8 lm_hash[16];
2299 pstring buf;
2300 uint32 len;
2301 uint16 acct_ctrl;
2302 BOOL result = True;
2304 if (id23 == NULL) {
2305 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2306 return False;
2309 pdb_init_sam(&pwd);
2311 if (!pdb_getsampwrid(pwd, rid)) {
2312 result = False;
2313 goto done;
2316 acct_ctrl = pdb_get_acct_ctrl(pwd);
2318 copy_id23_to_sam_passwd(pwd, id23);
2320 if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len, nt_hash, lm_hash)) {
2321 result = False;
2322 goto done;
2325 if (!pdb_set_lanman_passwd (pwd, lm_hash)) {
2326 result = False;
2327 goto done;
2329 if (!pdb_set_nt_passwd(pwd, nt_hash)) {
2330 result = False;
2331 goto done;
2334 /* if it's a trust account, don't update /etc/passwd */
2335 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2336 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2337 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2338 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2339 } else {
2340 /* update the UNIX password */
2341 if (lp_unix_password_sync() )
2342 if(!chgpasswd(pdb_get_username(pwd), "", buf, True)) {
2343 result = False;
2344 goto done;
2348 memset(buf, 0, sizeof(buf));
2350 if(!pdb_update_sam_account(pwd, True)) {
2351 result = False;
2352 goto done;
2355 done:
2356 pdb_free_sam(pwd);
2357 return result;
2360 /*******************************************************************
2361 set_user_info_pw
2362 ********************************************************************/
2364 static BOOL set_user_info_pw(char *pass, uint32 rid)
2366 SAM_ACCOUNT *pwd = NULL;
2367 uchar nt_hash[16];
2368 uchar lm_hash[16];
2369 uint32 len;
2370 pstring buf;
2371 uint16 acct_ctrl;
2373 pdb_init_sam(&pwd);
2375 if (!pdb_getsampwrid(pwd, rid)) {
2376 pdb_free_sam(pwd);
2377 return False;
2380 acct_ctrl = pdb_get_acct_ctrl(pwd);
2382 memset(buf, 0, sizeof(buf));
2384 if (!decode_pw_buffer(pass, buf, 256, &len, nt_hash, lm_hash)) {
2385 pdb_free_sam(pwd);
2386 return False;
2389 if (!pdb_set_lanman_passwd (pwd, lm_hash)) {
2390 pdb_free_sam(pwd);
2391 return False;
2393 if (!pdb_set_nt_passwd(pwd, nt_hash)) {
2394 pdb_free_sam(pwd);
2395 return False;
2398 /* if it's a trust account, don't update /etc/passwd */
2399 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2400 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2401 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2402 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2403 } else {
2404 /* update the UNIX password */
2405 if (lp_unix_password_sync())
2406 if(!chgpasswd(pdb_get_username(pwd), "", buf, True)) {
2407 pdb_free_sam(pwd);
2408 return False;
2412 memset(buf, 0, sizeof(buf));
2414 DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
2416 /* update the SAMBA password */
2417 if(!pdb_update_sam_account(pwd, True)) {
2418 pdb_free_sam(pwd);
2419 return False;
2422 pdb_free_sam(pwd);
2424 return True;
2427 /*******************************************************************
2428 samr_reply_set_userinfo
2429 ********************************************************************/
2431 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2433 uint32 rid = 0x0;
2434 DOM_SID sid;
2435 struct current_user user;
2436 SAM_ACCOUNT *sam_pass=NULL;
2437 unsigned char sess_key[16];
2438 POLICY_HND *pol = &q_u->pol;
2439 uint16 switch_value = q_u->switch_value;
2440 SAM_USERINFO_CTR *ctr = q_u->ctr;
2441 BOOL ret;
2443 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2445 r_u->status = NT_STATUS_OK;
2447 if (p->ntlmssp_auth_validated) {
2448 memcpy(&user, &p->pipe_user, sizeof(user));
2449 } else {
2450 extern struct current_user current_user;
2451 memcpy(&user, &current_user, sizeof(user));
2454 /* find the policy handle. open a policy on it. */
2455 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2456 return NT_STATUS_INVALID_HANDLE;
2458 sid_split_rid(&sid, &rid);
2460 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2462 if (ctr == NULL) {
2463 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2464 return NT_STATUS_INVALID_INFO_CLASS;
2468 pdb_init_sam(&sam_pass);
2471 * We need the NT hash of the user who is changing the user's password.
2472 * This NT hash is used to generate a "user session key"
2473 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2476 become_root();
2477 ret = pdb_getsampwuid(sam_pass, user.uid);
2478 unbecome_root();
2479 if(ret == False) {
2480 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
2481 pdb_free_sam(sam_pass);
2482 return NT_STATUS_ACCESS_DENIED;
2485 memset(sess_key, '\0', 16);
2486 mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2488 pdb_free_sam(sam_pass);
2489 sam_pass = NULL;
2491 /* ok! user info levels (lots: see MSDEV help), off we go... */
2492 switch (switch_value) {
2493 case 0x12:
2494 if (!set_user_info_12(ctr->info.id12, rid))
2495 return NT_STATUS_ACCESS_DENIED;
2496 break;
2498 case 24:
2499 SamOEMhash(ctr->info.id24->pass, sess_key, 516);
2501 dump_data(100, (char *)ctr->info.id24->pass, 516);
2503 if (!set_user_info_pw((char *)ctr->info.id24->pass, rid))
2504 return NT_STATUS_ACCESS_DENIED;
2505 break;
2507 case 25:
2508 #if 0
2510 * Currently we don't really know how to unmarshall
2511 * the level 25 struct, and the password encryption
2512 * is different. This is a placeholder for when we
2513 * do understand it. In the meantime just return INVALID
2514 * info level and W2K SP2 drops down to level 23... JRA.
2517 SamOEMhash(ctr->info.id25->pass, sess_key, 532);
2519 dump_data(100, (char *)ctr->info.id25->pass, 532);
2521 if (!set_user_info_pw(ctr->info.id25->pass, rid))
2522 return NT_STATUS_ACCESS_DENIED;
2523 break;
2524 #endif
2525 return NT_STATUS_INVALID_INFO_CLASS;
2527 case 23:
2528 SamOEMhash(ctr->info.id23->pass, sess_key, 516);
2530 dump_data(100, (char *)ctr->info.id23->pass, 516);
2532 if (!set_user_info_23(ctr->info.id23, rid))
2533 return NT_STATUS_ACCESS_DENIED;
2534 break;
2536 default:
2537 return NT_STATUS_INVALID_INFO_CLASS;
2540 return r_u->status;
2543 /*******************************************************************
2544 samr_reply_set_userinfo2
2545 ********************************************************************/
2547 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2549 DOM_SID sid;
2550 uint32 rid = 0x0;
2551 SAM_USERINFO_CTR *ctr = q_u->ctr;
2552 POLICY_HND *pol = &q_u->pol;
2553 uint16 switch_value = q_u->switch_value;
2555 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2557 r_u->status = NT_STATUS_OK;
2559 /* find the policy handle. open a policy on it. */
2560 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2561 return NT_STATUS_INVALID_HANDLE;
2563 sid_split_rid(&sid, &rid);
2565 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2567 if (ctr == NULL) {
2568 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2569 return NT_STATUS_INVALID_INFO_CLASS;
2572 switch_value=ctr->switch_value;
2574 /* ok! user info levels (lots: see MSDEV help), off we go... */
2575 switch (switch_value) {
2576 case 21:
2577 if (!set_user_info_21(ctr->info.id21, rid))
2578 return NT_STATUS_ACCESS_DENIED;
2579 break;
2580 case 16:
2581 if (!set_user_info_10(ctr->info.id10, rid))
2582 return NT_STATUS_ACCESS_DENIED;
2583 break;
2584 case 18:
2585 /* Used by AS/U JRA. */
2586 if (!set_user_info_12(ctr->info.id12, rid))
2587 return NT_STATUS_ACCESS_DENIED;
2588 break;
2589 default:
2590 return NT_STATUS_INVALID_INFO_CLASS;
2593 return r_u->status;
2596 /*********************************************************************
2597 _samr_query_aliasmem
2598 *********************************************************************/
2600 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
2602 uint32 *rid=NULL;
2603 int num_rids;
2605 num_rids = 1;
2606 rid=(uint32 *)talloc_zero(p->mem_ctx, num_rids*sizeof(uint32));
2607 if (rid == NULL)
2608 return NT_STATUS_NO_MEMORY;
2610 /* until i see a real useraliases query, we fack one up */
2612 rid[0] = BUILTIN_ALIAS_RID_USERS;
2614 init_samr_r_query_useraliases(r_u, num_rids, rid, NT_STATUS_OK);
2616 return NT_STATUS_OK;
2620 /*********************************************************************
2621 _samr_query_aliasmem
2622 *********************************************************************/
2624 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
2626 DEBUG(0,("_samr_query_aliasmem: Not yet implemented.\n"));
2627 return NT_STATUS_NOT_IMPLEMENTED;
2630 /*********************************************************************
2631 _samr_query_groupmem
2632 *********************************************************************/
2634 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
2636 DEBUG(0,("_samr_query_groupmem: Not yet implemented.\n"));
2637 return NT_STATUS_NOT_IMPLEMENTED;
2640 /*********************************************************************
2641 _samr_add_aliasmem
2642 *********************************************************************/
2644 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
2646 DEBUG(0,("_samr_add_aliasmem: Not yet implemented.\n"));
2647 return NT_STATUS_NOT_IMPLEMENTED;
2650 /*********************************************************************
2651 _samr_del_aliasmem
2652 *********************************************************************/
2654 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
2656 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2657 return NT_STATUS_NOT_IMPLEMENTED;
2660 /*********************************************************************
2661 _samr_add_groupmem
2662 *********************************************************************/
2664 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
2666 DEBUG(0,("_samr_add_groupmem: Not yet implemented.\n"));
2667 return NT_STATUS_NOT_IMPLEMENTED;
2670 /*********************************************************************
2671 _samr_del_groupmem
2672 *********************************************************************/
2674 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
2676 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2677 return NT_STATUS_NOT_IMPLEMENTED;
2680 /*********************************************************************
2681 _samr_delete_dom_user
2682 *********************************************************************/
2684 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
2686 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2687 return NT_STATUS_NOT_IMPLEMENTED;
2690 /*********************************************************************
2691 _samr_delete_dom_group
2692 *********************************************************************/
2694 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
2696 DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
2697 return NT_STATUS_NOT_IMPLEMENTED;
2700 /*********************************************************************
2701 _samr_delete_dom_alias
2702 *********************************************************************/
2704 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
2706 DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
2707 return NT_STATUS_NOT_IMPLEMENTED;
2710 /*********************************************************************
2711 _samr_create_dom_group
2712 *********************************************************************/
2714 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
2716 DEBUG(0,("_samr_create_dom_group: Not yet implemented.\n"));
2717 return NT_STATUS_NOT_IMPLEMENTED;
2720 /*********************************************************************
2721 _samr_create_dom_alias
2722 *********************************************************************/
2724 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
2726 DEBUG(0,("_samr_create_dom_alias: Not yet implemented.\n"));
2727 return NT_STATUS_NOT_IMPLEMENTED;
2730 /*********************************************************************
2731 _samr_query_groupinfo
2732 *********************************************************************/
2734 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
2736 DEBUG(0,("_samr_query_groupinfo: Not yet implemented.\n"));
2737 return NT_STATUS_NOT_IMPLEMENTED;
2740 /*********************************************************************
2741 _samr_set_groupinfo
2742 *********************************************************************/
2744 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
2746 DEBUG(0,("_samr_set_groupinfo: Not yet implemented.\n"));
2747 return NT_STATUS_NOT_IMPLEMENTED;
2750 /*********************************************************************
2751 _samr_get_dom_pwinfo
2752 *********************************************************************/
2754 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
2756 /* Actually, returning zeros here works quite well :-). */
2757 return NT_STATUS_OK;
2760 /*********************************************************************
2761 _samr_open_group
2762 *********************************************************************/
2764 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
2766 DEBUG(0,("_samr_open_group: Not yet implemented.\n"));
2767 return NT_STATUS_NOT_IMPLEMENTED;
2770 /*********************************************************************
2771 _samr_unknown_2d
2772 *********************************************************************/
2774 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
2776 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
2777 return NT_STATUS_NOT_IMPLEMENTED;