fixed error check which caused domain logons to fail
[Samba.git] / source / rpc_server / srv_samr_nt.c
blob1f61919be966da2cab51d4e6a83254d35849a7f3
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.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * This is the implementation of the SAMR code.
30 #include "includes.h"
32 extern fstring global_myworkgroup;
33 extern pstring global_myname;
34 extern DOM_SID global_sam_sid;
35 extern DOM_SID global_sid_Builtin;
37 extern rid_name domain_group_rids[];
38 extern rid_name domain_alias_rids[];
39 extern rid_name builtin_alias_rids[];
41 struct samr_info {
42 /* for use by the \PIPE\samr policy */
43 DOM_SID sid;
44 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
47 /*******************************************************************
48 Function to free the per handle data.
49 ********************************************************************/
51 static void free_samr_info(void *ptr)
53 SAFE_FREE(ptr);
56 /*******************************************************************
57 Ensure password info is never given out. Paranioa... JRA.
58 ********************************************************************/
60 static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
62 int i;
64 if (!pass)
65 return;
67 for (i = 0; i < num_entries; i++) {
68 memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
69 memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
73 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
75 if (!sam_pass)
76 return;
78 if (sam_pass->lm_pw) memset(sam_pass->lm_pw, '\0', 16);
79 if (sam_pass->nt_pw) memset(sam_pass->nt_pw, '\0', 16);
82 /*******************************************************************
83 This next function should be replaced with something that
84 dynamically returns the correct user info..... JRA.
85 ********************************************************************/
87 static NTSTATUS get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
88 int *total_entries, int *num_entries,
89 int max_num_entries, uint16 acb_mask)
91 SAM_ACCOUNT *pwd = NULL;
92 BOOL not_finished = True;
94 (*num_entries) = 0;
95 (*total_entries) = 0;
97 if (pw_buf == NULL)
98 return NT_STATUS_NO_MEMORY;
100 pdb_init_sam(&pwd);
102 if (!pdb_setsampwent(False)) {
103 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
104 pdb_free_sam(pwd);
105 return NT_STATUS_ACCESS_DENIED;
108 while (((not_finished = pdb_getsampwent(pwd)) != False)
109 && (*num_entries) < max_num_entries)
111 int user_name_len;
113 if (start_idx > 0) {
114 /* skip the requested number of entries.
115 not very efficient, but hey... */
116 pdb_reset_sam(pwd);
117 start_idx--;
118 continue;
121 user_name_len = strlen(pdb_get_username(pwd))+1;
122 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
123 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
124 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
125 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
127 /* Now check if the NT compatible password is available. */
128 if (pdb_get_nt_passwd(pwd))
129 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
131 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
133 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
134 (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
136 if (acb_mask == 0 || (pwd->acct_ctrl & acb_mask)) {
137 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
138 (*num_entries)++;
139 } else
140 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
142 (*total_entries)++;
143 pdb_reset_sam(pwd);
146 pdb_endsampwent();
147 pdb_free_sam(pwd);
149 if (not_finished)
150 return STATUS_MORE_ENTRIES;
151 else
152 return NT_STATUS_OK;
155 static NTSTATUS jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
156 int *total_entries, uint32 *num_entries,
157 int max_num_entries, uint16 acb_mask)
159 SAM_ACCOUNT *pwd = NULL;
160 BOOL not_finished = True;
162 *num_entries = 0;
163 *total_entries = 0;
165 if (pw_buf == NULL)
166 return NT_STATUS_NO_MEMORY;
168 DEBUG(10,("jf_get_sampwd_entries: start index:%d, max entries:%d, mask:%d\n",
169 start_idx, max_num_entries, acb_mask));
171 if (!pdb_setsampwent(False)) {
172 DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
173 return NT_STATUS_ACCESS_DENIED;
176 pdb_init_sam(&pwd);
178 while (((not_finished = pdb_getsampwent(pwd)) != False) && (*num_entries) < max_num_entries) {
179 int user_name_len;
180 int full_name_len;
182 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
183 pdb_reset_sam(pwd);
184 continue;
187 if (start_idx > 0) {
188 /* skip the requested number of entries.
189 not very efficient, but hey...
191 start_idx--;
192 pdb_reset_sam(pwd);
193 continue;
196 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
198 user_name_len = strlen(pdb_get_username(pwd));
199 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
200 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
202 full_name_len = strlen(pdb_get_fullname(pwd));
203 init_unistr2(&pw_buf[(*num_entries)].uni_full_name, pdb_get_fullname(pwd), full_name_len);
204 init_uni_hdr(&pw_buf[(*num_entries)].hdr_full_name, full_name_len);
206 pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
207 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
209 /* Now check if the NT compatible password is available. */
210 if (pdb_get_nt_passwd(pwd))
211 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
213 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
215 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries),
216 pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
218 (*num_entries)++;
220 pdb_reset_sam(pwd);
223 pdb_endsampwent();
225 *total_entries = *num_entries;
227 pdb_free_sam(pwd);
229 if (not_finished)
230 return STATUS_MORE_ENTRIES;
231 else
232 return NT_STATUS_OK;
236 * These next two functions are not used. Tagged
237 * for deletion
240 #if 0
241 /*******************************************************************
242 This function uses the username map file and tries to map a UNIX
243 user name to an DOS name. (Sort of the reverse of the
244 map_username() function.) Since more than one DOS name can map
245 to the UNIX name, to reverse the mapping you have to specify
246 which corresponding DOS name you want; that's where the name_idx
247 parameter comes in. Returns the string requested or NULL if it
248 fails or can't complete the request for any reason. This doesn't
249 handle group names (starting with '@') or names starting with
250 '+' or '&'. If they are encountered, they are skipped.
251 ********************************************************************/
253 static char *unmap_unixname(char *unix_user_name, int name_idx)
255 char *mapfile = lp_username_map();
256 char **lines;
257 static pstring tok;
258 int i;
260 if (!*unix_user_name) return NULL;
261 if (!*mapfile) return NULL;
263 lines = file_lines_load(mapfile, NULL,False);
264 if (!lines) {
265 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
266 return NULL;
269 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
271 for (i=0; lines[i]; i++) {
272 char *unixname = lines[i];
273 char *dosname = strchr(unixname,'=');
275 if (!dosname)
276 continue;
278 *dosname++ = 0;
280 while (isspace(*unixname))
281 unixname++;
282 if ('!' == *unixname) {
283 unixname++;
284 while (*unixname && isspace(*unixname))
285 unixname++;
288 if (!*unixname || strchr("#;",*unixname))
289 continue;
291 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
292 continue;
294 /* We have matched the UNIX user name */
296 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
297 if (!strchr("@&+", *tok)) {
298 name_idx--;
299 if (name_idx < 0 ) {
300 break;
305 if (name_idx >= 0) {
306 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
307 file_lines_free(lines);
308 return NULL;
309 } else {
310 file_lines_free(lines);
311 return tok;
315 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
316 file_lines_free(lines);
317 return NULL;
320 /*******************************************************************
321 This function sets up a list of users taken from the list of
322 users that UNIX knows about, as well as all the user names that
323 Samba maps to a valid UNIX user name. (This should work with
324 /etc/passwd or NIS.)
325 ********************************************************************/
327 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
328 int start_idx,
329 int *total_entries, int *num_entries,
330 int max_num_entries,
331 uint16 acb_mask)
333 static struct passwd *pwd = NULL;
334 static uint32 pw_rid;
335 static BOOL orig_done = False;
336 static int current_idx = 0;
337 static int mapped_idx = 0;
338 char *sep;
340 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
342 (*num_entries) = 0;
343 (*total_entries) = 0;
345 /* Skip all this stuff if we're in appliance mode */
347 if (lp_hide_local_users()) goto done;
349 if (pw_buf == NULL) return False;
351 if (current_idx == 0) {
352 sys_setpwent();
355 /* These two cases are inefficient, but should be called very rarely */
356 /* they are the cases where the starting index isn't picking up */
357 /* where we left off last time. It is efficient when it starts over */
358 /* at zero though. */
359 if (start_idx > current_idx) {
360 /* We aren't far enough; advance to start_idx */
361 while (current_idx <= start_idx) {
362 char *unmap_name;
364 if(!orig_done) {
365 if ((pwd = sys_getpwent()) == NULL) break;
366 current_idx++;
367 orig_done = True;
370 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
371 (current_idx < start_idx)) {
372 current_idx++;
373 mapped_idx++;
376 if (unmap_name == NULL) {
377 orig_done = False;
378 mapped_idx = 0;
381 } else if (start_idx < current_idx) {
382 /* We are already too far; start over and advance to start_idx */
383 sys_endpwent();
384 sys_setpwent();
385 current_idx = 0;
386 mapped_idx = 0;
387 orig_done = False;
388 while (current_idx < start_idx) {
389 char *unmap_name;
391 if(!orig_done) {
392 if ((pwd = sys_getpwent()) == NULL) break;
393 current_idx++;
394 orig_done = True;
397 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
398 (current_idx < start_idx)) {
399 current_idx++;
400 mapped_idx++;
403 if (unmap_name == NULL) {
404 orig_done = False;
405 mapped_idx = 0;
410 sep = lp_winbind_separator();
412 /* now current_idx == start_idx */
413 while ((*num_entries) < max_num_entries) {
414 int user_name_len;
415 char *unmap_name;
417 /* This does the original UNIX user itself */
418 if(!orig_done) {
419 if ((pwd = sys_getpwent()) == NULL) break;
421 /* Don't enumerate winbind users as they are not local */
423 if (strchr(pwd->pw_name, *sep) != NULL) {
424 continue;
427 user_name_len = strlen(pwd->pw_name);
429 /* skip the trust account stored in the /etc/passwd file */
430 if (pwd->pw_name[user_name_len-1]=='$')
431 continue;
433 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
434 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
435 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pwd->pw_name, user_name_len);
436 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
437 pw_buf[(*num_entries)].user_rid = pw_rid;
438 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
440 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
442 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
444 (*num_entries)++;
445 (*total_entries)++;
446 current_idx++;
447 orig_done = True;
450 /* This does all the user names that map to the UNIX user */
451 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
452 (*num_entries < max_num_entries)) {
453 user_name_len = strlen(unmap_name);
454 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
455 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, unmap_name, user_name_len);
456 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
457 pw_buf[(*num_entries)].user_rid = pw_rid;
458 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
460 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
462 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
464 (*num_entries)++;
465 (*total_entries)++;
466 current_idx++;
467 mapped_idx++;
470 if (unmap_name == NULL) {
471 /* done with 'aliases', go on to next UNIX user */
472 orig_done = False;
473 mapped_idx = 0;
477 if (pwd == NULL) {
478 /* totally done, reset everything */
479 sys_endpwent();
480 current_idx = 0;
481 mapped_idx = 0;
484 done:
485 return (*num_entries) > 0;
487 #endif
489 /*******************************************************************
490 _samr_close_hnd
491 ********************************************************************/
493 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
495 r_u->status = NT_STATUS_OK;
497 /* close the policy handle */
498 if (!close_policy_hnd(p, &q_u->pol))
499 return NT_STATUS_OBJECT_NAME_INVALID;
501 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
503 return r_u->status;
506 /*******************************************************************
507 samr_reply_open_domain
508 ********************************************************************/
510 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
512 struct samr_info *info;
514 r_u->status = NT_STATUS_OK;
516 /* find the connection policy handle. */
517 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
518 return NT_STATUS_INVALID_HANDLE;
520 /* associate the domain SID with the (unique) handle. */
521 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
522 return NT_STATUS_NO_MEMORY;
524 ZERO_STRUCTP(info);
525 info->sid = q_u->dom_sid.sid;
527 /* get a (unique) handle. open a policy on it. */
528 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
529 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
531 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
533 return r_u->status;
536 static uint32 get_lsa_policy_samr_rid(struct samr_info *info)
538 if (!info) {
539 DEBUG(3,("Error getting policy\n"));
540 return 0xffffffff;
543 return info->sid.sub_auths[info->sid.num_auths-1];
546 /*******************************************************************
547 _samr_get_usrdom_pwinfo
548 ********************************************************************/
550 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
552 struct samr_info *info = NULL;
554 r_u->status = NT_STATUS_OK;
556 /* find the policy handle. open a policy on it. */
557 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info)) {
558 return NT_STATUS_INVALID_HANDLE;
561 /* find the user's rid */
562 if (get_lsa_policy_samr_rid(info) == 0xffffffff) {
563 return NT_STATUS_OBJECT_TYPE_MISMATCH;
566 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
568 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
570 return r_u->status;
573 /*******************************************************************
574 samr_make_usr_obj_sd
575 ********************************************************************/
577 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
579 extern DOM_SID global_sid_Builtin;
580 extern DOM_SID global_sid_World;
581 DOM_SID adm_sid;
582 DOM_SID act_sid;
584 SEC_ACE ace[4];
585 SEC_ACCESS mask;
587 SEC_ACL *psa = NULL;
588 SEC_DESC *psd = NULL;
589 size_t sd_size;
591 sid_copy(&adm_sid, &global_sid_Builtin);
592 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
594 sid_copy(&act_sid, &global_sid_Builtin);
595 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
597 init_sec_access(&mask, 0x2035b);
598 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
600 init_sec_access(&mask, 0xf07ff);
601 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
602 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
604 init_sec_access(&mask,0x20044);
605 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
607 if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
608 return NT_STATUS_NO_MEMORY;
610 if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
611 return NT_STATUS_NO_MEMORY;
613 if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
614 return NT_STATUS_NO_MEMORY;
616 return NT_STATUS_OK;
619 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
621 struct samr_info *info = NULL;
623 /* find the policy handle. open a policy on it. */
624 if (!find_policy_by_hnd(p, pol, (void **)&info))
625 return False;
627 if (!info)
628 return False;
630 *sid = info->sid;
631 return True;
634 /*******************************************************************
635 _samr_query_sec_obj
636 ********************************************************************/
638 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
640 DOM_SID pol_sid;
642 r_u->status = NT_STATUS_OK;
644 /* Get the SID. */
646 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
647 return NT_STATUS_INVALID_HANDLE;
649 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
651 if (NT_STATUS_IS_OK(r_u->status))
652 r_u->ptr = 1;
654 return r_u->status;
657 /*******************************************************************
658 makes a SAM_ENTRY / UNISTR2* structure from a user list.
659 ********************************************************************/
661 static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
662 uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
664 uint32 i;
665 SAM_ENTRY *sam;
666 UNISTR2 *uni_name;
668 *sam_pp = NULL;
669 *uni_name_pp = NULL;
671 if (num_sam_entries == 0)
672 return;
674 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
676 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
678 if (sam == NULL || uni_name == NULL) {
679 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
680 return;
683 for (i = 0; i < num_sam_entries; i++) {
684 int len = pass[i].uni_user_name.uni_str_len;
686 init_sam_entry(&sam[i], len, pass[i].user_rid);
687 copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
690 *sam_pp = sam;
691 *uni_name_pp = uni_name;
694 /*******************************************************************
695 samr_reply_enum_dom_users
696 ********************************************************************/
698 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
700 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
701 int num_entries = 0;
702 int total_entries = 0;
704 r_u->status = NT_STATUS_OK;
706 /* find the policy handle. open a policy on it. */
707 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
708 return NT_STATUS_INVALID_HANDLE;
710 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
712 become_root();
713 r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
714 MAX_SAM_ENTRIES, q_u->acb_mask);
715 unbecome_root();
717 if (NT_STATUS_IS_ERR(r_u->status))
718 return r_u->status;
720 samr_clear_passwd_fields(pass, num_entries);
723 * Note from JRA. total_entries is not being used here. Currently if there is a
724 * large user base then it looks like NT will enumerate until get_sampwd_entries
725 * returns False due to num_entries being zero. This will cause an access denied
726 * return. I don't think this is right and needs further investigation. Note that
727 * this is also the same in the TNG code (I don't think that has been tested with
728 * a very large user list as MAX_SAM_ENTRIES is set to 600).
730 * I also think that one of the 'num_entries' return parameters is probably
731 * the "max entries" parameter - but in the TNG code they're all currently set to the same
732 * value (again I think this is wrong).
735 make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
737 init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
739 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
741 return r_u->status;
744 /*******************************************************************
745 makes a SAM_ENTRY / UNISTR2* structure from a group list.
746 ********************************************************************/
748 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
749 uint32 num_sam_entries, DOMAIN_GRP *grp)
751 uint32 i;
752 SAM_ENTRY *sam;
753 UNISTR2 *uni_name;
755 *sam_pp = NULL;
756 *uni_name_pp = NULL;
758 if (num_sam_entries == 0)
759 return;
761 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
763 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
765 if (sam == NULL || uni_name == NULL) {
766 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
767 return;
770 for (i = 0; i < num_sam_entries; i++) {
772 * JRA. I think this should include the null. TNG does not.
774 int len = strlen(grp[i].name)+1;
776 init_sam_entry(&sam[i], len, grp[i].rid);
777 init_unistr2(&uni_name[i], grp[i].name, len);
780 *sam_pp = sam;
781 *uni_name_pp = uni_name;
784 /*******************************************************************
785 Get the group entries - similar to get_sampwd_entries().
786 ********************************************************************/
788 static NTSTATUS get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
789 uint32 *p_num_entries, uint32 max_entries)
791 fstring sid_str;
792 fstring sam_sid_str;
793 uint32 num_entries = 0;
795 sid_to_string(sid_str, sid);
796 sid_to_string(sam_sid_str, &global_sam_sid);
798 *p_num_entries = 0;
800 /* well-known aliases */
801 if (strequal(sid_str, "S-1-5-32")) {
802 char *alias_name;
803 while (!lp_hide_local_users() &&
804 num_entries < max_entries &&
805 ((alias_name = builtin_alias_rids[num_entries].name) != NULL)) {
807 fstrcpy(d_grp[num_entries].name, alias_name);
808 d_grp[num_entries].rid = builtin_alias_rids[num_entries].rid;
810 num_entries++;
812 } else if (strequal(sid_str, sam_sid_str) && !lp_hide_local_users()) {
813 fstring name;
814 char *sep;
815 struct sys_grent *glist;
816 struct sys_grent *grp;
818 sep = lp_winbind_separator();
820 /* local aliases */
821 /* we return the UNIX groups here. This seems to be the right */
822 /* thing to do, since NT member servers return their local */
823 /* groups in the same situation. */
825 /* use getgrent_list() to retrieve the list of groups to avoid
826 * problems with getgrent possible infinite loop by internal
827 * libc grent structures overwrites by called functions */
828 grp = glist = getgrent_list();
829 if (grp == NULL)
830 return NT_STATUS_NO_MEMORY;
832 for (;(num_entries < max_entries) && (grp != NULL); grp = grp->next) {
833 int i;
834 uint32 trid;
836 fstrcpy(name,grp->gr_name);
837 DEBUG(10,("get_group_alias_entries: got group %s\n", name ));
839 /* Don't return winbind groups as they are not local! */
841 if (strchr(name, *sep) != NULL) {
842 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", name ));
843 continue;
846 /* Don't return user private groups... */
847 if (Get_Pwnam(name, False) != 0) {
848 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", name ));
849 continue;
852 trid = pdb_gid_to_group_rid(grp->gr_gid);
853 for( i = 0; i < num_entries; i++)
854 if ( d_grp[i].rid == trid )
855 break;
857 if ( i < num_entries )
858 continue; /* rid was there, dup! */
860 /* JRA - added this for large group db enumeration... */
862 if (start_idx > 0) {
863 /* skip the requested number of entries.
864 not very efficient, but hey...
866 start_idx--;
867 continue;
870 fstrcpy(d_grp[num_entries].name, name);
871 d_grp[num_entries].rid = trid;
872 num_entries++;
875 grent_free(glist);
878 *p_num_entries = num_entries;
880 if (num_entries >= max_entries)
881 return STATUS_MORE_ENTRIES;
882 return NT_STATUS_OK;
885 /*******************************************************************
886 Get the group entries - similar to get_sampwd_entries().
887 ********************************************************************/
889 static NTSTATUS get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
890 uint32 *p_num_entries, uint32 max_entries)
892 fstring sid_str;
893 fstring sam_sid_str;
894 uint32 num_entries = 0;
895 fstring name="Domain Admins";
896 fstring comment="Just to make it work !";
898 sid_to_string(sid_str, sid);
899 sid_to_string(sam_sid_str, &global_sam_sid);
901 *p_num_entries = 0;
903 fstrcpy(d_grp[0].name, name);
904 fstrcpy(d_grp[0].comment, comment);
905 d_grp[0].rid = DOMAIN_GROUP_RID_ADMINS;
906 d_grp[0].attr=SID_NAME_DOM_GRP;
908 fstrcpy(d_grp[1].name, "Domain Users");
909 fstrcpy(d_grp[1].comment, "Just to make it work !");
910 d_grp[1].rid = DOMAIN_GROUP_RID_USERS;
911 d_grp[1].attr=SID_NAME_DOM_GRP;
913 num_entries = 2;
915 *p_num_entries = num_entries;
917 return NT_STATUS_OK;
920 /*******************************************************************
921 samr_reply_enum_dom_groups
922 Only reply with one group - domain admins. This must be fixed for
923 a real PDC. JRA.
924 ********************************************************************/
926 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
928 DOMAIN_GRP grp[2];
929 uint32 num_entries;
930 DOM_SID sid;
932 r_u->status = NT_STATUS_OK;
934 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
935 return NT_STATUS_INVALID_HANDLE;
937 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
939 get_group_domain_entries(grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
941 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
943 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
945 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
947 return r_u->status;
951 /*******************************************************************
952 samr_reply_enum_dom_aliases
953 ********************************************************************/
955 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
957 DOMAIN_GRP grp[MAX_SAM_ENTRIES];
958 uint32 num_entries = 0;
959 fstring sid_str;
960 DOM_SID sid;
962 r_u->status = NT_STATUS_OK;
964 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
965 return NT_STATUS_INVALID_HANDLE;
967 sid_to_string(sid_str, &sid);
968 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
970 r_u->status = get_group_alias_entries(grp, &sid, q_u->start_idx,
971 &num_entries, MAX_SAM_ENTRIES);
972 if (NT_STATUS_IS_ERR(r_u->status))
973 return r_u->status;
975 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
977 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
979 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
981 return r_u->status;
984 /*******************************************************************
985 samr_reply_query_dispinfo
986 ********************************************************************/
988 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
990 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
991 DOMAIN_GRP grps[MAX_SAM_ENTRIES];
992 uint16 acb_mask = ACB_NORMAL;
993 uint32 num_entries = 0;
994 int orig_num_entries = 0;
995 int total_entries = 0;
996 uint32 data_size = 0;
997 DOM_SID sid;
998 NTSTATUS disp_ret;
999 SAM_DISPINFO_CTR *ctr;
1001 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1003 r_u->status = NT_STATUS_OK;
1005 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
1006 return NT_STATUS_INVALID_HANDLE;
1008 /* decide how many entries to get depending on the max_entries
1009 and max_size passed by client */
1011 if(q_u->max_entries > MAX_SAM_ENTRIES)
1012 q_u->max_entries = MAX_SAM_ENTRIES;
1014 /* Get what we need from the password database */
1015 switch (q_u->switch_level) {
1016 case 0x2:
1017 acb_mask = ACB_WSTRUST;
1018 /* Fall through */
1019 case 0x1:
1020 case 0x4:
1021 become_root();
1022 #if 0
1023 r_u->status = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1024 MAX_SAM_ENTRIES, acb_mask);
1025 #endif
1026 #if 0
1028 * Which should we use here ? JRA.
1030 r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1031 MAX_SAM_ENTRIES, acb_mask);
1032 #endif
1033 #if 1
1034 r_u->status = jf_get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1035 MAX_SAM_ENTRIES, acb_mask);
1036 #endif
1037 unbecome_root();
1038 if (NT_STATUS_IS_ERR(r_u->status)) {
1039 DEBUG(5, ("get_sampwd_entries: failed\n"));
1040 return r_u->status;
1042 break;
1043 case 0x3:
1044 case 0x5:
1045 r_u->status = get_group_domain_entries(grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
1046 break;
1047 default:
1048 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1049 return NT_STATUS_INVALID_INFO_CLASS;
1052 orig_num_entries = num_entries;
1054 if (num_entries > q_u->max_entries)
1055 num_entries = q_u->max_entries;
1057 if (num_entries > MAX_SAM_ENTRIES) {
1058 num_entries = MAX_SAM_ENTRIES;
1059 DEBUG(5, ("limiting number of entries to %d\n", num_entries));
1062 /* Ensure password info is never given out here. PARANOIA... JRA */
1063 samr_clear_passwd_fields(pass, num_entries);
1065 data_size = q_u->max_size;
1067 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1068 return NT_STATUS_NO_MEMORY;
1070 ZERO_STRUCTP(ctr);
1072 /* Now create reply structure */
1073 switch (q_u->switch_level) {
1074 case 0x1:
1075 if (num_entries) {
1076 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_1))))
1077 return NT_STATUS_NO_MEMORY;
1079 disp_ret = init_sam_dispinfo_1(p->mem_ctx,ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass);
1080 if (NT_STATUS_IS_ERR(disp_ret))
1081 return disp_ret;
1082 break;
1083 case 0x2:
1084 if (num_entries) {
1085 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_2))))
1086 return NT_STATUS_NO_MEMORY;
1088 disp_ret = init_sam_dispinfo_2(p->mem_ctx,ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass);
1089 if (NT_STATUS_IS_ERR(disp_ret))
1090 return disp_ret;
1091 break;
1092 case 0x3:
1093 if (num_entries) {
1094 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_3))))
1095 return NT_STATUS_NO_MEMORY;
1097 disp_ret = init_sam_dispinfo_3(p->mem_ctx,ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps);
1098 if (NT_STATUS_IS_ERR(disp_ret))
1099 return disp_ret;
1100 break;
1101 case 0x4:
1102 if (num_entries) {
1103 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_4))))
1104 return NT_STATUS_NO_MEMORY;
1106 disp_ret = init_sam_dispinfo_4(p->mem_ctx,ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass);
1107 if (NT_STATUS_IS_ERR(disp_ret))
1108 return disp_ret;
1109 break;
1110 case 0x5:
1111 if (num_entries) {
1112 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_5))))
1113 return NT_STATUS_NO_MEMORY;
1115 disp_ret = init_sam_dispinfo_5(p->mem_ctx,ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps);
1116 if (NT_STATUS_IS_ERR(disp_ret))
1117 return disp_ret;
1118 break;
1119 default:
1120 ctr->sam.info = NULL;
1121 return NT_STATUS_INVALID_INFO_CLASS;
1124 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1126 if (num_entries < orig_num_entries)
1127 return STATUS_MORE_ENTRIES;
1129 init_samr_r_query_dispinfo(r_u, num_entries, data_size, q_u->switch_level, ctr, r_u->status);
1131 return r_u->status;
1134 /*******************************************************************
1135 samr_reply_query_aliasinfo
1136 ********************************************************************/
1138 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1140 fstring alias_desc = "Local Unix group";
1141 fstring alias="";
1142 enum SID_NAME_USE type;
1143 uint32 alias_rid;
1144 struct samr_info *info = NULL;
1146 r_u->status = NT_STATUS_OK;
1148 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1150 /* find the policy handle. open a policy on it. */
1151 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1152 return NT_STATUS_INVALID_HANDLE;
1154 alias_rid = get_lsa_policy_samr_rid(info);
1155 if(alias_rid == 0xffffffff)
1156 return NT_STATUS_NO_SUCH_ALIAS;
1158 if(!local_lookup_rid(alias_rid, alias, &type))
1159 return NT_STATUS_NO_SUCH_ALIAS;
1161 switch (q_u->switch_level) {
1162 case 3:
1163 r_u->ptr = 1;
1164 r_u->ctr.switch_value1 = 3;
1165 init_samr_alias_info3(&r_u->ctr.alias.info3, alias_desc);
1166 break;
1167 default:
1168 return NT_STATUS_INVALID_INFO_CLASS;
1171 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1173 return r_u->status;
1176 #if 0
1177 /*******************************************************************
1178 samr_reply_lookup_ids
1179 ********************************************************************/
1181 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1183 uint32 rid[MAX_SAM_ENTRIES];
1184 int num_rids = q_u->num_sids1;
1186 r_u->status = NT_STATUS_OK;
1188 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1190 if (num_rids > MAX_SAM_ENTRIES) {
1191 num_rids = MAX_SAM_ENTRIES;
1192 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1195 #if 0
1196 int i;
1197 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1199 for (i = 0; i < num_rids && status == 0; i++)
1201 struct sam_passwd *sam_pass;
1202 fstring user_name;
1205 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1206 q_u->uni_user_name[i].uni_str_len));
1208 /* find the user account */
1209 become_root();
1210 sam_pass = get_smb21pwd_entry(user_name, 0);
1211 unbecome_root();
1213 if (sam_pass == NULL)
1215 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1216 rid[i] = 0;
1218 else
1220 rid[i] = sam_pass->user_rid;
1223 #endif
1225 num_rids = 1;
1226 rid[0] = BUILTIN_ALIAS_RID_USERS;
1228 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1230 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1232 return r_u->status;
1234 #endif
1236 /*******************************************************************
1237 _samr_lookup_names
1238 ********************************************************************/
1240 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1242 uint32 rid[MAX_SAM_ENTRIES];
1243 uint32 local_rid;
1244 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1245 enum SID_NAME_USE local_type;
1246 int i;
1247 int num_rids = q_u->num_names2;
1248 DOM_SID pol_sid;
1249 fstring sid_str;
1251 r_u->status = NT_STATUS_OK;
1253 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1255 ZERO_ARRAY(rid);
1256 ZERO_ARRAY(type);
1258 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
1259 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1260 return r_u->status;
1263 if (num_rids > MAX_SAM_ENTRIES) {
1264 num_rids = MAX_SAM_ENTRIES;
1265 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1268 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1270 for (i = 0; i < num_rids; i++) {
1271 fstring name;
1272 DOM_SID sid;
1274 r_u->status = NT_STATUS_NONE_MAPPED;
1276 rid [i] = 0xffffffff;
1277 type[i] = SID_NAME_UNKNOWN;
1279 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer, q_u->uni_name[i].uni_str_len));
1282 * we are only looking for a name
1283 * the SID we get back can be outside
1284 * the scope of the pol_sid
1286 * in clear: it prevents to reply to domain\group: yes
1287 * when only builtin\group exists.
1289 * a cleaner code is to add the sid of the domain we're looking in
1290 * to the local_lookup_name function.
1293 if(local_lookup_name(global_myname, name, &sid, &local_type)) {
1294 sid_split_rid(&sid, &local_rid);
1296 if (sid_equal(&sid, &pol_sid)) {
1297 rid[i]=local_rid;
1298 type[i]=local_type;
1299 r_u->status = NT_STATUS_OK;
1304 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1306 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1308 return r_u->status;
1311 /*******************************************************************
1312 _samr_chgpasswd_user
1313 ********************************************************************/
1315 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1317 fstring user_name;
1318 fstring wks;
1320 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1322 r_u->status = NT_STATUS_OK;
1324 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1325 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1327 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1330 * Pass the user through the NT -> unix user mapping
1331 * function.
1334 (void)map_username(user_name);
1337 * Do any UNIX username case mangling.
1339 (void)Get_Pwnam( user_name, True);
1341 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1342 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1343 r_u->status = NT_STATUS_WRONG_PASSWORD;
1345 init_samr_r_chgpasswd_user(r_u, r_u->status);
1347 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1349 return r_u->status;
1352 /*******************************************************************
1353 makes a SAMR_R_LOOKUP_RIDS structure.
1354 ********************************************************************/
1356 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1357 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1359 uint32 i;
1360 UNIHDR *hdr_name = NULL;
1361 UNISTR2 *uni_name = NULL;
1363 *pp_uni_name = NULL;
1364 *pp_hdr_name = NULL;
1366 if (num_names != 0) {
1367 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1368 if (hdr_name == NULL)
1369 return False;
1371 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1372 if (uni_name == NULL)
1373 return False;
1376 for (i = 0; i < num_names; i++) {
1377 int len = names[i] != NULL ? strlen(names[i]) : 0;
1378 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1379 init_uni_hdr(&hdr_name[i], len);
1380 init_unistr2(&uni_name[i], names[i], len);
1383 *pp_uni_name = uni_name;
1384 *pp_hdr_name = hdr_name;
1386 return True;
1389 /*******************************************************************
1390 _samr_lookup_rids
1391 ********************************************************************/
1393 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1395 fstring group_names[MAX_SAM_ENTRIES];
1396 uint32 *group_attrs = NULL;
1397 UNIHDR *hdr_name = NULL;
1398 UNISTR2 *uni_name = NULL;
1399 DOM_SID pol_sid;
1400 int num_rids = q_u->num_rids1;
1401 int i;
1403 r_u->status = NT_STATUS_OK;
1405 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1407 /* find the policy handle. open a policy on it. */
1408 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
1409 return NT_STATUS_INVALID_HANDLE;
1411 if (num_rids > MAX_SAM_ENTRIES) {
1412 num_rids = MAX_SAM_ENTRIES;
1413 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1416 if (num_rids) {
1417 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1418 return NT_STATUS_NO_MEMORY;
1421 r_u->status = NT_STATUS_NONE_MAPPED;
1423 for (i = 0; i < num_rids; i++) {
1424 fstring tmpname;
1425 fstring domname;
1426 DOM_SID sid;
1427 enum SID_NAME_USE type;
1429 group_attrs[i] = SID_NAME_UNKNOWN;
1430 *group_names[i] = '\0';
1432 if (sid_equal(&pol_sid, &global_sam_sid)) {
1433 sid_copy(&sid, &pol_sid);
1434 sid_append_rid(&sid, q_u->rid[i]);
1436 if (lookup_sid(&sid, domname, tmpname, &type)) {
1437 r_u->status = NT_STATUS_OK;
1438 group_attrs[i] = (uint32)type;
1439 fstrcpy(group_names[i],tmpname);
1444 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1445 return NT_STATUS_NO_MEMORY;
1447 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1449 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1451 return r_u->status;
1454 /*******************************************************************
1455 _api_samr_open_user. Safe - gives out no passwd info.
1456 ********************************************************************/
1458 NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1460 SAM_ACCOUNT *sampass=NULL;
1461 DOM_SID sid;
1462 POLICY_HND domain_pol = q_u->domain_pol;
1463 uint32 user_rid = q_u->user_rid;
1464 POLICY_HND *user_pol = &r_u->user_pol;
1465 struct samr_info *info = NULL;
1466 BOOL ret;
1468 r_u->status = NT_STATUS_OK;
1470 /* find the domain policy handle. */
1471 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1472 return NT_STATUS_INVALID_HANDLE;
1474 pdb_init_sam(&sampass);
1476 become_root();
1477 ret=pdb_getsampwrid(sampass, user_rid);
1478 unbecome_root();
1480 /* check that the RID exists in our domain. */
1481 if (ret == False) {
1482 pdb_free_sam(sampass);
1483 return NT_STATUS_NO_SUCH_USER;
1486 samr_clear_sam_passwd(sampass);
1487 pdb_free_sam(sampass);
1489 /* Get the domain SID stored in the domain policy */
1490 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1491 return NT_STATUS_INVALID_HANDLE;
1493 /* append the user's RID to it */
1494 if(!sid_append_rid(&sid, user_rid))
1495 return NT_STATUS_NO_SUCH_USER;
1497 /* associate the user's SID with the new handle. */
1498 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1499 return NT_STATUS_NO_MEMORY;
1501 ZERO_STRUCTP(info);
1502 info->sid = sid;
1504 /* get a (unique) handle. open a policy on it. */
1505 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1506 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1508 return r_u->status;
1511 /*************************************************************************
1512 get_user_info_10. Safe. Only gives out acb bits.
1513 *************************************************************************/
1515 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1517 SAM_ACCOUNT *smbpass=NULL;
1518 BOOL ret;
1520 if (!pdb_rid_is_user(user_rid)) {
1521 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1522 return False;
1525 pdb_init_sam(&smbpass);
1527 become_root();
1528 ret = pdb_getsampwrid(smbpass, user_rid);
1529 unbecome_root();
1531 if (ret==False) {
1532 DEBUG(4,("User 0x%x not found\n", user_rid));
1533 pdb_free_sam(smbpass);
1534 return False;
1537 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1539 ZERO_STRUCTP(id10);
1540 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1542 samr_clear_sam_passwd(smbpass);
1543 pdb_free_sam(smbpass);
1545 return True;
1548 /*************************************************************************
1549 get_user_info_12. OK - this is the killer as it gives out password info.
1550 Ensure that this is only allowed on an encrypted connection with a root
1551 user. JRA.
1552 *************************************************************************/
1554 static NTSTATUS get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
1556 SAM_ACCOUNT *smbpass=NULL;
1557 BOOL ret;
1559 if (!p->ntlmssp_auth_validated)
1560 return NT_STATUS_ACCESS_DENIED;
1562 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1563 return NT_STATUS_ACCESS_DENIED;
1566 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1568 pdb_init_sam(&smbpass);
1570 ret = pdb_getsampwrid(smbpass, user_rid);
1572 if (ret == False) {
1573 DEBUG(4, ("User 0x%x not found\n", user_rid));
1574 pdb_free_sam(smbpass);
1575 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1578 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1580 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1581 pdb_free_sam(smbpass);
1582 return NT_STATUS_ACCOUNT_DISABLED;
1585 ZERO_STRUCTP(id12);
1586 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1588 pdb_free_sam(smbpass);
1590 return NT_STATUS_OK;
1593 #if 1 /* JRA - re-enabled... JERRY - why was this removed ? */
1594 /*************************************************************************
1595 get_user_info_20
1596 *************************************************************************/
1598 static BOOL get_user_info_20(SAM_USER_INFO_20 *id20, uint32 user_rid)
1600 SAM_ACCOUNT *sampass=NULL;
1601 BOOL ret;
1603 if (!pdb_rid_is_user(user_rid)) {
1604 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1605 return False;
1608 pdb_init_sam(&sampass);
1610 become_root();
1611 ret = pdb_getsampwrid(sampass, user_rid);
1612 unbecome_root();
1614 if (ret == False) {
1615 DEBUG(4,("User 0x%x not found\n", user_rid));
1616 pdb_free_sam(sampass);
1617 return False;
1620 samr_clear_sam_passwd(sampass);
1622 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1624 ZERO_STRUCTP(id20);
1625 init_sam_user_info20A(id20, sampass);
1627 pdb_free_sam(sampass);
1629 return True;
1631 #endif
1633 /*************************************************************************
1634 get_user_info_21
1635 *************************************************************************/
1637 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1639 SAM_ACCOUNT *sampass=NULL;
1640 BOOL ret;
1642 if (!pdb_rid_is_user(user_rid)) {
1643 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1644 return False;
1647 pdb_init_sam(&sampass);
1649 become_root();
1650 ret = pdb_getsampwrid(sampass, user_rid);
1651 unbecome_root();
1653 if (ret == False) {
1654 DEBUG(4,("User 0x%x not found\n", user_rid));
1655 pdb_free_sam(sampass);
1656 return False;
1659 samr_clear_sam_passwd(sampass);
1661 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1663 ZERO_STRUCTP(id21);
1664 init_sam_user_info21A(id21, sampass);
1666 pdb_free_sam(sampass);
1668 return True;
1671 /*******************************************************************
1672 _samr_query_userinfo
1673 ********************************************************************/
1675 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1677 SAM_USERINFO_CTR *ctr;
1678 uint32 rid = 0;
1679 struct samr_info *info = NULL;
1681 r_u->status=NT_STATUS_OK;
1683 /* search for the handle */
1684 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1685 return NT_STATUS_INVALID_HANDLE;
1687 /* find the user's rid */
1688 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1689 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1691 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
1693 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1694 if (!ctr)
1695 return NT_STATUS_NO_MEMORY;
1697 ZERO_STRUCTP(ctr);
1699 /* ok! user info levels (lots: see MSDEV help), off we go... */
1700 ctr->switch_value = q_u->switch_value;
1702 switch (q_u->switch_value) {
1703 case 0x10:
1704 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1705 if (ctr->info.id10 == NULL)
1706 return NT_STATUS_NO_MEMORY;
1708 if (!get_user_info_10(ctr->info.id10, rid))
1709 return NT_STATUS_NO_SUCH_USER;
1710 break;
1712 #if 0
1713 /* whoops - got this wrong. i think. or don't understand what's happening. */
1714 case 0x11:
1716 NTTIME expire;
1717 info = (void *)&id11;
1719 expire.low = 0xffffffff;
1720 expire.high = 0x7fffffff;
1722 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1723 sizeof
1724 (*ctr->
1725 info.
1726 id11));
1727 init_sam_user_info11(ctr->info.id11, &expire,
1728 "BROOKFIELDS$", /* name */
1729 0x03ef, /* user rid */
1730 0x201, /* group rid */
1731 0x0080); /* acb info */
1733 break;
1735 #endif
1737 case 0x12:
1738 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1739 if (ctr->info.id12 == NULL)
1740 return NT_STATUS_NO_MEMORY;
1742 if (NT_STATUS_IS_ERR(r_u->status = get_user_info_12(p, ctr->info.id12, rid)))
1743 return r_u->status;
1744 break;
1746 case 20:
1747 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1748 if (ctr->info.id20 == NULL)
1749 return NT_STATUS_NO_MEMORY;
1750 if (!get_user_info_20(ctr->info.id20, rid))
1751 return NT_STATUS_NO_SUCH_USER;
1752 break;
1754 case 21:
1755 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1756 if (ctr->info.id21 == NULL)
1757 return NT_STATUS_NO_MEMORY;
1758 if (!get_user_info_21(ctr->info.id21, rid))
1759 return NT_STATUS_NO_SUCH_USER;
1760 break;
1762 default:
1763 return NT_STATUS_INVALID_INFO_CLASS;
1766 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1768 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1770 return r_u->status;
1773 /*******************************************************************
1774 samr_reply_query_usergroups
1775 ********************************************************************/
1777 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1779 SAM_ACCOUNT *sam_pass=NULL;
1780 DOM_GID *gids = NULL;
1781 int num_groups = 0;
1782 pstring groups;
1783 uint32 rid;
1784 struct samr_info *info = NULL;
1785 BOOL ret;
1787 r_u->status = NT_STATUS_OK;
1789 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1791 /* find the policy handle. open a policy on it. */
1792 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1793 return NT_STATUS_INVALID_HANDLE;
1795 /* find the user's rid */
1796 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1797 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1799 pdb_init_sam(&sam_pass);
1801 become_root();
1802 ret = pdb_getsampwrid(sam_pass, rid);
1803 unbecome_root();
1805 if (ret == False) {
1806 samr_clear_sam_passwd(sam_pass);
1807 return NT_STATUS_NO_SUCH_USER;
1810 get_domain_user_groups(groups, pdb_get_username(sam_pass));
1811 gids = NULL;
1812 num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
1814 /* construct the response. lkclXXXX: gids are not copied! */
1815 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1817 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1819 samr_clear_sam_passwd(sam_pass);
1821 return r_u->status;
1824 /*******************************************************************
1825 _samr_query_dom_info
1826 ********************************************************************/
1828 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1830 SAM_UNK_CTR *ctr;
1832 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
1833 return NT_STATUS_NO_MEMORY;
1835 ZERO_STRUCTP(ctr);
1837 r_u->status = NT_STATUS_OK;
1839 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1841 /* find the policy handle. open a policy on it. */
1842 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
1843 return NT_STATUS_INVALID_HANDLE;
1845 switch (q_u->switch_value) {
1846 case 0x01:
1847 init_unk_info1(&ctr->info.inf1);
1848 break;
1849 case 0x02:
1850 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1851 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL));
1852 break;
1853 case 0x03:
1854 init_unk_info3(&ctr->info.inf3);
1855 break;
1856 case 0x05:
1857 init_unk_info5(&ctr->info.inf5, global_myname);
1858 break;
1859 case 0x06:
1860 init_unk_info6(&ctr->info.inf6);
1861 break;
1862 case 0x07:
1863 init_unk_info7(&ctr->info.inf7);
1864 break;
1865 case 0x0c:
1866 init_unk_info12(&ctr->info.inf12);
1867 break;
1868 default:
1869 return NT_STATUS_INVALID_INFO_CLASS;
1872 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
1874 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1876 return r_u->status;
1879 /*******************************************************************
1880 _api_samr_create_user
1881 Create an account, can be either a normal user or a machine.
1882 This funcion will need to be updated for bdc/domain trusts.
1883 ********************************************************************/
1885 NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
1887 SAM_ACCOUNT *sam_pass=NULL;
1888 fstring mach_acct;
1889 pstring err_str;
1890 pstring msg_str;
1891 int local_flags=0;
1892 DOM_SID sid;
1893 pstring add_script;
1894 POLICY_HND dom_pol = q_u->domain_pol;
1895 UNISTR2 user_account = q_u->uni_name;
1896 uint16 acb_info = q_u->acb_info;
1897 POLICY_HND *user_pol = &r_u->user_pol;
1898 struct samr_info *info = NULL;
1899 BOOL ret;
1901 /* find the policy handle. open a policy on it. */
1902 if (!find_policy_by_hnd(p, &dom_pol, NULL))
1903 return NT_STATUS_INVALID_HANDLE;
1905 /* find the machine account: tell the caller if it exists.
1906 lkclXXXX i have *no* idea if this is a problem or not
1907 or even if you are supposed to construct a different
1908 reply if the account already exists...
1911 fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
1912 strlower(mach_acct);
1914 pdb_init_sam(&sam_pass);
1916 become_root();
1917 ret = pdb_getsampwnam(sam_pass, mach_acct);
1918 unbecome_root();
1919 if (ret == True) {
1920 /* machine account exists: say so */
1921 pdb_free_sam(sam_pass);
1922 return NT_STATUS_USER_EXISTS;
1925 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1926 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1929 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1930 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1931 * that only people with write access to the smbpasswd file will be able
1932 * to create a user. JRA.
1936 * add the user in the /etc/passwd file or the unix authority system.
1937 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1938 * a) local_password_change() checks for us if the /etc/passwd account really exists
1939 * b) smb_create_user() would return an error if the account already exists
1940 * and as it could return an error also if it can't create the account, it would be tricky.
1942 * So we go the easy way, only check after if the account exists.
1943 * JFM (2/3/2001), to clear any possible bad understanding (-:
1946 pstrcpy(add_script, lp_adduser_script());
1948 if(*add_script)
1949 smb_create_user(mach_acct, NULL);
1951 /* add the user in the smbpasswd file or the Samba authority database */
1952 if (!local_password_change(mach_acct, local_flags, NULL, err_str, sizeof(err_str), msg_str, sizeof(msg_str))) {
1953 DEBUG(0, ("%s\n", err_str));
1954 pdb_free_sam(sam_pass);
1955 return NT_STATUS_ACCESS_DENIED;
1958 become_root();
1959 ret = pdb_getsampwnam(sam_pass, mach_acct);
1960 unbecome_root();
1961 if (ret == False) {
1962 /* account doesn't exist: say so */
1963 pdb_free_sam(sam_pass);
1964 return NT_STATUS_ACCESS_DENIED;
1967 /* Get the domain SID stored in the domain policy */
1968 if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
1969 pdb_free_sam(sam_pass);
1970 return NT_STATUS_INVALID_HANDLE;
1973 /* append the user's RID to it */
1974 if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
1975 pdb_free_sam(sam_pass);
1976 return NT_STATUS_NO_SUCH_USER;
1979 /* associate the user's SID with the new handle. */
1980 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL) {
1981 pdb_free_sam(sam_pass);
1982 return NT_STATUS_NO_MEMORY;
1985 ZERO_STRUCTP(info);
1986 info->sid = sid;
1988 /* get a (unique) handle. open a policy on it. */
1989 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
1990 pdb_free_sam(sam_pass);
1991 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1994 r_u->user_rid=sam_pass->user_rid;
1995 r_u->unknown_0 = 0x000703ff;
1997 pdb_free_sam(sam_pass);
1999 return NT_STATUS_OK;
2002 /*******************************************************************
2003 samr_reply_connect_anon
2004 ********************************************************************/
2006 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2008 struct samr_info *info = NULL;
2010 /* set up the SAMR connect_anon response */
2012 r_u->status = NT_STATUS_OK;
2014 /* associate the user's SID with the new handle. */
2015 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2016 return NT_STATUS_NO_MEMORY;
2018 ZERO_STRUCTP(info);
2019 info->status = q_u->unknown_0;
2021 /* get a (unique) handle. open a policy on it. */
2022 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2023 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2025 return r_u->status;
2028 /*******************************************************************
2029 samr_reply_connect
2030 ********************************************************************/
2032 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2034 struct samr_info *info = NULL;
2036 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2038 r_u->status = NT_STATUS_OK;
2040 /* associate the user's SID with the new handle. */
2041 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2042 return NT_STATUS_NO_MEMORY;
2044 ZERO_STRUCTP(info);
2045 info->status = q_u->access_mask;
2047 /* get a (unique) handle. open a policy on it. */
2048 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2049 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2051 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2053 return r_u->status;
2056 /**********************************************************************
2057 api_samr_lookup_domain
2058 **********************************************************************/
2060 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2062 r_u->status = NT_STATUS_OK;
2064 if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
2065 return NT_STATUS_INVALID_HANDLE;
2067 /* assume the domain name sent is our global_myname and
2068 send global_sam_sid */
2069 init_samr_r_lookup_domain(r_u, &global_sam_sid, r_u->status);
2071 return r_u->status;
2074 /******************************************************************
2075 makes a SAMR_R_ENUM_DOMAINS structure.
2076 ********************************************************************/
2078 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2079 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2081 uint32 i;
2082 SAM_ENTRY *sam;
2083 UNISTR2 *uni_name;
2085 DEBUG(5, ("make_enum_domains\n"));
2087 *pp_sam = NULL;
2088 *pp_uni_name = NULL;
2090 if (num_sam_entries == 0)
2091 return True;
2093 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2094 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2096 if (sam == NULL || uni_name == NULL)
2097 return False;
2099 for (i = 0; i < num_sam_entries; i++) {
2100 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
2102 init_sam_entry(&sam[i], len, 0);
2103 init_unistr2(&uni_name[i], doms[i], len);
2106 *pp_sam = sam;
2107 *pp_uni_name = uni_name;
2109 return True;
2112 /**********************************************************************
2113 api_samr_enum_domains
2114 **********************************************************************/
2116 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2118 uint32 num_entries = 2;
2119 fstring dom[2];
2121 r_u->status = NT_STATUS_OK;
2123 fstrcpy(dom[0],global_myworkgroup);
2124 fstrcpy(dom[1],"Builtin");
2126 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2127 return NT_STATUS_NO_MEMORY;
2129 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2131 return r_u->status;
2134 /*******************************************************************
2135 api_samr_open_alias
2136 ********************************************************************/
2138 NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2140 DOM_SID sid;
2141 POLICY_HND domain_pol = q_u->dom_pol;
2142 uint32 alias_rid = q_u->rid_alias;
2143 POLICY_HND *alias_pol = &r_u->pol;
2144 struct samr_info *info = NULL;
2146 r_u->status = NT_STATUS_OK;
2148 /* get the domain policy. */
2149 if (!find_policy_by_hnd(p, &domain_pol, NULL))
2150 return NT_STATUS_INVALID_HANDLE;
2152 /* Get the domain SID stored in the domain policy */
2153 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
2154 return NT_STATUS_INVALID_HANDLE;
2156 /* append the alias' RID to it */
2157 if(!sid_append_rid(&sid, alias_rid))
2158 return NT_STATUS_NO_SUCH_USER;
2161 * we should check if the rid really exist !!!
2162 * JFM.
2165 /* associate the user's SID with the new handle. */
2166 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2167 return NT_STATUS_NO_MEMORY;
2169 ZERO_STRUCTP(info);
2170 info->sid = sid;
2172 /* get a (unique) handle. open a policy on it. */
2173 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2174 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2176 return r_u->status;
2179 /*******************************************************************
2180 set_user_info_10
2181 ********************************************************************/
2183 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2185 SAM_ACCOUNT *pwd =NULL;
2186 BOOL ret;
2188 pdb_init_sam(&pwd);
2190 ret = pdb_getsampwrid(pwd, rid);
2192 if(ret==False) {
2193 pdb_free_sam(pwd);
2194 return False;
2197 if (id10 == NULL) {
2198 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2199 pdb_free_sam(pwd);
2200 return False;
2203 if (!pdb_set_acct_ctrl(pwd, id10->acb_info)) {
2204 pdb_free_sam(pwd);
2205 return False;
2208 if(!pdb_update_sam_account(pwd, True)) {
2209 pdb_free_sam(pwd);
2210 return False;
2213 pdb_free_sam(pwd);
2215 return True;
2218 /*******************************************************************
2219 set_user_info_12
2220 ********************************************************************/
2222 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2224 SAM_ACCOUNT *pwd = NULL;
2226 pdb_init_sam(&pwd);
2228 if(!pdb_getsampwrid(pwd, rid)) {
2229 pdb_free_sam(pwd);
2230 return False;
2233 if (id12 == NULL) {
2234 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2235 pdb_free_sam(pwd);
2236 return False;
2239 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd)) {
2240 pdb_free_sam(pwd);
2241 return False;
2243 if (!pdb_set_nt_passwd(pwd, id12->nt_pwd)) {
2244 pdb_free_sam(pwd);
2245 return False;
2248 if(!pdb_update_sam_account(pwd, True)) {
2249 pdb_free_sam(pwd);
2250 return False;
2253 pdb_free_sam(pwd);
2254 return True;
2257 /*******************************************************************
2258 set_user_info_21
2259 ********************************************************************/
2261 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
2263 SAM_ACCOUNT *pwd = NULL;
2264 SAM_ACCOUNT *new_pwd = NULL;
2266 if (id21 == NULL) {
2267 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2268 return False;
2271 pdb_init_sam(&pwd);
2272 pdb_init_sam(&new_pwd);
2274 if (!pdb_getsampwrid(pwd, rid)) {
2275 pdb_free_sam(pwd);
2276 pdb_free_sam(new_pwd);
2277 return False;
2280 /* we make a copy so that we can modify stuff */
2281 copy_sam_passwd(new_pwd, pwd);
2282 copy_id21_to_sam_passwd(new_pwd, id21);
2285 * The funny part about the previous two calls is
2286 * that pwd still has the password hashes from the
2287 * passdb entry. These have not been updated from
2288 * id21. I don't know if they need to be set. --jerry
2291 /* write the change out */
2292 if(!pdb_update_sam_account(new_pwd, True)) {
2293 pdb_free_sam(pwd);
2294 pdb_free_sam(new_pwd);
2295 return False;
2298 pdb_free_sam(pwd);
2299 pdb_free_sam(new_pwd);
2301 return True;
2304 /*******************************************************************
2305 set_user_info_23
2306 ********************************************************************/
2308 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2310 SAM_ACCOUNT *pwd = NULL;
2311 SAM_ACCOUNT *new_pwd = NULL;
2312 uint8 nt_hash[16];
2313 uint8 lm_hash[16];
2314 pstring buf;
2315 uint32 len;
2316 uint16 acct_ctrl;
2318 if (id23 == NULL) {
2319 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2320 return False;
2323 pdb_init_sam(&pwd);
2324 pdb_init_sam(&new_pwd);
2326 if (!pdb_getsampwrid(pwd, rid)) {
2327 pdb_free_sam(pwd);
2328 pdb_free_sam(new_pwd);
2329 return False;
2332 acct_ctrl = pdb_get_acct_ctrl(pwd);
2334 copy_sam_passwd(new_pwd, pwd);
2335 pdb_free_sam(pwd);
2337 copy_id23_to_sam_passwd(new_pwd, id23);
2339 if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len, nt_hash, lm_hash)) {
2340 pdb_free_sam(new_pwd);
2341 return False;
2344 if (!pdb_set_lanman_passwd (new_pwd, lm_hash)) {
2345 pdb_free_sam(new_pwd);
2346 return False;
2348 if (!pdb_set_nt_passwd(new_pwd, nt_hash)) {
2349 pdb_free_sam(new_pwd);
2350 return False;
2353 /* if it's a trust account, don't update /etc/passwd */
2354 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2355 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2356 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2357 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2358 } else {
2359 /* update the UNIX password */
2360 if (lp_unix_password_sync() )
2361 if(!chgpasswd(pdb_get_username(new_pwd), "", buf, True)) {
2362 pdb_free_sam(new_pwd);
2363 return False;
2367 memset(buf, 0, sizeof(buf));
2369 if(!pdb_update_sam_account(new_pwd, True)) {
2370 pdb_free_sam(new_pwd);
2371 return False;
2374 pdb_free_sam(new_pwd);
2376 return True;
2379 /*******************************************************************
2380 set_user_info_pw
2381 ********************************************************************/
2383 static BOOL set_user_info_pw(char *pass, uint32 rid)
2385 SAM_ACCOUNT *pwd = NULL;
2386 uchar nt_hash[16];
2387 uchar lm_hash[16];
2388 uint32 len;
2389 pstring buf;
2390 uint16 acct_ctrl;
2392 pdb_init_sam(&pwd);
2394 if (!pdb_getsampwrid(pwd, rid)) {
2395 pdb_free_sam(pwd);
2396 return False;
2399 acct_ctrl = pdb_get_acct_ctrl(pwd);
2401 memset(buf, 0, sizeof(buf));
2403 if (!decode_pw_buffer(pass, buf, 256, &len, nt_hash, lm_hash)) {
2404 pdb_free_sam(pwd);
2405 return False;
2408 if (!pdb_set_lanman_passwd (pwd, lm_hash)) {
2409 pdb_free_sam(pwd);
2410 return False;
2412 if (!pdb_set_nt_passwd(pwd, nt_hash)) {
2413 pdb_free_sam(pwd);
2414 return False;
2417 /* if it's a trust account, don't update /etc/passwd */
2418 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2419 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2420 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2421 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2422 } else {
2423 /* update the UNIX password */
2424 if (lp_unix_password_sync())
2425 if(!chgpasswd(pdb_get_username(pwd), "", buf, True)) {
2426 pdb_free_sam(pwd);
2427 return False;
2431 memset(buf, 0, sizeof(buf));
2433 DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
2435 /* update the SAMBA password */
2436 if(!pdb_update_sam_account(pwd, True)) {
2437 pdb_free_sam(pwd);
2438 return False;
2441 pdb_free_sam(pwd);
2443 return True;
2446 /*******************************************************************
2447 samr_reply_set_userinfo
2448 ********************************************************************/
2450 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2452 uint32 rid = 0x0;
2453 DOM_SID sid;
2454 struct current_user user;
2455 SAM_ACCOUNT *sam_pass=NULL;
2456 unsigned char sess_key[16];
2457 POLICY_HND *pol = &q_u->pol;
2458 uint16 switch_value = q_u->switch_value;
2459 SAM_USERINFO_CTR *ctr = q_u->ctr;
2460 BOOL ret;
2462 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2464 r_u->status = NT_STATUS_OK;
2466 if (p->ntlmssp_auth_validated) {
2467 memcpy(&user, &p->pipe_user, sizeof(user));
2468 } else {
2469 extern struct current_user current_user;
2470 memcpy(&user, &current_user, sizeof(user));
2473 /* find the policy handle. open a policy on it. */
2474 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2475 return NT_STATUS_INVALID_HANDLE;
2477 sid_split_rid(&sid, &rid);
2479 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2481 if (ctr == NULL) {
2482 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2483 return NT_STATUS_INVALID_INFO_CLASS;
2487 pdb_init_sam(&sam_pass);
2490 * We need the NT hash of the user who is changing the user's password.
2491 * This NT hash is used to generate a "user session key"
2492 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2495 become_root();
2496 ret = pdb_getsampwuid(sam_pass, user.uid);
2497 unbecome_root();
2498 if(ret == False) {
2499 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
2500 pdb_free_sam(sam_pass);
2501 return NT_STATUS_ACCESS_DENIED;
2504 memset(sess_key, '\0', 16);
2505 mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2507 pdb_free_sam(sam_pass);
2509 /* ok! user info levels (lots: see MSDEV help), off we go... */
2510 switch (switch_value) {
2511 case 0x12:
2512 if (!set_user_info_12(ctr->info.id12, rid))
2513 return NT_STATUS_ACCESS_DENIED;
2514 break;
2516 case 24:
2517 SamOEMhash(ctr->info.id24->pass, sess_key, 516);
2519 dump_data(100, (char *)ctr->info.id24->pass, 516);
2521 if (!set_user_info_pw((char *)ctr->info.id24->pass, rid))
2522 return NT_STATUS_ACCESS_DENIED;
2523 break;
2525 case 25:
2526 #if 0
2528 * Currently we don't really know how to unmarshall
2529 * the level 25 struct, and the password encryption
2530 * is different. This is a placeholder for when we
2531 * do understand it. In the meantime just return INVALID
2532 * info level and W2K SP2 drops down to level 23... JRA.
2535 SamOEMhash(ctr->info.id25->pass, sess_key, 532);
2537 dump_data(100, (char *)ctr->info.id25->pass, 532);
2539 if (!set_user_info_pw(ctr->info.id25->pass, rid))
2540 return NT_STATUS_ACCESS_DENIED;
2541 break;
2542 #endif
2543 return NT_STATUS_INVALID_INFO_CLASS;
2545 case 23:
2546 SamOEMhash(ctr->info.id23->pass, sess_key, 516);
2548 dump_data(100, (char *)ctr->info.id23->pass, 516);
2550 if (!set_user_info_23(ctr->info.id23, rid))
2551 return NT_STATUS_ACCESS_DENIED;
2552 break;
2554 default:
2555 return NT_STATUS_INVALID_INFO_CLASS;
2558 return r_u->status;
2561 /*******************************************************************
2562 samr_reply_set_userinfo2
2563 ********************************************************************/
2565 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2567 DOM_SID sid;
2568 uint32 rid = 0x0;
2569 SAM_USERINFO_CTR *ctr = q_u->ctr;
2570 POLICY_HND *pol = &q_u->pol;
2571 uint16 switch_value = q_u->switch_value;
2573 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2575 r_u->status = NT_STATUS_OK;
2577 /* find the policy handle. open a policy on it. */
2578 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2579 return NT_STATUS_INVALID_HANDLE;
2581 sid_split_rid(&sid, &rid);
2583 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2585 if (ctr == NULL) {
2586 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2587 return NT_STATUS_INVALID_INFO_CLASS;
2590 switch_value=ctr->switch_value;
2592 /* ok! user info levels (lots: see MSDEV help), off we go... */
2593 switch (switch_value) {
2594 case 21:
2595 if (!set_user_info_21(ctr->info.id21, rid))
2596 return NT_STATUS_ACCESS_DENIED;
2597 break;
2598 case 16:
2599 if (!set_user_info_10(ctr->info.id10, rid))
2600 return NT_STATUS_ACCESS_DENIED;
2601 break;
2602 case 18:
2603 /* Used by AS/U JRA. */
2604 if (!set_user_info_12(ctr->info.id12, rid))
2605 return NT_STATUS_ACCESS_DENIED;
2606 break;
2607 default:
2608 return NT_STATUS_INVALID_INFO_CLASS;
2611 return r_u->status;
2614 /*********************************************************************
2615 _samr_query_aliasmem
2616 *********************************************************************/
2618 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
2620 uint32 *rid=NULL;
2621 int num_rids;
2623 num_rids = 1;
2624 rid=(uint32 *)talloc_zero(p->mem_ctx, num_rids*sizeof(uint32));
2625 if (rid == NULL)
2626 return NT_STATUS_NO_MEMORY;
2628 /* until i see a real useraliases query, we fack one up */
2630 rid[0] = BUILTIN_ALIAS_RID_USERS;
2632 init_samr_r_query_useraliases(r_u, num_rids, rid, NT_STATUS_OK);
2634 return NT_STATUS_OK;
2638 /*********************************************************************
2639 _samr_query_aliasmem
2640 *********************************************************************/
2642 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
2644 DEBUG(0,("_samr_query_aliasmem: Not yet implemented.\n"));
2645 return NT_STATUS_NOT_IMPLEMENTED;
2648 /*********************************************************************
2649 _samr_query_groupmem
2650 *********************************************************************/
2652 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
2654 DEBUG(0,("_samr_query_groupmem: Not yet implemented.\n"));
2655 return NT_STATUS_NOT_IMPLEMENTED;
2658 /*********************************************************************
2659 _samr_add_aliasmem
2660 *********************************************************************/
2662 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
2664 DEBUG(0,("_samr_add_aliasmem: Not yet implemented.\n"));
2665 return NT_STATUS_NOT_IMPLEMENTED;
2668 /*********************************************************************
2669 _samr_del_aliasmem
2670 *********************************************************************/
2672 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
2674 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2675 return NT_STATUS_NOT_IMPLEMENTED;
2678 /*********************************************************************
2679 _samr_add_groupmem
2680 *********************************************************************/
2682 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
2684 DEBUG(0,("_samr_add_groupmem: Not yet implemented.\n"));
2685 return NT_STATUS_NOT_IMPLEMENTED;
2688 /*********************************************************************
2689 _samr_del_groupmem
2690 *********************************************************************/
2692 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
2694 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2695 return NT_STATUS_NOT_IMPLEMENTED;
2698 /*********************************************************************
2699 _samr_delete_dom_user
2700 *********************************************************************/
2702 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
2704 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2705 return NT_STATUS_NOT_IMPLEMENTED;
2708 /*********************************************************************
2709 _samr_delete_dom_group
2710 *********************************************************************/
2712 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
2714 DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
2715 return NT_STATUS_NOT_IMPLEMENTED;
2718 /*********************************************************************
2719 _samr_delete_dom_alias
2720 *********************************************************************/
2722 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
2724 DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
2725 return NT_STATUS_NOT_IMPLEMENTED;
2728 /*********************************************************************
2729 _samr_create_dom_group
2730 *********************************************************************/
2732 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
2734 DEBUG(0,("_samr_create_dom_group: Not yet implemented.\n"));
2735 return NT_STATUS_NOT_IMPLEMENTED;
2738 /*********************************************************************
2739 _samr_create_dom_alias
2740 *********************************************************************/
2742 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
2744 DEBUG(0,("_samr_create_dom_alias: Not yet implemented.\n"));
2745 return NT_STATUS_NOT_IMPLEMENTED;
2748 /*********************************************************************
2749 _samr_query_groupinfo
2750 *********************************************************************/
2752 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
2754 DEBUG(0,("_samr_query_groupinfo: Not yet implemented.\n"));
2755 return NT_STATUS_NOT_IMPLEMENTED;
2758 /*********************************************************************
2759 _samr_set_groupinfo
2760 *********************************************************************/
2762 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
2764 DEBUG(0,("_samr_set_groupinfo: Not yet implemented.\n"));
2765 return NT_STATUS_NOT_IMPLEMENTED;
2768 /*********************************************************************
2769 _samr_get_dom_pwinfo
2770 *********************************************************************/
2772 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
2774 /* Actually, returning zeros here works quite well :-). */
2775 return NT_STATUS_OK;
2778 /*********************************************************************
2779 _samr_open_group
2780 *********************************************************************/
2782 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
2784 DEBUG(0,("_samr_open_group: Not yet implemented.\n"));
2785 return NT_STATUS_NOT_IMPLEMENTED;
2788 /*********************************************************************
2789 _samr_unknown_2d
2790 *********************************************************************/
2792 NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
2794 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
2795 return NT_STATUS_NOT_IMPLEMENTED;