Patch from Simo:
[Samba.git] / source / rpc_server / srv_samr_nt.c
blob8c8418d2e01ebd403835da80518215a4c73c77f9
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 int DEBUGLEVEL;
34 extern fstring global_myworkgroup;
35 extern pstring global_myname;
36 extern DOM_SID global_sam_sid;
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
43 struct samr_info {
44 /* for use by the \PIPE\samr policy */
45 DOM_SID sid;
46 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
49 /*******************************************************************
50 Function to free the per handle data.
51 ********************************************************************/
53 static void free_samr_info(void *ptr)
55 struct samr_info *samr = (struct samr_info *)ptr;
57 safe_free(samr);
60 /*******************************************************************
61 Ensure password info is never given out. Paranioa... JRA.
62 ********************************************************************/
64 static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
66 int i;
68 if (!pass)
69 return;
71 for (i = 0; i < num_entries; i++) {
72 memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
73 memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
77 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
79 if (!sam_pass)
80 return;
82 memset(sam_pass->lm_pw, '\0', 16);
83 memset(sam_pass->nt_pw, '\0', 16);
86 /*******************************************************************
87 This next function should be replaced with something that
88 dynamically returns the correct user info..... JRA.
89 ********************************************************************/
91 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
92 int *total_entries, int *num_entries,
93 int max_num_entries, uint16 acb_mask)
95 SAM_ACCOUNT *pwd = NULL;
96 BOOL ret;
98 (*num_entries) = 0;
99 (*total_entries) = 0;
101 if (pw_buf == NULL)
102 return False;
104 pdb_init_sam(&pwd);
106 if (!pdb_setsampwent(False)) {
107 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
108 pdb_free_sam(pwd);
109 return False;
112 while (((ret = pdb_getsampwent(pwd)) != False) && (*num_entries) < max_num_entries) {
113 int user_name_len;
115 if (start_idx > 0) {
116 /* skip the requested number of entries.
117 not very efficient, but hey...
119 start_idx--;
120 continue;
123 user_name_len = strlen(pdb_get_username(pwd))+1;
124 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
125 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
126 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
127 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
129 /* Now check if the NT compatible password is available. */
130 if (pdb_get_nt_passwd(pwd))
131 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
133 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
135 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
136 (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
138 if (acb_mask == 0 || (pwd->acct_ctrl & acb_mask)) {
139 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
140 (*num_entries)++;
142 else
143 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
145 (*total_entries)++;
148 pdb_endsampwent();
149 pdb_free_sam(pwd);
151 return (*num_entries) > 0;
154 static BOOL jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
155 int *total_entries, uint32 *num_entries,
156 int max_num_entries, uint16 acb_mask)
158 SAM_ACCOUNT *pwd = NULL;
160 *num_entries = 0;
161 *total_entries = 0;
163 if (pw_buf == NULL)
164 return False;
166 DEBUG(10,("jf_get_sampwd_entries: start index:%d, max entries:%d, mask:%d\n",
167 start_idx, max_num_entries, acb_mask));
169 if (!pdb_setsampwent(False)) {
170 DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
171 return False;
174 pdb_init_sam(&pwd);
176 while ((pdb_getsampwent(pwd) != False) && (*num_entries) < max_num_entries) {
177 int user_name_len;
178 int full_name_len;
180 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask))
181 continue;
183 if (start_idx > 0) {
184 /* skip the requested number of entries.
185 not very efficient, but hey...
187 start_idx--;
188 continue;
191 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
193 user_name_len = strlen(pdb_get_username(pwd));
194 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
195 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
197 full_name_len = strlen(pdb_get_fullname(pwd));
198 init_unistr2(&pw_buf[(*num_entries)].uni_full_name, pdb_get_fullname(pwd), full_name_len);
199 init_uni_hdr(&pw_buf[(*num_entries)].hdr_full_name, full_name_len);
201 pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
202 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
204 /* Now check if the NT compatible password is available. */
205 if (pdb_get_nt_passwd(pwd))
206 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
208 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
210 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries),
211 pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
213 (*num_entries)++;
216 pdb_endsampwent();
218 *total_entries = *num_entries;
220 pdb_free_sam(pwd);
222 return True;
225 /*******************************************************************
226 This function uses the username map file and tries to map a UNIX
227 user name to an DOS name. (Sort of the reverse of the
228 map_username() function.) Since more than one DOS name can map
229 to the UNIX name, to reverse the mapping you have to specify
230 which corresponding DOS name you want; that's where the name_idx
231 parameter comes in. Returns the string requested or NULL if it
232 fails or can't complete the request for any reason. This doesn't
233 handle group names (starting with '@') or names starting with
234 '+' or '&'. If they are encountered, they are skipped.
235 ********************************************************************/
237 static char *unmap_unixname(char *unix_user_name, int name_idx)
239 char *mapfile = lp_username_map();
240 char **lines;
241 static pstring tok;
242 int i;
244 if (!*unix_user_name) return NULL;
245 if (!*mapfile) return NULL;
247 lines = file_lines_load(mapfile, NULL,False);
248 if (!lines) {
249 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
250 return NULL;
253 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
255 for (i=0; lines[i]; i++) {
256 char *unixname = lines[i];
257 char *dosname = strchr(unixname,'=');
259 if (!dosname)
260 continue;
262 *dosname++ = 0;
264 while (isspace(*unixname))
265 unixname++;
266 if ('!' == *unixname) {
267 unixname++;
268 while (*unixname && isspace(*unixname))
269 unixname++;
272 if (!*unixname || strchr("#;",*unixname))
273 continue;
275 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
276 continue;
278 /* We have matched the UNIX user name */
280 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
281 if (!strchr("@&+", *tok)) {
282 name_idx--;
283 if (name_idx < 0 ) {
284 break;
289 if (name_idx >= 0) {
290 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
291 file_lines_free(lines);
292 return NULL;
293 } else {
294 file_lines_free(lines);
295 return tok;
299 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
300 file_lines_free(lines);
301 return NULL;
304 /*******************************************************************
305 This function sets up a list of users taken from the list of
306 users that UNIX knows about, as well as all the user names that
307 Samba maps to a valid UNIX user name. (This should work with
308 /etc/passwd or NIS.)
309 ********************************************************************/
311 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
312 int start_idx,
313 int *total_entries, int *num_entries,
314 int max_num_entries,
315 uint16 acb_mask)
317 static struct passwd *pwd = NULL;
318 static uint32 pw_rid;
319 static BOOL orig_done = False;
320 static int current_idx = 0;
321 static int mapped_idx = 0;
322 char *sep;
324 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
326 (*num_entries) = 0;
327 (*total_entries) = 0;
329 /* Skip all this stuff if we're in appliance mode */
331 if (lp_hide_local_users()) goto done;
333 if (pw_buf == NULL) return False;
335 if (current_idx == 0) {
336 sys_setpwent();
339 /* These two cases are inefficient, but should be called very rarely */
340 /* they are the cases where the starting index isn't picking up */
341 /* where we left off last time. It is efficient when it starts over */
342 /* at zero though. */
343 if (start_idx > current_idx) {
344 /* We aren't far enough; advance to start_idx */
345 while (current_idx <= start_idx) {
346 char *unmap_name;
348 if(!orig_done) {
349 if ((pwd = sys_getpwent()) == NULL) break;
350 current_idx++;
351 orig_done = True;
354 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
355 (current_idx < start_idx)) {
356 current_idx++;
357 mapped_idx++;
360 if (unmap_name == NULL) {
361 orig_done = False;
362 mapped_idx = 0;
365 } else if (start_idx < current_idx) {
366 /* We are already too far; start over and advance to start_idx */
367 sys_endpwent();
368 sys_setpwent();
369 current_idx = 0;
370 mapped_idx = 0;
371 orig_done = False;
372 while (current_idx < start_idx) {
373 char *unmap_name;
375 if(!orig_done) {
376 if ((pwd = sys_getpwent()) == NULL) break;
377 current_idx++;
378 orig_done = True;
381 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
382 (current_idx < start_idx)) {
383 current_idx++;
384 mapped_idx++;
387 if (unmap_name == NULL) {
388 orig_done = False;
389 mapped_idx = 0;
394 sep = lp_winbind_separator();
396 /* now current_idx == start_idx */
397 while ((*num_entries) < max_num_entries) {
398 int user_name_len;
399 char *unmap_name;
401 /* This does the original UNIX user itself */
402 if(!orig_done) {
403 if ((pwd = sys_getpwent()) == NULL) break;
405 /* Don't enumerate winbind users as they are not local */
407 if (strchr(pwd->pw_name, *sep) != NULL) {
408 continue;
411 user_name_len = strlen(pwd->pw_name);
413 /* skip the trust account stored in the /etc/passwd file */
414 if (pwd->pw_name[user_name_len-1]=='$')
415 continue;
417 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
418 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
419 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pwd->pw_name, user_name_len);
420 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
421 pw_buf[(*num_entries)].user_rid = pw_rid;
422 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
424 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
426 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
428 (*num_entries)++;
429 (*total_entries)++;
430 current_idx++;
431 orig_done = True;
434 /* This does all the user names that map to the UNIX user */
435 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
436 (*num_entries < max_num_entries)) {
437 user_name_len = strlen(unmap_name);
438 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
439 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, unmap_name, user_name_len);
440 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
441 pw_buf[(*num_entries)].user_rid = pw_rid;
442 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
444 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
446 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
448 (*num_entries)++;
449 (*total_entries)++;
450 current_idx++;
451 mapped_idx++;
454 if (unmap_name == NULL) {
455 /* done with 'aliases', go on to next UNIX user */
456 orig_done = False;
457 mapped_idx = 0;
461 if (pwd == NULL) {
462 /* totally done, reset everything */
463 sys_endpwent();
464 current_idx = 0;
465 mapped_idx = 0;
468 done:
469 return (*num_entries) > 0;
472 /*******************************************************************
473 _samr_close_hnd
474 ********************************************************************/
476 uint32 _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
478 r_u->status = NT_STATUS_NOPROBLEMO;
480 /* close the policy handle */
481 if (!close_policy_hnd(p, &q_u->pol))
482 return NT_STATUS_OBJECT_NAME_INVALID;
484 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
486 return r_u->status;
489 /*******************************************************************
490 samr_reply_open_domain
491 ********************************************************************/
493 uint32 _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
495 struct samr_info *info;
497 r_u->status = NT_STATUS_NOPROBLEMO;
499 /* find the connection policy handle. */
500 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
501 return NT_STATUS_INVALID_HANDLE;
503 /* associate the domain SID with the (unique) handle. */
504 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
505 return NT_STATUS_NO_MEMORY;
507 ZERO_STRUCTP(info);
508 info->sid = q_u->dom_sid.sid;
510 /* get a (unique) handle. open a policy on it. */
511 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
512 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
514 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
516 return r_u->status;
519 static uint32 get_lsa_policy_samr_rid(struct samr_info *info)
521 if (!info) {
522 DEBUG(3,("Error getting policy\n"));
523 return 0xffffffff;
526 return info->sid.sub_auths[info->sid.num_auths-1];
529 /*******************************************************************
530 _samr_get_usrdom_pwinfo
531 ********************************************************************/
533 uint32 _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
535 struct samr_info *info = NULL;
537 r_u->status = NT_STATUS_NOPROBLEMO;
539 /* find the policy handle. open a policy on it. */
540 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info)) {
541 return NT_STATUS_INVALID_HANDLE;
544 /* find the user's rid */
545 if (get_lsa_policy_samr_rid(info) == 0xffffffff) {
546 return NT_STATUS_OBJECT_TYPE_MISMATCH;
549 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_NOPROBLEMO);
551 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
553 return r_u->status;
556 /*******************************************************************
557 samr_make_usr_obj_sd
558 ********************************************************************/
560 static uint32 samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
562 extern DOM_SID global_sid_World;
563 DOM_SID adm_sid;
564 DOM_SID act_sid;
566 SEC_ACE ace[4];
567 SEC_ACCESS mask;
569 SEC_ACL *psa = NULL;
570 SEC_DESC *psd = NULL;
571 size_t sd_size;
573 sid_copy(&adm_sid, &global_sid_Builtin);
574 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
576 sid_copy(&act_sid, &global_sid_Builtin);
577 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
579 init_sec_access(&mask, 0x2035b);
580 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
582 init_sec_access(&mask, 0xf07ff);
583 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
584 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
586 init_sec_access(&mask,0x20044);
587 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
589 if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
590 return NT_STATUS_NO_MEMORY;
592 if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
593 return NT_STATUS_NO_MEMORY;
595 if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
596 return NT_STATUS_NO_MEMORY;
598 return NT_STATUS_NOPROBLEMO;
601 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
603 struct samr_info *info = NULL;
605 /* find the policy handle. open a policy on it. */
606 if (!find_policy_by_hnd(p, pol, (void **)&info))
607 return False;
609 if (!info)
610 return False;
612 *sid = info->sid;
613 return True;
616 /*******************************************************************
617 _samr_query_sec_obj
618 ********************************************************************/
620 uint32 _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
622 DOM_SID pol_sid;
624 r_u->status = NT_STATUS_NOPROBLEMO;
626 /* Get the SID. */
628 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
629 return NT_STATUS_INVALID_HANDLE;
631 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
633 if (r_u->status == NT_STATUS_NOPROBLEMO)
634 r_u->ptr = 1;
636 return r_u->status;
639 /*******************************************************************
640 makes a SAM_ENTRY / UNISTR2* structure from a user list.
641 ********************************************************************/
643 static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
644 uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
646 uint32 i;
647 SAM_ENTRY *sam;
648 UNISTR2 *uni_name;
650 *sam_pp = NULL;
651 *uni_name_pp = NULL;
653 if (num_sam_entries == 0)
654 return;
656 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
658 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
660 if (sam == NULL || uni_name == NULL) {
661 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
662 return;
665 for (i = 0; i < num_sam_entries; i++) {
666 int len = pass[i].uni_user_name.uni_str_len;
668 init_sam_entry(&sam[i], len, pass[i].user_rid);
669 copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
672 *sam_pp = sam;
673 *uni_name_pp = uni_name;
676 /*******************************************************************
677 samr_reply_enum_dom_users
678 ********************************************************************/
680 uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
682 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
683 int num_entries = 0;
684 int total_entries = 0;
685 BOOL ret;
687 r_u->status = NT_STATUS_NOPROBLEMO;
689 /* find the policy handle. open a policy on it. */
690 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
691 return NT_STATUS_INVALID_HANDLE;
693 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
695 become_root();
696 ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
697 MAX_SAM_ENTRIES, q_u->acb_mask);
698 unbecome_root();
700 if (!ret)
701 return NT_STATUS_ACCESS_DENIED;
703 samr_clear_passwd_fields(pass, num_entries);
706 * Note from JRA. total_entries is not being used here. Currently if there is a
707 * large user base then it looks like NT will enumerate until get_sampwd_entries
708 * returns False due to num_entries being zero. This will cause an access denied
709 * return. I don't think this is right and needs further investigation. Note that
710 * this is also the same in the TNG code (I don't think that has been tested with
711 * a very large user list as MAX_SAM_ENTRIES is set to 600).
713 * I also think that one of the 'num_entries' return parameters is probably
714 * the "max entries" parameter - but in the TNG code they're all currently set to the same
715 * value (again I think this is wrong).
718 make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
720 init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
722 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
724 return r_u->status;
727 /*******************************************************************
728 makes a SAM_ENTRY / UNISTR2* structure from a group list.
729 ********************************************************************/
731 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
732 uint32 num_sam_entries, DOMAIN_GRP *grp)
734 uint32 i;
735 SAM_ENTRY *sam;
736 UNISTR2 *uni_name;
738 *sam_pp = NULL;
739 *uni_name_pp = NULL;
741 if (num_sam_entries == 0)
742 return;
744 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
746 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
748 if (sam == NULL || uni_name == NULL) {
749 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
750 return;
753 for (i = 0; i < num_sam_entries; i++) {
755 * JRA. I think this should include the null. TNG does not.
757 int len = strlen(grp[i].name)+1;
759 init_sam_entry(&sam[i], len, grp[i].rid);
760 init_unistr2(&uni_name[i], grp[i].name, len);
763 *sam_pp = sam;
764 *uni_name_pp = uni_name;
767 /*******************************************************************
768 Get the group entries - similar to get_sampwd_entries().
769 ********************************************************************/
771 static BOOL get_group_alias_entries(DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
772 uint32 *p_num_entries, uint32 max_entries)
774 fstring sid_str;
775 uint32 num_entries = 0;
776 int i;
777 GROUP_MAP smap;
778 GROUP_MAP *map;
780 sid_to_string(sid_str, sid);
781 DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
783 *p_num_entries = 0;
785 /* well-known aliases */
786 if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
788 enum_group_mapping(SID_NAME_WKN_GRP, &map, &num_entries, ENUM_ONLY_MAPPED);
790 *d_grp=(DOMAIN_GRP *)malloc(num_entries*sizeof(DOMAIN_GRP));
791 if (*d_grp==NULL)
792 return NT_STATUS_NO_MEMORY;
794 for(i=0; i<num_entries && i<max_entries; i++) {
795 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
796 sid_split_rid(&map[i].sid, &(*d_grp)[i].rid);
800 safe_free(map);
802 } else if (sid_equal(sid, &global_sam_sid) && !lp_hide_local_users()) {
803 char *sep;
804 struct group *grp;
805 fstring sid_string;
807 sep = lp_winbind_separator();
809 /* local aliases */
810 /* we return the UNIX groups here. This seems to be the right */
811 /* thing to do, since NT member servers return their local */
812 /* groups in the same situation. */
813 setgrent();
815 while (num_entries < max_entries && ((grp = getgrent()) != NULL)) {
816 int i;
817 uint32 trid;
819 if(!get_group_from_gid(grp->gr_gid, &smap))
820 continue;
822 if (smap.sid_name_use!=SID_NAME_ALIAS)
823 continue;
825 sid_split_rid(&smap.sid, &trid);
827 /* Don't return winbind groups as they are not local! */
828 if (strchr(smap.nt_name, *sep) != NULL) {
829 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
830 continue;
833 /* Don't return user private groups... */
834 if (Get_Pwnam(smap.nt_name, False) != 0) {
835 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
836 continue;
839 for( i = 0; i < num_entries; i++)
840 if ( (*d_grp)[i].rid == trid ) break;
842 if ( i < num_entries )
843 continue; /* rid was there, dup! */
845 /* JRA - added this for large group db enumeration... */
847 if (start_idx > 0) {
848 /* skip the requested number of entries.
849 not very efficient, but hey...
851 start_idx--;
852 continue;
855 *d_grp=Realloc(*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
856 if (*d_grp==NULL)
857 return NT_STATUS_NO_MEMORY;
859 fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
860 (*d_grp)[num_entries].rid = trid;
861 num_entries++;
864 endgrent();
867 *p_num_entries = num_entries;
869 return True;
872 /*******************************************************************
873 Get the group entries - similar to get_sampwd_entries().
874 ********************************************************************/
876 static BOOL get_group_domain_entries(DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
877 uint32 *p_num_entries, uint32 max_entries)
879 GROUP_MAP *map=NULL;
880 int i;
881 uint32 num_entries = 0;
883 *p_num_entries = 0;
885 enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED);
887 *d_grp=(DOMAIN_GRP *)malloc(num_entries*sizeof(DOMAIN_GRP));
888 if (*d_grp==NULL)
889 return False;
891 for (i=0; i<num_entries; i++) {
892 fstrcpy((*d_grp)[i].name, map[i].nt_name);
893 fstrcpy((*d_grp)[i].comment, map[i].comment);
894 sid_split_rid(&map[i].sid, &(*d_grp)[i].rid);
895 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
898 safe_free(map);
900 *p_num_entries = num_entries;
902 return True;
905 /*******************************************************************
906 samr_reply_enum_dom_groups
907 Only reply with one group - domain admins. This must be fixed for
908 a real PDC. JRA.
909 ********************************************************************/
911 uint32 _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
913 DOMAIN_GRP *grp=NULL;
914 uint32 num_entries;
915 DOM_SID sid;
917 r_u->status = NT_STATUS_NOPROBLEMO;
919 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
920 return NT_STATUS_INVALID_HANDLE;
922 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
924 /* the domain group array is being allocated in the function below */
925 get_group_domain_entries(&grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
927 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
929 safe_free(grp);
931 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
933 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
935 return r_u->status;
939 /*******************************************************************
940 samr_reply_enum_dom_aliases
941 ********************************************************************/
943 uint32 _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
945 DOMAIN_GRP *grp=NULL;
946 uint32 num_entries = 0;
947 fstring sid_str;
948 DOM_SID sid;
950 r_u->status = NT_STATUS_NOPROBLEMO;
952 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
953 return NT_STATUS_INVALID_HANDLE;
955 sid_to_string(sid_str, &sid);
956 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
958 if (!get_group_alias_entries(&grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))
959 return NT_STATUS_ACCESS_DENIED;
961 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
963 safe_free(grp);
965 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx, num_entries);
967 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
969 return r_u->status;
972 /*******************************************************************
973 samr_reply_query_dispinfo
974 ********************************************************************/
976 uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
978 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
979 DOMAIN_GRP *grps=NULL;
980 uint16 acb_mask = ACB_NORMAL;
981 uint32 num_entries = 0;
982 int orig_num_entries = 0;
983 int total_entries = 0;
984 uint32 data_size = 0;
985 DOM_SID sid;
986 BOOL ret;
987 SAM_DISPINFO_CTR *ctr;
989 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
991 r_u->status = NT_STATUS_NOPROBLEMO;
993 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
994 return NT_STATUS_INVALID_HANDLE;
996 /* decide how many entries to get depending on the max_entries
997 and max_size passed by client */
999 if(q_u->max_entries > MAX_SAM_ENTRIES)
1000 q_u->max_entries = MAX_SAM_ENTRIES;
1002 /* Get what we need from the password database */
1003 switch (q_u->switch_level) {
1004 case 0x2:
1005 acb_mask = ACB_WSTRUST;
1006 /* Fall through */
1007 case 0x1:
1008 case 0x4:
1009 become_root();
1010 #if 0
1011 ret = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1012 MAX_SAM_ENTRIES, acb_mask);
1013 #endif
1014 #if 0
1016 * Which should we use here ? JRA.
1018 ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1019 MAX_SAM_ENTRIES, acb_mask);
1020 #endif
1021 #if 1
1022 ret = jf_get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
1023 MAX_SAM_ENTRIES, acb_mask);
1024 #endif
1025 unbecome_root();
1026 if (!ret) {
1027 DEBUG(5, ("get_sampwd_entries: failed\n"));
1028 return NT_STATUS_ACCESS_DENIED;
1030 break;
1031 case 0x3:
1032 case 0x5:
1033 ret = get_group_domain_entries(&grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
1034 if (!ret)
1035 return NT_STATUS_ACCESS_DENIED;
1036 break;
1037 default:
1038 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1039 return NT_STATUS_INVALID_INFO_CLASS;
1043 if (num_entries > q_u->max_entries)
1044 num_entries = q_u->max_entries;
1046 if (num_entries > MAX_SAM_ENTRIES) {
1047 num_entries = MAX_SAM_ENTRIES;
1048 DEBUG(5, ("limiting number of entries to %d\n", num_entries));
1051 /* Ensure password info is never given out here. PARANOIA... JRA */
1052 samr_clear_passwd_fields(pass, num_entries);
1054 data_size = q_u->max_size;
1055 orig_num_entries = num_entries;
1057 ctr = (SAM_DISPINFO_CTR *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_CTR));
1059 /* Now create reply structure */
1060 switch (q_u->switch_level) {
1061 case 0x1:
1062 ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_1));
1063 init_sam_dispinfo_1(ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass);
1064 break;
1065 case 0x2:
1066 ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_2));
1067 init_sam_dispinfo_2(ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass);
1068 break;
1069 case 0x3:
1070 ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_3));
1071 init_sam_dispinfo_3(ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps);
1072 safe_free(grps);
1073 break;
1074 case 0x4:
1075 ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_4));
1076 init_sam_dispinfo_4(ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass);
1077 break;
1078 case 0x5:
1079 ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_5));
1080 init_sam_dispinfo_5(ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps);
1081 safe_free(grps);
1082 break;
1083 default:
1084 ctr->sam.info = NULL;
1085 return NT_STATUS_INVALID_INFO_CLASS;
1088 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1090 init_samr_r_query_dispinfo(r_u, num_entries, data_size, q_u->switch_level, ctr, r_u->status);
1092 if (num_entries < orig_num_entries) {
1093 return STATUS_MORE_ENTRIES;
1096 return r_u->status;
1099 /*******************************************************************
1100 samr_reply_query_aliasinfo
1101 ********************************************************************/
1103 uint32 _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1105 fstring alias_desc = "Local Unix group";
1106 fstring alias="";
1107 enum SID_NAME_USE type;
1108 uint32 alias_rid;
1109 struct samr_info *info = NULL;
1111 r_u->status = NT_STATUS_NOPROBLEMO;
1113 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1115 /* find the policy handle. open a policy on it. */
1116 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1117 return NT_STATUS_INVALID_HANDLE;
1119 alias_rid = get_lsa_policy_samr_rid(info);
1120 if(alias_rid == 0xffffffff)
1121 return NT_STATUS_NO_SUCH_ALIAS;
1123 if(!local_lookup_rid(alias_rid, alias, &type))
1124 return NT_STATUS_NO_SUCH_ALIAS;
1126 switch (q_u->switch_level) {
1127 case 3:
1128 r_u->ptr = 1;
1129 r_u->ctr.switch_value1 = 3;
1130 init_samr_alias_info3(&r_u->ctr.alias.info3, alias_desc);
1131 break;
1132 default:
1133 return NT_STATUS_INVALID_INFO_CLASS;
1136 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1138 return r_u->status;
1141 #if 0
1142 /*******************************************************************
1143 samr_reply_lookup_ids
1144 ********************************************************************/
1146 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1148 uint32 rid[MAX_SAM_ENTRIES];
1149 int num_rids = q_u->num_sids1;
1151 r_u->status = NT_STATUS_NOPROBLEMO;
1153 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1155 if (num_rids > MAX_SAM_ENTRIES) {
1156 num_rids = MAX_SAM_ENTRIES;
1157 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1160 #if 0
1161 int i;
1162 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1164 for (i = 0; i < num_rids && status == 0; i++)
1166 struct sam_passwd *sam_pass;
1167 fstring user_name;
1170 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1171 q_u->uni_user_name[i].uni_str_len));
1173 /* find the user account */
1174 become_root();
1175 sam_pass = get_smb21pwd_entry(user_name, 0);
1176 unbecome_root();
1178 if (sam_pass == NULL)
1180 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1181 rid[i] = 0;
1183 else
1185 rid[i] = sam_pass->user_rid;
1188 #endif
1190 num_rids = 1;
1191 rid[0] = BUILTIN_ALIAS_RID_USERS;
1193 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_NOPROBLEMO);
1195 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1197 return r_u->status;
1199 #endif
1201 /*******************************************************************
1202 _samr_lookup_names
1203 ********************************************************************/
1205 uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1207 uint32 rid[MAX_SAM_ENTRIES];
1208 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1209 int i;
1210 int num_rids = q_u->num_names1;
1211 DOM_SID pol_sid;
1213 r_u->status = NT_STATUS_NOPROBLEMO;
1215 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1217 ZERO_ARRAY(rid);
1218 ZERO_ARRAY(type);
1220 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
1221 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1222 return r_u->status;
1225 if (num_rids > MAX_SAM_ENTRIES) {
1226 num_rids = MAX_SAM_ENTRIES;
1227 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1230 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1232 for (i = 0; i < num_rids; i++) {
1233 fstring name;
1235 r_u->status = NT_STATUS_NONE_MAPPED;
1237 rid [i] = 0xffffffff;
1238 type[i] = SID_NAME_UNKNOWN;
1240 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer, q_u->uni_name[i].uni_str_len));
1242 if(sid_equal(&pol_sid, &global_sam_sid)) {
1243 DOM_SID sid;
1244 if(local_lookup_name(global_myname, name, &sid, &type[i])) {
1245 sid_split_rid( &sid, &rid[i]);
1246 r_u->status = NT_STATUS_NOPROBLEMO;
1251 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1253 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1255 return r_u->status;
1258 /*******************************************************************
1259 _samr_chgpasswd_user
1260 ********************************************************************/
1262 uint32 _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1264 fstring user_name;
1265 fstring wks;
1267 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1269 r_u->status = NT_STATUS_NOPROBLEMO;
1271 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1272 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1274 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1277 * Pass the user through the NT -> unix user mapping
1278 * function.
1281 (void)map_username(user_name);
1284 * Do any UNIX username case mangling.
1286 (void)Get_Pwnam( user_name, True);
1288 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1289 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1290 r_u->status = NT_STATUS_WRONG_PASSWORD;
1292 init_samr_r_chgpasswd_user(r_u, r_u->status);
1294 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1296 return r_u->status;
1299 /*******************************************************************
1300 makes a SAMR_R_LOOKUP_RIDS structure.
1301 ********************************************************************/
1303 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1304 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1306 uint32 i;
1307 UNIHDR *hdr_name=NULL;
1308 UNISTR2 *uni_name=NULL;
1310 *pp_uni_name = NULL;
1311 *pp_hdr_name = NULL;
1313 if (num_names != 0) {
1314 hdr_name = (UNIHDR *)talloc(ctx, sizeof(UNIHDR)*num_names);
1315 if (hdr_name == NULL)
1316 return False;
1318 uni_name = (UNISTR2 *)talloc(ctx,sizeof(UNISTR2)*num_names);
1319 if (uni_name == NULL)
1320 return False;
1323 for (i = 0; i < num_names; i++) {
1324 int len = names[i] != NULL ? strlen(names[i]) : 0;
1325 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1326 init_uni_hdr(&hdr_name[i], len);
1327 init_unistr2(&uni_name[i], names[i], len);
1330 *pp_uni_name = uni_name;
1331 *pp_hdr_name = hdr_name;
1333 return True;
1336 /*******************************************************************
1337 _samr_lookup_rids
1338 ********************************************************************/
1340 uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1342 fstring group_names[MAX_SAM_ENTRIES];
1343 uint32 group_attrs[MAX_SAM_ENTRIES];
1344 UNIHDR *hdr_name = NULL;
1345 UNISTR2 *uni_name = NULL;
1346 DOM_SID pol_sid;
1347 int num_rids = q_u->num_rids1;
1348 int i;
1350 r_u->status = NT_STATUS_NOPROBLEMO;
1352 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1354 /* find the policy handle. open a policy on it. */
1355 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
1356 return NT_STATUS_INVALID_HANDLE;
1358 if (num_rids > MAX_SAM_ENTRIES) {
1359 num_rids = MAX_SAM_ENTRIES;
1360 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1363 r_u->status = NT_STATUS_NONE_MAPPED;
1365 for (i = 0; i < num_rids; i++) {
1366 fstring tmpname;
1367 fstring domname;
1368 DOM_SID sid;
1369 enum SID_NAME_USE type;
1371 group_attrs[i] = SID_NAME_UNKNOWN;
1372 *group_names[i] = '\0';
1374 if (sid_equal(&pol_sid, &global_sam_sid)) {
1375 sid_copy(&sid, &pol_sid);
1376 sid_append_rid(&sid, q_u->rid[i]);
1378 if (lookup_sid(&sid, domname, tmpname, &type)) {
1379 r_u->status = NT_STATUS_NOPROBLEMO;
1380 group_attrs[i] = (uint32)type;
1381 fstrcpy(group_names[i],tmpname);
1386 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1387 return NT_STATUS_NO_MEMORY;
1389 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1391 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1393 return r_u->status;
1396 /*******************************************************************
1397 _api_samr_open_user. Safe - gives out no passwd info.
1398 ********************************************************************/
1400 uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1402 SAM_ACCOUNT *sampass=NULL;
1403 DOM_SID sid;
1404 POLICY_HND domain_pol = q_u->domain_pol;
1405 uint32 user_rid = q_u->user_rid;
1406 POLICY_HND *user_pol = &r_u->user_pol;
1407 struct samr_info *info = NULL;
1408 BOOL ret;
1410 r_u->status = NT_STATUS_NO_PROBLEMO;
1412 /* find the domain policy handle. */
1413 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1414 return NT_STATUS_INVALID_HANDLE;
1416 become_root();
1417 ret=pdb_getsampwrid(sampass, user_rid);
1418 unbecome_root();
1420 /* check that the RID exists in our domain. */
1421 if (ret == False) {
1422 pdb_free_sam(sampass);
1423 return NT_STATUS_NO_SUCH_USER;
1426 samr_clear_sam_passwd(sampass);
1427 pdb_free_sam(sampass);
1429 /* Get the domain SID stored in the domain policy */
1430 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1431 return NT_STATUS_INVALID_HANDLE;
1433 /* append the user's RID to it */
1434 if(!sid_append_rid(&sid, user_rid))
1435 return NT_STATUS_NO_SUCH_USER;
1437 /* associate the user's SID with the new handle. */
1438 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1439 return NT_STATUS_NO_MEMORY;
1441 ZERO_STRUCTP(info);
1442 info->sid = sid;
1444 /* get a (unique) handle. open a policy on it. */
1445 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1446 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1448 return r_u->status;
1451 /*************************************************************************
1452 get_user_info_10. Safe. Only gives out acb bits.
1453 *************************************************************************/
1455 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1457 SAM_ACCOUNT *smbpass=NULL;
1458 BOOL ret;
1460 if (!pdb_rid_is_user(user_rid)) {
1461 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1462 return False;
1465 pdb_init_sam(&smbpass);
1467 become_root();
1468 ret = pdb_getsampwrid(smbpass, user_rid);
1469 unbecome_root();
1471 if (ret==False) {
1472 DEBUG(4,("User 0x%x not found\n", user_rid));
1473 pdb_free_sam(smbpass);
1474 return False;
1477 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1479 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1481 samr_clear_sam_passwd(smbpass);
1482 pdb_free_sam(smbpass);
1484 return True;
1487 /*************************************************************************
1488 get_user_info_12. OK - this is the killer as it gives out password info.
1489 Ensure that this is only allowed on an encrypted connection with a root
1490 user. JRA.
1491 *************************************************************************/
1493 static uint32 get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
1495 SAM_ACCOUNT *smbpass=NULL;
1496 BOOL ret;
1498 if (!p->ntlmssp_auth_validated)
1499 return NT_STATUS_ACCESS_DENIED;
1501 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1502 return NT_STATUS_ACCESS_DENIED;
1505 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1507 pdb_init_sam(&smbpass);
1509 ret = pdb_getsampwrid(smbpass, user_rid);
1511 if (ret == False) {
1512 DEBUG(4, ("User 0x%x not found\n", user_rid));
1513 pdb_free_sam(smbpass);
1514 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1517 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1519 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1520 pdb_free_sam(smbpass);
1521 return NT_STATUS_ACCOUNT_DISABLED;
1524 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1526 pdb_free_sam(smbpass);
1528 return NT_STATUS_NOPROBLEMO;
1531 /*************************************************************************
1532 get_user_info_21
1533 *************************************************************************/
1535 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1537 SAM_ACCOUNT *sampass=NULL;
1538 BOOL ret;
1540 if (!pdb_rid_is_user(user_rid)) {
1541 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1542 return False;
1545 become_root();
1546 ret = pdb_getsampwrid(sampass, user_rid);
1547 unbecome_root();
1549 if (ret == False) {
1550 DEBUG(4,("User 0x%x not found\n", user_rid));
1551 pdb_free_sam(sampass);
1552 return False;
1555 samr_clear_sam_passwd(sampass);
1557 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1559 init_sam_user_info21A(id21, sampass);
1561 pdb_free_sam(sampass);
1563 return True;
1566 /*******************************************************************
1567 _samr_query_userinfo
1568 ********************************************************************/
1570 uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1572 SAM_USERINFO_CTR *ctr;
1573 uint32 rid = 0;
1574 struct samr_info *info = NULL;
1576 r_u->status=NT_STATUS_NO_PROBLEMO;
1578 /* search for the handle */
1579 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1580 return NT_STATUS_INVALID_HANDLE;
1582 /* find the user's rid */
1583 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1584 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1586 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
1588 ctr = (SAM_USERINFO_CTR *)talloc(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1589 if (!ctr)
1590 return NT_STATUS_NO_MEMORY;
1592 ZERO_STRUCTP(ctr);
1594 /* ok! user info levels (lots: see MSDEV help), off we go... */
1595 ctr->switch_value = q_u->switch_value;
1597 switch (q_u->switch_value) {
1598 case 0x10:
1599 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1600 if (ctr->info.id10 == NULL)
1601 return NT_STATUS_NO_MEMORY;
1603 if (!get_user_info_10(ctr->info.id10, rid))
1604 return NT_STATUS_NO_SUCH_USER;
1605 break;
1607 #if 0
1608 /* whoops - got this wrong. i think. or don't understand what's happening. */
1609 case 0x11:
1611 NTTIME expire;
1612 info = (void *)&id11;
1614 expire.low = 0xffffffff;
1615 expire.high = 0x7fffffff;
1617 ctr->info.id = (SAM_USER_INFO_11 *)talloc(p->mem_ctx,
1618 sizeof
1619 (*ctr->
1620 info.
1621 id11));
1622 init_sam_user_info11(ctr->info.id11, &expire,
1623 "BROOKFIELDS$", /* name */
1624 0x03ef, /* user rid */
1625 0x201, /* group rid */
1626 0x0080); /* acb info */
1628 break;
1630 #endif
1632 case 0x12:
1633 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1634 if (ctr->info.id12 == NULL)
1635 return NT_STATUS_NO_MEMORY;
1637 if ((r_u->status = get_user_info_12(p, ctr->info.id12, rid)) != NT_STATUS_NOPROBLEMO)
1638 return r_u->status;
1639 break;
1641 case 21:
1642 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1643 if (ctr->info.id21 == NULL)
1644 return NT_STATUS_NO_MEMORY;
1645 if (!get_user_info_21(ctr->info.id21, rid))
1646 return NT_STATUS_NO_SUCH_USER;
1647 break;
1649 default:
1650 return NT_STATUS_INVALID_INFO_CLASS;
1653 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1655 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1657 return r_u->status;
1660 /*******************************************************************
1661 samr_reply_query_usergroups
1662 ********************************************************************/
1664 uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1666 struct sam_passwd *sam_pass=NULL;
1667 DOM_GID *gids = NULL;
1668 int num_groups = 0;
1669 pstring groups;
1670 uint32 rid;
1671 struct samr_info *info = NULL;
1672 BOOL ret;
1674 r_u->status = NT_STATUS_NO_PROBLEMO;
1676 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1678 /* find the policy handle. open a policy on it. */
1679 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1680 return NT_STATUS_INVALID_HANDLE;
1682 /* find the user's rid */
1683 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1684 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1686 pdb_init_sam(&sam_pass);
1688 become_root();
1689 ret = pdb_getsampwrid(sam_pass, rid);
1690 unbecome_root();
1692 if (ret == False) {
1693 samr_clear_sam_passwd(sam_pass);
1694 return NT_STATUS_NO_SUCH_USER;
1697 get_domain_user_groups(groups, pdb_get_username(sam_pass));
1698 gids = NULL;
1699 num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
1701 /* construct the response. lkclXXXX: gids are not copied! */
1702 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1704 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1706 samr_clear_sam_passwd(sam_pass);
1708 return r_u->status;
1711 /*******************************************************************
1712 _samr_query_dom_info
1713 ********************************************************************/
1715 uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1717 SAM_UNK_CTR *ctr;
1719 if ((ctr = (SAM_UNK_CTR *)talloc(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
1720 return NT_STATUS_NO_MEMORY;
1722 ZERO_STRUCTP(ctr);
1724 r_u->status = NT_STATUS_NO_PROBLEMO;
1726 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1728 /* find the policy handle. open a policy on it. */
1729 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
1730 return NT_STATUS_INVALID_HANDLE;
1732 switch (q_u->switch_value) {
1733 case 0x01:
1734 init_unk_info1(&ctr->info.inf1);
1735 break;
1736 case 0x02:
1737 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1738 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL));
1739 break;
1740 case 0x03:
1741 init_unk_info3(&ctr->info.inf3);
1742 break;
1743 case 0x06:
1744 init_unk_info6(&ctr->info.inf6);
1745 break;
1746 case 0x07:
1747 init_unk_info7(&ctr->info.inf7);
1748 break;
1749 case 0x0c:
1750 init_unk_info12(&ctr->info.inf12);
1751 break;
1752 default:
1753 return NT_STATUS_INVALID_INFO_CLASS;
1756 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_NOPROBLEMO);
1758 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1760 return r_u->status;
1763 /*******************************************************************
1764 _api_samr_create_user
1765 ********************************************************************/
1767 uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
1769 SAM_ACCOUNT *sam_pass=NULL;
1770 fstring mach_acct;
1771 pstring err_str;
1772 pstring msg_str;
1773 int local_flags=0;
1774 DOM_SID sid;
1775 pstring add_script;
1776 POLICY_HND dom_pol = q_u->domain_pol;
1777 UNISTR2 user_account = q_u->uni_name;
1778 uint16 acb_info = q_u->acb_info;
1779 POLICY_HND *user_pol = &r_u->user_pol;
1780 struct samr_info *info = NULL;
1781 BOOL ret;
1783 /* find the policy handle. open a policy on it. */
1784 if (!find_policy_by_hnd(p, &dom_pol, NULL))
1785 return NT_STATUS_INVALID_HANDLE;
1787 /* find the machine account: tell the caller if it exists.
1788 lkclXXXX i have *no* idea if this is a problem or not
1789 or even if you are supposed to construct a different
1790 reply if the account already exists...
1793 fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
1794 strlower(mach_acct);
1796 pdb_init_sam(&sam_pass);
1798 become_root();
1799 ret = pdb_getsampwnam(sam_pass, mach_acct);
1800 unbecome_root();
1801 if (ret == True) {
1802 /* machine account exists: say so */
1803 pdb_free_sam(sam_pass);
1804 return NT_STATUS_USER_EXISTS;
1807 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1808 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1811 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1812 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1813 * that only people with write access to the smbpasswd file will be able
1814 * to create a user. JRA.
1818 * add the user in the /etc/passwd file or the unix authority system.
1819 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1820 * a) local_password_change() checks for us if the /etc/passwd account really exists
1821 * b) smb_create_user() would return an error if the account already exists
1822 * and as it could return an error also if it can't create the account, it would be tricky.
1824 * So we go the easy way, only check after if the account exists.
1825 * JFM (2/3/2001), to clear any possible bad understanding (-:
1828 pstrcpy(add_script, lp_adduser_script());
1830 if(*add_script)
1831 smb_create_user(mach_acct, NULL);
1833 /* add the user in the smbpasswd file or the Samba authority database */
1834 if (!local_password_change(mach_acct, local_flags, NULL, err_str,
1835 sizeof(err_str), msg_str, sizeof(msg_str))) {
1836 DEBUG(0, ("%s\n", err_str));
1837 close_policy_hnd(p, user_pol);
1838 pdb_free_sam(sam_pass);
1839 return NT_STATUS_ACCESS_DENIED;
1842 become_root();
1843 ret = pdb_getsampwnam(sam_pass, mach_acct);
1844 unbecome_root();
1845 if (ret == False) {
1846 /* account doesn't exist: say so */
1847 close_policy_hnd(p, user_pol);
1848 pdb_free_sam(sam_pass);
1849 return NT_STATUS_ACCESS_DENIED;
1852 /* Get the domain SID stored in the domain policy */
1853 if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
1854 close_policy_hnd(p, user_pol);
1855 pdb_free_sam(sam_pass);
1856 return NT_STATUS_INVALID_HANDLE;
1859 /* append the user's RID to it */
1860 if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
1861 close_policy_hnd(p, user_pol);
1862 pdb_free_sam(sam_pass);
1863 return NT_STATUS_NO_SUCH_USER;
1866 /* associate the user's SID with the new handle. */
1867 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL) {
1868 pdb_free_sam(sam_pass);
1869 return NT_STATUS_NO_MEMORY;
1872 ZERO_STRUCTP(info);
1873 info->sid = sid;
1875 /* get a (unique) handle. open a policy on it. */
1876 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
1877 pdb_free_sam(sam_pass);
1878 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1881 r_u->user_rid=sam_pass->user_rid;
1882 r_u->unknown_0 = 0x000703ff;
1884 pdb_free_sam(sam_pass);
1886 return NT_STATUS_NO_PROBLEMO;
1889 /*******************************************************************
1890 samr_reply_connect_anon
1891 ********************************************************************/
1893 uint32 _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
1895 struct samr_info *info = NULL;
1897 /* set up the SAMR connect_anon response */
1899 r_u->status = NT_STATUS_NO_PROBLEMO;
1901 /* associate the user's SID with the new handle. */
1902 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1903 return NT_STATUS_NO_MEMORY;
1905 ZERO_STRUCTP(info);
1906 info->status = q_u->unknown_0;
1908 /* get a (unique) handle. open a policy on it. */
1909 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
1910 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1912 return r_u->status;
1915 /*******************************************************************
1916 samr_reply_connect
1917 ********************************************************************/
1919 uint32 _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
1921 struct samr_info *info = NULL;
1923 DEBUG(5,("_samr_connect: %d\n", __LINE__));
1925 r_u->status = NT_STATUS_NO_PROBLEMO;
1927 /* associate the user's SID with the new handle. */
1928 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1929 return NT_STATUS_NO_MEMORY;
1931 ZERO_STRUCTP(info);
1932 info->status = q_u->access_mask;
1934 /* get a (unique) handle. open a policy on it. */
1935 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
1936 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1938 DEBUG(5,("_samr_connect: %d\n", __LINE__));
1940 return r_u->status;
1943 /**********************************************************************
1944 api_samr_lookup_domain
1945 **********************************************************************/
1947 uint32 _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
1949 r_u->status = NT_STATUS_NO_PROBLEMO;
1951 if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
1952 return NT_STATUS_INVALID_HANDLE;
1954 /* assume the domain name sent is our global_myname and
1955 send global_sam_sid */
1956 init_samr_r_lookup_domain(r_u, &global_sam_sid, r_u->status);
1958 return r_u->status;
1961 /******************************************************************
1962 makes a SAMR_R_ENUM_DOMAINS structure.
1963 ********************************************************************/
1965 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
1966 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
1968 uint32 i;
1969 SAM_ENTRY *sam;
1970 UNISTR2 *uni_name;
1972 DEBUG(5, ("make_enum_domains\n"));
1974 *pp_sam = NULL;
1975 *pp_uni_name = NULL;
1977 if (num_sam_entries == 0)
1978 return True;
1980 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
1981 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
1983 if (sam == NULL || uni_name == NULL)
1984 return False;
1986 for (i = 0; i < num_sam_entries; i++) {
1987 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
1989 init_sam_entry(&sam[i], len, 0);
1990 init_unistr2(&uni_name[i], doms[i], len);
1993 *pp_sam = sam;
1994 *pp_uni_name = uni_name;
1996 return True;
1999 /**********************************************************************
2000 api_samr_enum_domains
2001 **********************************************************************/
2003 uint32 _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2005 uint32 num_entries = 2;
2006 fstring dom[2];
2008 r_u->status = NT_STATUS_NO_PROBLEMO;
2010 fstrcpy(dom[0],global_myworkgroup);
2011 fstrcpy(dom[1],"Builtin");
2013 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2014 return NT_STATUS_NO_MEMORY;
2016 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2018 return r_u->status;
2021 /*******************************************************************
2022 api_samr_open_alias
2023 ********************************************************************/
2025 uint32 _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2027 DOM_SID sid;
2028 POLICY_HND domain_pol = q_u->dom_pol;
2029 uint32 alias_rid = q_u->rid_alias;
2030 POLICY_HND *alias_pol = &r_u->pol;
2031 struct samr_info *info = NULL;
2033 r_u->status = NT_STATUS_NO_PROBLEMO;
2035 /* get the domain policy. */
2036 if (!find_policy_by_hnd(p, &domain_pol, NULL))
2037 return NT_STATUS_INVALID_HANDLE;
2039 /* Get the domain SID stored in the domain policy */
2040 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
2041 return NT_STATUS_INVALID_HANDLE;
2043 /* append the alias' RID to it */
2044 if(!sid_append_rid(&sid, alias_rid))
2045 return NT_STATUS_NO_SUCH_USER;
2048 * we should check if the rid really exist !!!
2049 * JFM.
2052 /* associate the user's SID with the new handle. */
2053 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2054 return NT_STATUS_NO_MEMORY;
2056 ZERO_STRUCTP(info);
2057 info->sid = sid;
2059 /* get a (unique) handle. open a policy on it. */
2060 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2061 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2063 return r_u->status;
2066 /*******************************************************************
2067 set_user_info_10
2068 ********************************************************************/
2070 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2072 SAM_ACCOUNT *pwd =NULL;
2073 BOOL ret;
2075 pdb_init_sam(&pwd);
2077 ret = pdb_getsampwrid(pwd, rid);
2079 if(ret==False) {
2080 pdb_free_sam(pwd);
2081 return False;
2084 if (id10 == NULL) {
2085 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2086 pdb_free_sam(pwd);
2087 return False;
2090 pdb_set_acct_ctrl(pwd, id10->acb_info);
2092 if(!pdb_update_sam_account(pwd, True)) {
2093 pdb_free_sam(pwd);
2094 return False;
2097 pdb_free_sam(pwd);
2099 return True;
2102 /*******************************************************************
2103 set_user_info_12
2104 ********************************************************************/
2106 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2108 SAM_ACCOUNT *pwd = NULL;
2109 BOOL ret;
2111 pdb_init_sam(&pwd);
2113 if(!pdb_getsampwrid(pwd, rid)) {
2114 pdb_free_sam(pwd);
2115 return False;
2118 if (id12 == NULL) {
2119 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2120 pdb_free_sam(pwd);
2121 return False;
2124 pdb_set_lanman_passwd (pwd, id12->lm_pwd);
2125 pdb_set_nt_passwd (pwd, id12->nt_pwd);
2127 if(!pdb_update_sam_account(pwd, True)) {
2128 pdb_free_sam(pwd);
2129 return False;
2132 pdb_free_sam(pwd);
2133 return True;
2136 /*******************************************************************
2137 set_user_info_21
2138 ********************************************************************/
2140 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
2142 SAM_ACCOUNT *pwd = NULL;
2143 SAM_ACCOUNT *new_pwd = NULL;
2145 if (id21 == NULL) {
2146 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2147 return False;
2150 pdb_init_sam(&pwd);
2151 pdb_init_sam(&new_pwd);
2153 if (!pdb_getsampwrid(pwd, rid)) {
2154 pdb_free_sam(pwd);
2155 pdb_free_sam(new_pwd);
2156 return False;
2159 /* we make a copy so that we can modify stuff */
2160 copy_sam_passwd(new_pwd, pwd);
2161 copy_id21_to_sam_passwd(new_pwd, id21);
2164 * The funny part about the previous two calls is
2165 * that pwd still has the password hashes from the
2166 * passdb entry. These have not been updated from
2167 * id21. I don't know if they need to be set. --jerry
2170 /* write the change out */
2171 if(!pdb_update_sam_account(new_pwd, True)) {
2172 pdb_free_sam(pwd);
2173 pdb_free_sam(new_pwd);
2174 return False;
2177 pdb_free_sam(pwd);
2178 pdb_free_sam(new_pwd);
2180 return True;
2183 /*******************************************************************
2184 set_user_info_23
2185 ********************************************************************/
2187 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2189 SAM_ACCOUNT *pwd = NULL;
2190 SAM_ACCOUNT *new_pwd = NULL;
2191 uint8 nt_hash[16];
2192 uint8 lm_hash[16];
2193 pstring buf;
2194 uint32 len;
2195 uint16 acct_ctrl;
2197 if (id23 == NULL) {
2198 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2199 return False;
2202 pdb_init_sam(&pwd);
2203 pdb_init_sam(&new_pwd);
2205 if (pdb_getsampwrid(pwd, rid)) {
2206 pdb_free_sam(pwd);
2207 pdb_free_sam(new_pwd);
2208 return False;
2211 acct_ctrl = pdb_get_acct_ctrl(pwd);
2213 copy_sam_passwd(new_pwd, pwd);
2214 pdb_free_sam(pwd);
2216 copy_id23_to_sam_passwd(new_pwd, id23);
2218 if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len, nt_hash, lm_hash)) {
2219 pdb_free_sam(new_pwd);
2220 return False;
2223 pdb_set_lanman_passwd (new_pwd, lm_hash);
2224 pdb_set_nt_passwd (new_pwd, nt_hash);
2226 /* if it's a trust account, don't update /etc/passwd */
2227 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2228 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2229 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2230 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2231 } else {
2232 /* update the UNIX password */
2233 if (lp_unix_password_sync() )
2234 if(!chgpasswd(pdb_get_username(new_pwd), "", buf, True)) {
2235 pdb_free_sam(new_pwd);
2236 return False;
2240 memset(buf, 0, sizeof(buf));
2242 if(!pdb_update_sam_account(new_pwd, True)) {
2243 pdb_free_sam(new_pwd);
2244 return False;
2247 pdb_free_sam(new_pwd);
2249 return True;
2252 /*******************************************************************
2253 set_user_info_24
2254 ********************************************************************/
2256 static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid)
2258 SAM_ACCOUNT *pwd = NULL;
2259 uchar nt_hash[16];
2260 uchar lm_hash[16];
2261 uint32 len;
2262 pstring buf;
2263 uint16 acct_ctrl;
2265 pdb_init_sam(&pwd);
2267 if (!pdb_getsampwrid(pwd, rid)) {
2268 pdb_free_sam(pwd);
2269 return False;
2272 acct_ctrl = pdb_get_acct_ctrl(pwd);
2274 memset(buf, 0, sizeof(buf));
2276 if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len, nt_hash, lm_hash)) {
2277 pdb_free_sam(pwd);
2278 return False;
2281 pdb_set_lanman_passwd (pwd, lm_hash);
2282 pdb_set_nt_passwd (pwd, nt_hash);
2284 /* if it's a trust account, don't update /etc/passwd */
2285 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2286 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2287 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2288 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2289 } else {
2290 /* update the UNIX password */
2291 if (lp_unix_password_sync())
2292 if(!chgpasswd(pdb_get_username(pwd), "", buf, True)) {
2293 pdb_free_sam(pwd);
2294 return False;
2298 memset(buf, 0, sizeof(buf));
2300 DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
2302 /* update the SAMBA password */
2303 if(!pdb_update_sam_account(pwd, True)) {
2304 pdb_free_sam(pwd);
2305 return False;
2308 pdb_free_sam(pwd);
2310 return True;
2313 /*******************************************************************
2314 samr_reply_set_userinfo
2315 ********************************************************************/
2317 uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2319 uint32 rid = 0x0;
2320 DOM_SID sid;
2321 struct current_user user;
2322 SAM_ACCOUNT *sam_pass=NULL;
2323 unsigned char sess_key[16];
2324 POLICY_HND *pol = &q_u->pol;
2325 uint16 switch_value = q_u->switch_value;
2326 SAM_USERINFO_CTR *ctr = q_u->ctr;
2327 BOOL ret;
2329 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2331 r_u->status = NT_STATUS_NOPROBLEMO;
2333 if (p->ntlmssp_auth_validated) {
2334 memcpy(&user, &p->pipe_user, sizeof(user));
2335 } else {
2336 extern struct current_user current_user;
2337 memcpy(&user, &current_user, sizeof(user));
2340 /* find the policy handle. open a policy on it. */
2341 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2342 return NT_STATUS_INVALID_HANDLE;
2344 sid_split_rid(&sid, &rid);
2346 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2348 if (ctr == NULL) {
2349 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2350 return NT_STATUS_INVALID_INFO_CLASS;
2354 pdb_init_sam(&sam_pass);
2357 * We need the NT hash of the user who is changing the user's password.
2358 * This NT hash is used to generate a "user session key"
2359 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2362 become_root();
2363 ret = pdb_getsampwuid(sam_pass, user.uid);
2364 unbecome_root();
2365 if(ret == False) {
2366 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
2367 pdb_free_sam(sam_pass);
2368 return NT_STATUS_ACCESS_DENIED;
2371 memset(sess_key, '\0', 16);
2372 mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2374 pdb_free_sam(sam_pass);
2376 /* ok! user info levels (lots: see MSDEV help), off we go... */
2377 switch (switch_value) {
2378 case 0x12:
2379 if (!set_user_info_12(ctr->info.id12, rid))
2380 return NT_STATUS_ACCESS_DENIED;
2381 break;
2383 case 24:
2384 SamOEMhash(ctr->info.id24->pass, sess_key, 1);
2385 if (!set_user_info_24(ctr->info.id24, rid))
2386 return NT_STATUS_ACCESS_DENIED;
2387 break;
2389 case 23:
2390 SamOEMhash(ctr->info.id23->pass, sess_key, 1);
2391 if (!set_user_info_23(ctr->info.id23, rid))
2392 return NT_STATUS_ACCESS_DENIED;
2393 break;
2395 default:
2396 return NT_STATUS_INVALID_INFO_CLASS;
2399 return r_u->status;
2402 /*******************************************************************
2403 samr_reply_set_userinfo2
2404 ********************************************************************/
2406 uint32 _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2408 DOM_SID sid;
2409 uint32 rid = 0x0;
2410 SAM_USERINFO_CTR *ctr = q_u->ctr;
2411 POLICY_HND *pol = &q_u->pol;
2412 uint16 switch_value = q_u->switch_value;
2414 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2416 r_u->status = NT_STATUS_NOPROBLEMO;
2418 /* find the policy handle. open a policy on it. */
2419 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2420 return NT_STATUS_INVALID_HANDLE;
2422 sid_split_rid(&sid, &rid);
2424 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2426 if (ctr == NULL) {
2427 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2428 return NT_STATUS_INVALID_INFO_CLASS;
2431 switch_value=ctr->switch_value;
2433 /* ok! user info levels (lots: see MSDEV help), off we go... */
2434 switch (switch_value) {
2435 case 21:
2436 if (!set_user_info_21(ctr->info.id21, rid))
2437 return NT_STATUS_ACCESS_DENIED;
2438 break;
2439 case 16:
2440 if (!set_user_info_10(ctr->info.id10, rid))
2441 return NT_STATUS_ACCESS_DENIED;
2442 break;
2443 case 18:
2444 /* Used by AS/U JRA. */
2445 if (!set_user_info_12(ctr->info.id12, rid))
2446 return NT_STATUS_ACCESS_DENIED;
2447 break;
2448 default:
2449 return NT_STATUS_INVALID_INFO_CLASS;
2452 return r_u->status;
2455 /*********************************************************************
2456 _samr_query_aliasmem
2457 *********************************************************************/
2459 uint32 _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
2461 uint32 *rid=NULL;
2462 int num_rids;
2464 num_rids = 1;
2465 rid=(uint32 *)talloc(p->mem_ctx, num_rids*sizeof(uint32));
2466 if (rid==NULL)
2467 return NT_STATUS_NO_MEMORY;
2469 /* until i see a real useraliases query, we fack one up */
2471 rid[0] = BUILTIN_ALIAS_RID_USERS;
2473 init_samr_r_query_useraliases(r_u, num_rids, rid, NT_STATUS_NO_PROBLEMO);
2475 return NT_STATUS_NO_PROBLEMO;
2479 /*********************************************************************
2480 _samr_query_aliasmem
2481 *********************************************************************/
2483 uint32 _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
2485 int i;
2487 GROUP_MAP map;
2488 int num_uids = 0;
2489 DOM_SID2 *sid;
2490 uid_t *uid=NULL;
2492 DOM_SID alias_sid;
2493 DOM_SID als_sid;
2494 uint32 alias_rid;
2495 fstring alias_sid_str;
2496 DOM_SID temp_sid;
2499 /* find the policy handle. open a policy on it. */
2500 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2501 return NT_STATUS_INVALID_HANDLE;
2503 sid_copy(&als_sid, &alias_sid);
2504 sid_to_string(alias_sid_str, &alias_sid);
2505 sid_split_rid(&alias_sid, &alias_rid);
2507 DEBUG(10, ("sid is %s\n", alias_sid_str));
2509 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
2510 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
2511 if(!get_builtin_group_from_sid(als_sid, &map))
2512 return NT_STATUS_NO_SUCH_ALIAS;
2513 } else {
2514 if (sid_equal(&alias_sid, &global_sam_sid)) {
2515 DEBUG(10, ("lookup on Server SID\n"));
2516 if(!get_local_group_from_sid(als_sid, &map))
2517 return NT_STATUS_NO_SUCH_ALIAS;
2521 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2522 return NT_STATUS_NO_SUCH_ALIAS;
2524 DEBUG(10, ("sid is %s\n", alias_sid_str));
2525 sid = (DOM_SID2 *)talloc(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
2526 if (sid == NULL)
2527 return NT_STATUS_NO_SUCH_ALIAS;
2529 for (i = 0; i < num_uids; i++) {
2530 sid_copy(&temp_sid, &global_sam_sid);
2531 sid_append_rid(&temp_sid, pdb_uid_to_user_rid(uid[i]));
2533 init_dom_sid2(&sid[i], &temp_sid);
2536 DEBUG(10, ("sid is %s\n", alias_sid_str));
2537 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_NO_PROBLEMO);
2539 return NT_STATUS_NOPROBLEMO;
2542 /*********************************************************************
2543 _samr_query_groupmem
2544 *********************************************************************/
2546 uint32 _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
2548 int num_uids = 0;
2549 int i;
2550 DOM_SID group_sid;
2551 uint32 group_rid;
2552 fstring group_sid_str;
2553 uid_t *uid=NULL;
2555 GROUP_MAP map;
2557 uint32 *rid=NULL;
2558 uint32 *attr=NULL;
2561 /* find the policy handle. open a policy on it. */
2562 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid))
2563 return NT_STATUS_INVALID_HANDLE;
2565 /* todo: change to use sid_compare_front */
2567 sid_split_rid(&group_sid, &group_rid);
2568 sid_to_string(group_sid_str, &group_sid);
2569 DEBUG(10, ("sid is %s\n", group_sid_str));
2571 /* can we get a query for an SID outside our domain ? */
2572 if (!sid_equal(&group_sid, &global_sam_sid))
2573 return NT_STATUS_NO_SUCH_GROUP;
2575 sid_append_rid(&group_sid, group_rid);
2576 DEBUG(10, ("lookup on Domain SID\n"));
2578 if(!get_domain_group_from_sid(group_sid, &map))
2579 return NT_STATUS_NO_SUCH_GROUP;
2581 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2582 return NT_STATUS_NO_SUCH_GROUP;
2584 rid=talloc(p->mem_ctx, sizeof(uint32)*num_uids);
2585 attr=talloc(p->mem_ctx, sizeof(uint32)*num_uids);
2587 if (rid==NULL || attr==NULL)
2588 return NT_STATUS_NO_MEMORY;
2590 for (i=0; i<num_uids; i++) {
2591 rid[i]=pdb_uid_to_user_rid(uid[i]);
2592 attr[i] = SID_NAME_USER;
2595 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_NOPROBLEMO);
2597 return NT_STATUS_NOPROBLEMO;
2600 /*********************************************************************
2601 _samr_add_aliasmem
2602 *********************************************************************/
2604 uint32 _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
2606 DOM_SID alias_sid;
2607 fstring alias_sid_str;
2608 uid_t uid;
2609 struct passwd *pwd;
2610 struct group *grp;
2611 fstring grp_name;
2612 uint32 rid;
2613 GROUP_MAP map;
2615 /* Find the policy handle. Open a policy on it. */
2616 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2617 return NT_STATUS_INVALID_HANDLE;
2619 sid_to_string(alias_sid_str, &alias_sid);
2620 DEBUG(10, ("sid is %s\n", alias_sid_str));
2622 if (sid_compare(&alias_sid, &global_sam_sid)>0) {
2623 DEBUG(10, ("adding member on Server SID\n"));
2624 if(!get_local_group_from_sid(alias_sid, &map))
2625 return NT_STATUS_NO_SUCH_ALIAS;
2627 } else {
2628 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
2629 DEBUG(10, ("adding member on BUILTIN SID\n"));
2630 if( !get_builtin_group_from_sid(alias_sid, &map))
2631 return NT_STATUS_NO_SUCH_ALIAS;
2633 } else
2634 return NT_STATUS_NO_SUCH_ALIAS;
2637 sid_split_rid(&q_u->sid.sid, &rid);
2638 uid=pdb_user_rid_to_uid(rid);
2640 if ((pwd=getpwuid(uid)) == NULL)
2641 return NT_STATUS_NO_SUCH_USER;
2643 if ((grp=getgrgid(map.gid)) == NULL)
2644 return NT_STATUS_NO_SUCH_ALIAS;
2646 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2647 fstrcpy(grp_name, grp->gr_name);
2649 /* if the user is already in the group */
2650 if(user_in_group_list(pwd->pw_name, grp_name))
2651 return NT_STATUS_MEMBER_IN_ALIAS;
2654 * ok, the group exist, the user exist, the user is not in the group,
2655 * we can (finally) add it to the group !
2657 smb_add_user_group(grp_name, pwd->pw_name);
2659 /* check if the user has been added then ... */
2660 if(!user_in_group_list(pwd->pw_name, grp_name))
2661 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
2663 return NT_STATUS_NOPROBLEMO;
2666 /*********************************************************************
2667 _samr_del_aliasmem
2668 *********************************************************************/
2670 uint32 _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
2672 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2673 return False;
2676 /*********************************************************************
2677 _samr_add_groupmem
2678 *********************************************************************/
2680 uint32 _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
2682 DOM_SID group_sid;
2683 fstring group_sid_str;
2684 struct passwd *pwd;
2685 struct group *grp;
2686 fstring grp_name;
2687 GROUP_MAP map;
2689 /* Find the policy handle. Open a policy on it. */
2690 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2691 return NT_STATUS_INVALID_HANDLE;
2693 sid_to_string(group_sid_str, &group_sid);
2694 DEBUG(10, ("sid is %s\n", group_sid_str));
2696 if (sid_compare(&group_sid, &global_sam_sid)<=0)
2697 return NT_STATUS_NO_SUCH_GROUP;
2699 DEBUG(10, ("lookup on Domain SID\n"));
2701 if(!get_domain_group_from_sid(group_sid, &map))
2702 return NT_STATUS_NO_SUCH_GROUP;
2704 if ((pwd=getpwuid(pdb_user_rid_to_uid(q_u->rid))) ==NULL)
2705 return NT_STATUS_NO_SUCH_USER;
2707 if ((grp=getgrgid(map.gid)) == NULL)
2708 return NT_STATUS_NO_SUCH_GROUP;
2710 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2711 fstrcpy(grp_name, grp->gr_name);
2713 /* if the user is already in the group */
2714 if(user_in_group_list(pwd->pw_name, grp_name))
2715 return NT_STATUS_MEMBER_IN_GROUP;
2718 * ok, the group exist, the user exist, the user is not in the group,
2720 * we can (finally) add it to the group !
2723 smb_add_user_group(grp_name, pwd->pw_name);
2725 /* check if the user has been added then ... */
2726 if(!user_in_group_list(pwd->pw_name, grp_name))
2727 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
2729 return NT_STATUS_NOPROBLEMO;
2732 /*********************************************************************
2733 _samr_del_groupmem
2734 *********************************************************************/
2736 uint32 _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
2738 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2739 return False;
2742 /*********************************************************************
2743 _samr_delete_dom_user
2744 *********************************************************************/
2746 uint32 _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
2748 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2749 return False;
2752 /*********************************************************************
2753 _samr_delete_dom_group
2754 *********************************************************************/
2756 uint32 _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
2758 DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
2759 return False;
2762 /*********************************************************************
2763 _samr_delete_dom_alias
2764 *********************************************************************/
2766 uint32 _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
2768 DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
2769 return False;
2772 /*********************************************************************
2773 _samr_create_dom_group
2774 *********************************************************************/
2776 uint32 _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
2778 DOM_SID dom_sid;
2779 DOM_SID info_sid;
2780 fstring name;
2781 fstring sid_string;
2782 struct group *grp;
2783 struct samr_info *info;
2785 /* Find the policy handle. Open a policy on it. */
2786 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid))
2787 return NT_STATUS_INVALID_HANDLE;
2789 if (!sid_equal(&dom_sid, &global_sam_sid))
2790 return NT_STATUS_ACCESS_DENIED;
2792 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2794 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
2796 /* check if group already exist */
2797 if ((grp=getgrnam(name)) != NULL)
2798 return NT_STATUS_GROUP_EXISTS;
2800 /* we can create the UNIX group */
2801 smb_create_group(name);
2803 /* check if the group has been successfully created */
2804 if ((grp=getgrnam(name)) == NULL)
2805 return NT_STATUS_ACCESS_DENIED;
2807 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
2809 /* add the group to the mapping table */
2810 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, SE_PRIV_NONE))
2811 return NT_STATUS_ACCESS_DENIED;
2813 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2814 return NT_STATUS_NO_MEMORY;
2816 ZERO_STRUCTP(info);
2818 sid_copy(&info_sid, &global_sam_sid);
2819 sid_append_rid(&info->sid, r_u->rid);
2820 sid_to_string(sid_string, &info->sid);
2822 /* get a (unique) handle. open a policy on it. */
2823 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
2824 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2826 return NT_STATUS_NOPROBLEMO;
2829 /*********************************************************************
2830 _samr_create_dom_alias
2831 *********************************************************************/
2833 uint32 _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
2835 DOM_SID dom_sid;
2836 fstring name;
2837 fstring sid_string;
2838 struct group *grp;
2839 struct samr_info *info;
2841 /* Find the policy handle. Open a policy on it. */
2842 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid))
2843 return NT_STATUS_INVALID_HANDLE;
2845 if (!sid_equal(&dom_sid, &global_sam_sid))
2846 return NT_STATUS_ACCESS_DENIED;
2848 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2850 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
2852 /* check if group already exists */
2853 if ( (grp=getgrnam(name)) != NULL)
2854 return NT_STATUS_GROUP_EXISTS;
2856 /* we can create the UNIX group */
2857 smb_create_group(name);
2859 /* check if the group has been successfully created */
2860 if ((grp=getgrnam(name)) == NULL)
2861 return NT_STATUS_ACCESS_DENIED;
2863 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
2865 /* add the group to the mapping table */
2866 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, NULL, NULL, SE_PRIV_NONE))
2867 return NT_STATUS_ACCESS_DENIED;
2869 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2870 return NT_STATUS_NO_MEMORY;
2872 ZERO_STRUCTP(info);
2874 sid_copy(&info->sid, &global_sam_sid);
2875 sid_append_rid(&info->sid, r_u->rid);
2876 sid_to_string(sid_string, &info->sid);
2878 /* get a (unique) handle. open a policy on it. */
2879 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
2880 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2882 return NT_STATUS_NOPROBLEMO;
2885 /*********************************************************************
2886 _samr_query_groupinfo
2888 sends the name/comment pair of a domain group
2889 level 1 send also the number of users of that group
2890 *********************************************************************/
2892 uint32 _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
2894 DOM_SID group_sid;
2895 GROUP_MAP map;
2896 uid_t *uid;
2897 int num_uids=0;
2898 GROUP_INFO_CTR *ctr;
2900 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2901 return NT_STATUS_INVALID_HANDLE;
2903 if (!get_domain_group_from_sid(group_sid, &map))
2904 return NT_STATUS_INVALID_HANDLE;
2906 ctr=(GROUP_INFO_CTR *)talloc(p->mem_ctx, sizeof(GROUP_INFO_CTR));
2907 if (ctr==NULL)
2908 return NT_STATUS_NO_MEMORY;
2910 switch (q_u->switch_level) {
2911 case 1:
2912 ctr->switch_value1 = 1;
2913 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2914 return NT_STATUS_NO_SUCH_GROUP;
2915 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
2916 safe_free(uid);
2917 break;
2918 case 4:
2919 ctr->switch_value1 = 4;
2920 init_samr_group_info4(&ctr->group.info4, map.comment);
2921 break;
2922 default:
2923 return NT_STATUS_INVALID_INFO_CLASS;
2926 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_NO_PROBLEMO);
2928 return NT_STATUS_NO_PROBLEMO;
2931 /*********************************************************************
2932 _samr_set_groupinfo
2934 update a domain group's comment.
2935 *********************************************************************/
2937 uint32 _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
2939 DOM_SID group_sid;
2940 GROUP_MAP map;
2941 GROUP_INFO_CTR *ctr;
2943 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2944 return NT_STATUS_INVALID_HANDLE;
2946 if (!get_domain_group_from_sid(group_sid, &map))
2947 return NT_STATUS_NO_SUCH_GROUP;
2949 ctr=q_u->ctr;
2951 switch (ctr->switch_value1) {
2952 case 1:
2953 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
2954 break;
2955 case 4:
2956 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
2957 break;
2958 default:
2959 return NT_STATUS_INVALID_INFO_CLASS;
2962 if(!add_mapping_entry(&map, TDB_REPLACE))
2963 return NT_STATUS_NO_SUCH_GROUP;
2965 return NT_STATUS_NO_PROBLEMO;
2968 /*********************************************************************
2969 _samr_get_dom_pwinfo
2970 *********************************************************************/
2972 uint32 _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
2974 /* Actually, returning zeros here works quite well :-). */
2975 return NT_STATUS_NOPROBLEMO;
2978 /*********************************************************************
2979 _samr_open_group
2980 *********************************************************************/
2982 uint32 _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
2984 DOM_SID sid;
2985 GROUP_MAP map;
2986 struct samr_info *info;
2987 fstring sid_string;
2989 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
2990 return NT_STATUS_INVALID_HANDLE;
2992 /* this should not be hard-coded like this */
2993 if (!sid_equal(&sid, &global_sam_sid))
2994 return NT_STATUS_ACCESS_DENIED;
2996 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2997 return NT_STATUS_NO_MEMORY;
2999 ZERO_STRUCTP(info);
3001 sid_copy(&info->sid, &global_sam_sid);
3002 sid_append_rid(&info->sid, q_u->rid_group);
3003 sid_to_string(sid_string, &info->sid);
3005 DEBUG(10, ("Opening SID: %s\n", sid_string));
3007 /* check if that group really exists */
3008 if (!get_domain_group_from_sid(info->sid, &map))
3009 return NT_STATUS_NO_SUCH_USER;
3011 /* get a (unique) handle. open a policy on it. */
3012 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3013 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3015 return NT_STATUS_NO_PROBLEMO;
3018 /*********************************************************************
3019 _samr_unknown_2d
3020 *********************************************************************/
3022 uint32 _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
3024 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
3025 return False;