converted the passdb smbpasswd implementation to using talloc
[Samba/gbeck.git] / source / rpc_server / srv_samr_nt.c
blob7054f85ff97dd5c2fd0292cb284bb8c980cdc682
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 if (sam_pass->lm_pw)
83 memset(sam_pass->lm_pw, '\0', 16);
84 if (sam_pass->nt_pw)
85 memset(sam_pass->nt_pw, '\0', 16);
88 /*******************************************************************
89 This next function should be replaced with something that
90 dynamically returns the correct user info..... JRA.
91 ********************************************************************/
93 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
94 int *total_entries, int *num_entries,
95 int max_num_entries, uint16 acb_mask)
97 SAM_ACCOUNT *pwd = NULL;
99 (*num_entries) = 0;
100 (*total_entries) = 0;
102 if (pw_buf == NULL)
103 return False;
105 if (!pdb_setsampwent(False)) {
106 DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
107 return False;
110 while (((pwd = pdb_getsampwent()) != NULL) && (*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...
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)++;
140 else
141 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
143 (*total_entries)++;
146 pdb_endsampwent();
148 return (*num_entries) > 0;
151 static BOOL jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
152 int *total_entries, uint32 *num_entries,
153 int max_num_entries, uint16 acb_mask)
155 SAM_ACCOUNT *pwd = NULL;
157 *num_entries = 0;
158 *total_entries = 0;
160 if (pw_buf == NULL)
161 return False;
163 if (!pdb_setsampwent(False)) {
164 DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
165 return False;
168 while (((pwd = pdb_getsampwent()) != NULL) && (*num_entries) < max_num_entries) {
169 int user_name_len;
170 int full_name_len;
172 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask))
173 continue;
175 if (start_idx > 0) {
176 /* skip the requested number of entries.
177 not very efficient, but hey...
179 start_idx--;
180 continue;
183 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
185 user_name_len = strlen(pdb_get_username(pwd));
186 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
187 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
189 full_name_len = strlen(pdb_get_fullname(pwd));
190 init_unistr2(&pw_buf[(*num_entries)].uni_full_name, pdb_get_fullname(pwd), full_name_len);
191 init_uni_hdr(&pw_buf[(*num_entries)].hdr_full_name, full_name_len);
193 pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
194 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
196 /* Now check if the NT compatible password is available. */
197 if (pdb_get_nt_passwd(pwd))
198 memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
200 pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
202 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries),
203 pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
204 (*num_entries)++;
207 pdb_endsampwent();
209 *total_entries = *num_entries;
210 return True;
213 /*******************************************************************
214 This function uses the username map file and tries to map a UNIX
215 user name to an DOS name. (Sort of the reverse of the
216 map_username() function.) Since more than one DOS name can map
217 to the UNIX name, to reverse the mapping you have to specify
218 which corresponding DOS name you want; that's where the name_idx
219 parameter comes in. Returns the string requested or NULL if it
220 fails or can't complete the request for any reason. This doesn't
221 handle group names (starting with '@') or names starting with
222 '+' or '&'. If they are encountered, they are skipped.
223 ********************************************************************/
225 static char *unmap_unixname(char *unix_user_name, int name_idx)
227 char *mapfile = lp_username_map();
228 char **lines;
229 static pstring tok;
230 int i;
232 if (!*unix_user_name) return NULL;
233 if (!*mapfile) return NULL;
235 lines = file_lines_load(mapfile, NULL,False);
236 if (!lines) {
237 DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
238 return NULL;
241 DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
243 for (i=0; lines[i]; i++) {
244 char *unixname = lines[i];
245 char *dosname = strchr(unixname,'=');
247 if (!dosname)
248 continue;
250 *dosname++ = 0;
252 while (isspace(*unixname))
253 unixname++;
254 if ('!' == *unixname) {
255 unixname++;
256 while (*unixname && isspace(*unixname))
257 unixname++;
260 if (!*unixname || strchr("#;",*unixname))
261 continue;
263 if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
264 continue;
266 /* We have matched the UNIX user name */
268 while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
269 if (!strchr("@&+", *tok)) {
270 name_idx--;
271 if (name_idx < 0 ) {
272 break;
277 if (name_idx >= 0) {
278 DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
279 file_lines_free(lines);
280 return NULL;
281 } else {
282 file_lines_free(lines);
283 return tok;
287 DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
288 file_lines_free(lines);
289 return NULL;
292 /*******************************************************************
293 This function sets up a list of users taken from the list of
294 users that UNIX knows about, as well as all the user names that
295 Samba maps to a valid UNIX user name. (This should work with
296 /etc/passwd or NIS.)
297 ********************************************************************/
299 static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
300 int start_idx,
301 int *total_entries, int *num_entries,
302 int max_num_entries,
303 uint16 acb_mask)
305 static struct passwd *pwd = NULL;
306 static uint32 pw_rid;
307 static BOOL orig_done = False;
308 static int current_idx = 0;
309 static int mapped_idx = 0;
310 char *sep;
312 DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
314 (*num_entries) = 0;
315 (*total_entries) = 0;
317 /* Skip all this stuff if we're in appliance mode */
319 if (lp_hide_local_users()) goto done;
321 if (pw_buf == NULL) return False;
323 if (current_idx == 0) {
324 sys_setpwent();
327 /* These two cases are inefficient, but should be called very rarely */
328 /* they are the cases where the starting index isn't picking up */
329 /* where we left off last time. It is efficient when it starts over */
330 /* at zero though. */
331 if (start_idx > current_idx) {
332 /* We aren't far enough; advance to start_idx */
333 while (current_idx <= start_idx) {
334 char *unmap_name;
336 if(!orig_done) {
337 if ((pwd = sys_getpwent()) == NULL) break;
338 current_idx++;
339 orig_done = True;
342 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
343 (current_idx < start_idx)) {
344 current_idx++;
345 mapped_idx++;
348 if (unmap_name == NULL) {
349 orig_done = False;
350 mapped_idx = 0;
353 } else if (start_idx < current_idx) {
354 /* We are already too far; start over and advance to start_idx */
355 sys_endpwent();
356 sys_setpwent();
357 current_idx = 0;
358 mapped_idx = 0;
359 orig_done = False;
360 while (current_idx < start_idx) {
361 char *unmap_name;
363 if(!orig_done) {
364 if ((pwd = sys_getpwent()) == NULL) break;
365 current_idx++;
366 orig_done = True;
369 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
370 (current_idx < start_idx)) {
371 current_idx++;
372 mapped_idx++;
375 if (unmap_name == NULL) {
376 orig_done = False;
377 mapped_idx = 0;
382 sep = lp_winbind_separator();
384 /* now current_idx == start_idx */
385 while ((*num_entries) < max_num_entries) {
386 int user_name_len;
387 char *unmap_name;
389 /* This does the original UNIX user itself */
390 if(!orig_done) {
391 if ((pwd = sys_getpwent()) == NULL) break;
393 /* Don't enumerate winbind users as they are not local */
395 if (strchr(pwd->pw_name, *sep) != NULL) {
396 continue;
399 user_name_len = strlen(pwd->pw_name);
401 /* skip the trust account stored in the /etc/passwd file */
402 if (pwd->pw_name[user_name_len-1]=='$')
403 continue;
405 pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
406 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
407 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pwd->pw_name, user_name_len);
408 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
409 pw_buf[(*num_entries)].user_rid = pw_rid;
410 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
412 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
414 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
416 (*num_entries)++;
417 (*total_entries)++;
418 current_idx++;
419 orig_done = True;
422 /* This does all the user names that map to the UNIX user */
423 while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
424 (*num_entries < max_num_entries)) {
425 user_name_len = strlen(unmap_name);
426 ZERO_STRUCTP(&pw_buf[(*num_entries)]);
427 init_unistr2(&pw_buf[(*num_entries)].uni_user_name, unmap_name, user_name_len);
428 init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
429 pw_buf[(*num_entries)].user_rid = pw_rid;
430 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
432 pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
434 DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
436 (*num_entries)++;
437 (*total_entries)++;
438 current_idx++;
439 mapped_idx++;
442 if (unmap_name == NULL) {
443 /* done with 'aliases', go on to next UNIX user */
444 orig_done = False;
445 mapped_idx = 0;
449 if (pwd == NULL) {
450 /* totally done, reset everything */
451 sys_endpwent();
452 current_idx = 0;
453 mapped_idx = 0;
456 done:
457 return (*num_entries) > 0;
460 /*******************************************************************
461 _samr_close_hnd
462 ********************************************************************/
464 uint32 _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
466 r_u->status = NT_STATUS_NOPROBLEMO;
468 /* close the policy handle */
469 if (!close_policy_hnd(p, &q_u->pol))
470 return NT_STATUS_OBJECT_NAME_INVALID;
472 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
474 return r_u->status;
477 /*******************************************************************
478 samr_reply_open_domain
479 ********************************************************************/
481 uint32 _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
483 struct samr_info *info;
485 r_u->status = NT_STATUS_NOPROBLEMO;
487 /* find the connection policy handle. */
488 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
489 return NT_STATUS_INVALID_HANDLE;
491 /* associate the domain SID with the (unique) handle. */
492 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
493 return NT_STATUS_NO_MEMORY;
495 ZERO_STRUCTP(info);
496 info->sid = q_u->dom_sid.sid;
498 /* get a (unique) handle. open a policy on it. */
499 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
500 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
502 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
504 return r_u->status;
507 static uint32 get_lsa_policy_samr_rid(struct samr_info *info)
509 if (!info) {
510 DEBUG(3,("Error getting policy\n"));
511 return 0xffffffff;
514 return info->sid.sub_auths[info->sid.num_auths-1];
517 /*******************************************************************
518 _samr_get_usrdom_pwinfo
519 ********************************************************************/
521 uint32 _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
523 struct samr_info *info = NULL;
525 r_u->status = NT_STATUS_NOPROBLEMO;
527 /* find the policy handle. open a policy on it. */
528 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info)) {
529 return NT_STATUS_INVALID_HANDLE;
532 /* find the user's rid */
533 if (get_lsa_policy_samr_rid(info) == 0xffffffff) {
534 return NT_STATUS_OBJECT_TYPE_MISMATCH;
537 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_NOPROBLEMO);
539 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
541 return r_u->status;
544 /*******************************************************************
545 samr_make_usr_obj_sd
546 ********************************************************************/
548 static uint32 samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
550 extern DOM_SID global_sid_World;
551 DOM_SID adm_sid;
552 DOM_SID act_sid;
554 SEC_ACE ace[4];
555 SEC_ACCESS mask;
557 SEC_ACL *psa = NULL;
558 SEC_DESC *psd = NULL;
559 size_t sd_size;
561 sid_copy(&adm_sid, &global_sid_Builtin);
562 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
564 sid_copy(&act_sid, &global_sid_Builtin);
565 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
567 init_sec_access(&mask, 0x2035b);
568 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
570 init_sec_access(&mask, 0xf07ff);
571 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
572 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
574 init_sec_access(&mask,0x20044);
575 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
577 if((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
578 return NT_STATUS_NO_MEMORY;
580 if((psd = make_sec_desc(ctx, SEC_DESC_REVISION, NULL, NULL, NULL, psa, &sd_size)) == NULL)
581 return NT_STATUS_NO_MEMORY;
583 if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
584 return NT_STATUS_NO_MEMORY;
586 return NT_STATUS_NOPROBLEMO;
589 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
591 struct samr_info *info = NULL;
593 /* find the policy handle. open a policy on it. */
594 if (!find_policy_by_hnd(p, pol, (void **)&info))
595 return False;
597 if (!info)
598 return False;
600 *sid = info->sid;
601 return True;
604 /*******************************************************************
605 _samr_query_sec_obj
606 ********************************************************************/
608 uint32 _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
610 DOM_SID pol_sid;
612 r_u->status = NT_STATUS_NOPROBLEMO;
614 /* Get the SID. */
616 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid))
617 return NT_STATUS_INVALID_HANDLE;
619 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
621 if (r_u->status == NT_STATUS_NOPROBLEMO)
622 r_u->ptr = 1;
624 return r_u->status;
627 /*******************************************************************
628 makes a SAM_ENTRY / UNISTR2* structure from a user list.
629 ********************************************************************/
631 static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
632 uint32 num_sam_entries, SAM_USER_INFO_21 *pass)
634 uint32 i;
635 SAM_ENTRY *sam;
636 UNISTR2 *uni_name;
638 *sam_pp = NULL;
639 *uni_name_pp = NULL;
641 if (num_sam_entries == 0)
642 return;
644 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
646 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
648 if (sam == NULL || uni_name == NULL) {
649 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
650 return;
653 for (i = 0; i < num_sam_entries; i++) {
654 int len = pass[i].uni_user_name.uni_str_len;
656 init_sam_entry(&sam[i], len, pass[i].user_rid);
657 copy_unistr2(&uni_name[i], &pass[i].uni_user_name);
660 *sam_pp = sam;
661 *uni_name_pp = uni_name;
664 /*******************************************************************
665 samr_reply_enum_dom_users
666 ********************************************************************/
668 uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
670 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
671 int num_entries = 0;
672 int total_entries = 0;
673 BOOL ret;
675 r_u->status = NT_STATUS_NOPROBLEMO;
677 /* find the policy handle. open a policy on it. */
678 if (!find_policy_by_hnd(p, &q_u->pol, NULL))
679 return NT_STATUS_INVALID_HANDLE;
681 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
683 become_root();
684 ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
685 MAX_SAM_ENTRIES, q_u->acb_mask);
686 unbecome_root();
688 if (!ret)
689 return NT_STATUS_ACCESS_DENIED;
691 samr_clear_passwd_fields(pass, num_entries);
694 * Note from JRA. total_entries is not being used here. Currently if there is a
695 * large user base then it looks like NT will enumerate until get_sampwd_entries
696 * returns False due to num_entries being zero. This will cause an access denied
697 * return. I don't think this is right and needs further investigation. Note that
698 * this is also the same in the TNG code (I don't think that has been tested with
699 * a very large user list as MAX_SAM_ENTRIES is set to 600).
701 * I also think that one of the 'num_entries' return parameters is probably
702 * the "max entries" parameter - but in the TNG code they're all currently set to the same
703 * value (again I think this is wrong).
706 make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, num_entries, pass);
708 init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_entries, num_entries);
710 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
712 return r_u->status;
715 /*******************************************************************
716 makes a SAM_ENTRY / UNISTR2* structure from a group list.
717 ********************************************************************/
719 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
720 uint32 num_sam_entries, DOMAIN_GRP *grp)
722 uint32 i;
723 SAM_ENTRY *sam;
724 UNISTR2 *uni_name;
726 *sam_pp = NULL;
727 *uni_name_pp = NULL;
729 if (num_sam_entries == 0)
730 return;
732 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
734 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
736 if (sam == NULL || uni_name == NULL) {
737 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
738 return;
741 for (i = 0; i < num_sam_entries; i++) {
743 * JRA. I think this should include the null. TNG does not.
745 int len = strlen(grp[i].name)+1;
747 init_sam_entry(&sam[i], len, grp[i].rid);
748 init_unistr2(&uni_name[i], grp[i].name, len);
751 *sam_pp = sam;
752 *uni_name_pp = uni_name;
755 /*******************************************************************
756 Get the group entries - similar to get_sampwd_entries().
757 ********************************************************************/
759 static BOOL get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
760 uint32 *p_num_entries, uint32 max_entries)
762 fstring sid_str;
763 fstring sam_sid_str;
764 uint32 num_entries = 0;
766 sid_to_string(sid_str, sid);
767 sid_to_string(sam_sid_str, &global_sam_sid);
769 *p_num_entries = 0;
771 /* well-known aliases */
772 if (strequal(sid_str, "S-1-5-32")) {
773 char *name;
774 while (!lp_hide_local_users() &&
775 num_entries < max_entries &&
776 ((name = builtin_alias_rids[num_entries].name) != NULL)) {
778 fstrcpy(d_grp[num_entries].name, name);
779 d_grp[num_entries].rid = builtin_alias_rids[num_entries].rid;
781 num_entries++;
783 } else if (strequal(sid_str, sam_sid_str) && !lp_hide_local_users()) {
784 char *name;
785 char *sep;
786 struct group *grp;
788 sep = lp_winbind_separator();
790 /* local aliases */
791 /* we return the UNIX groups here. This seems to be the right */
792 /* thing to do, since NT member servers return their local */
793 /* groups in the same situation. */
794 setgrent();
796 while (num_entries < max_entries && ((grp = getgrent()) != NULL)) {
797 int i;
798 uint32 trid;
799 name = grp->gr_name;
801 DEBUG(10,("get_group_alias_entries: got group %s\n", name ));
803 /* Don't return winbind groups as they are not local! */
805 if (strchr(name, *sep) != NULL) {
806 DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", name ));
807 continue;
810 /* Don't return user private groups... */
811 if (Get_Pwnam(name, False) != 0) {
812 DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", name ));
813 continue;
816 trid = pdb_gid_to_group_rid(grp->gr_gid);
817 for( i = 0; i < num_entries; i++)
818 if ( d_grp[i].rid == trid ) break;
820 if ( i < num_entries )
821 continue; /* rid was there, dup! */
823 /* JRA - added this for large group db enumeration... */
825 if (start_idx > 0) {
826 /* skip the requested number of entries.
827 not very efficient, but hey...
829 start_idx--;
830 continue;
833 fstrcpy(d_grp[num_entries].name, name);
834 d_grp[num_entries].rid = trid;
835 num_entries++;
838 endgrent();
841 *p_num_entries = num_entries;
843 return True;
846 /*******************************************************************
847 Get the group entries - similar to get_sampwd_entries().
848 ********************************************************************/
850 static BOOL get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
851 uint32 *p_num_entries, uint32 max_entries)
853 fstring sid_str;
854 fstring sam_sid_str;
855 uint32 num_entries = 0;
856 fstring name="Domain Admins";
857 fstring comment="Just to make it work !";
859 sid_to_string(sid_str, sid);
860 sid_to_string(sam_sid_str, &global_sam_sid);
862 *p_num_entries = 0;
864 fstrcpy(d_grp[0].name, name);
865 fstrcpy(d_grp[0].comment, comment);
866 d_grp[0].rid = DOMAIN_GROUP_RID_ADMINS;
867 d_grp[0].attr=SID_NAME_DOM_GRP;
869 fstrcpy(d_grp[1].name, "Domain Users");
870 fstrcpy(d_grp[1].comment, "Just to make it work !");
871 d_grp[1].rid = DOMAIN_GROUP_RID_USERS;
872 d_grp[1].attr=SID_NAME_DOM_GRP;
874 num_entries = 2;
876 *p_num_entries = num_entries;
878 return True;
881 /*******************************************************************
882 samr_reply_enum_dom_groups
883 Only reply with one group - domain admins. This must be fixed for
884 a real PDC. JRA.
885 ********************************************************************/
887 uint32 _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
889 DOMAIN_GRP grp[2];
890 uint32 num_entries;
891 DOM_SID sid;
893 r_u->status = NT_STATUS_NOPROBLEMO;
895 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
896 return NT_STATUS_INVALID_HANDLE;
898 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
900 get_group_domain_entries(grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
902 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
904 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
906 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
908 return r_u->status;
912 /*******************************************************************
913 samr_reply_enum_dom_aliases
914 ********************************************************************/
916 uint32 _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
918 DOMAIN_GRP grp[MAX_SAM_ENTRIES];
919 uint32 num_entries = 0;
920 fstring sid_str;
921 DOM_SID sid;
923 r_u->status = NT_STATUS_NOPROBLEMO;
925 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
926 return NT_STATUS_INVALID_HANDLE;
928 sid_to_string(sid_str, &sid);
929 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
931 if (!get_group_alias_entries(grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))
932 return NT_STATUS_ACCESS_DENIED;
934 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
936 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx, num_entries);
938 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
940 return r_u->status;
943 /*******************************************************************
944 samr_reply_query_dispinfo
945 ********************************************************************/
947 uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
949 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
950 DOMAIN_GRP grps[MAX_SAM_ENTRIES];
951 uint16 acb_mask = ACB_NORMAL;
952 uint32 num_entries = 0;
953 int orig_num_entries = 0;
954 int total_entries = 0;
955 uint32 data_size = 0;
956 DOM_SID sid;
957 BOOL ret;
958 SAM_DISPINFO_CTR *ctr;
960 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
962 r_u->status = NT_STATUS_NOPROBLEMO;
964 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
965 return NT_STATUS_INVALID_HANDLE;
967 /* decide how many entries to get depending on the max_entries
968 and max_size passed by client */
970 if(q_u->max_entries > MAX_SAM_ENTRIES)
971 q_u->max_entries = MAX_SAM_ENTRIES;
973 /* Get what we need from the password database */
974 switch (q_u->switch_level) {
975 case 0x2:
976 acb_mask = ACB_WSTRUST;
977 /* Fall through */
978 case 0x1:
979 case 0x4:
980 become_root();
981 #if 0
982 ret = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
983 MAX_SAM_ENTRIES, acb_mask);
984 #endif
985 #if 0
987 * Which should we use here ? JRA.
989 ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
990 MAX_SAM_ENTRIES, acb_mask);
991 #endif
992 #if 1
993 ret = jf_get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
994 MAX_SAM_ENTRIES, acb_mask);
995 #endif
996 unbecome_root();
997 if (!ret) {
998 DEBUG(5, ("get_sampwd_entries: failed\n"));
999 return NT_STATUS_ACCESS_DENIED;
1001 break;
1002 case 0x3:
1003 case 0x5:
1004 ret = get_group_domain_entries(grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
1005 if (!ret)
1006 return NT_STATUS_ACCESS_DENIED;
1007 break;
1008 default:
1009 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1010 return NT_STATUS_INVALID_INFO_CLASS;
1014 if (num_entries > q_u->max_entries)
1015 num_entries = q_u->max_entries;
1017 if (num_entries > MAX_SAM_ENTRIES) {
1018 num_entries = MAX_SAM_ENTRIES;
1019 DEBUG(5, ("limiting number of entries to %d\n", num_entries));
1022 /* Ensure password info is never given out here. PARANOIA... JRA */
1023 samr_clear_passwd_fields(pass, num_entries);
1025 data_size = q_u->max_size;
1026 orig_num_entries = num_entries;
1028 ctr = (SAM_DISPINFO_CTR *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_CTR));
1030 /* Now create reply structure */
1031 switch (q_u->switch_level) {
1032 case 0x1:
1033 ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_1));
1034 init_sam_dispinfo_1(ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass);
1035 break;
1036 case 0x2:
1037 ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_2));
1038 init_sam_dispinfo_2(ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass);
1039 break;
1040 case 0x3:
1041 ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_3));
1042 init_sam_dispinfo_3(ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps);
1043 break;
1044 case 0x4:
1045 ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_4));
1046 init_sam_dispinfo_4(ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass);
1047 break;
1048 case 0x5:
1049 ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_5));
1050 init_sam_dispinfo_5(ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps);
1051 break;
1052 default:
1053 ctr->sam.info = NULL;
1054 return NT_STATUS_INVALID_INFO_CLASS;
1057 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1059 init_samr_r_query_dispinfo(r_u, num_entries, data_size, q_u->switch_level, ctr, r_u->status);
1061 if (num_entries < orig_num_entries) {
1062 return STATUS_MORE_ENTRIES;
1065 return r_u->status;
1068 /*******************************************************************
1069 samr_reply_query_aliasinfo
1070 ********************************************************************/
1072 uint32 _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1074 fstring alias_desc = "Local Unix group";
1075 fstring alias="";
1076 enum SID_NAME_USE type;
1077 uint32 alias_rid;
1078 struct samr_info *info = NULL;
1080 r_u->status = NT_STATUS_NOPROBLEMO;
1082 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1084 /* find the policy handle. open a policy on it. */
1085 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1086 return NT_STATUS_INVALID_HANDLE;
1088 alias_rid = get_lsa_policy_samr_rid(info);
1089 if(alias_rid == 0xffffffff)
1090 return NT_STATUS_NO_SUCH_ALIAS;
1092 if(!local_lookup_rid(alias_rid, alias, &type))
1093 return NT_STATUS_NO_SUCH_ALIAS;
1095 switch (q_u->switch_level) {
1096 case 3:
1097 r_u->ptr = 1;
1098 r_u->ctr.switch_value1 = 3;
1099 init_samr_alias_info3(&r_u->ctr.alias.info3, alias_desc);
1100 break;
1101 default:
1102 return NT_STATUS_INVALID_INFO_CLASS;
1105 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1107 return r_u->status;
1110 #if 0
1111 /*******************************************************************
1112 samr_reply_lookup_ids
1113 ********************************************************************/
1115 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1117 uint32 rid[MAX_SAM_ENTRIES];
1118 int num_rids = q_u->num_sids1;
1120 r_u->status = NT_STATUS_NOPROBLEMO;
1122 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1124 if (num_rids > MAX_SAM_ENTRIES) {
1125 num_rids = MAX_SAM_ENTRIES;
1126 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1129 #if 0
1130 int i;
1131 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1133 for (i = 0; i < num_rids && status == 0; i++)
1135 struct sam_passwd *sam_pass;
1136 fstring user_name;
1139 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1140 q_u->uni_user_name[i].uni_str_len));
1142 /* find the user account */
1143 become_root();
1144 sam_pass = get_smb21pwd_entry(user_name, 0);
1145 unbecome_root();
1147 if (sam_pass == NULL)
1149 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1150 rid[i] = 0;
1152 else
1154 rid[i] = sam_pass->user_rid;
1157 #endif
1159 num_rids = 1;
1160 rid[0] = BUILTIN_ALIAS_RID_USERS;
1162 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_NOPROBLEMO);
1164 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1166 return r_u->status;
1168 #endif
1170 /*******************************************************************
1171 _samr_lookup_names
1172 ********************************************************************/
1174 uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1176 uint32 rid[MAX_SAM_ENTRIES];
1177 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1178 int i;
1179 int num_rids = q_u->num_names1;
1180 DOM_SID pol_sid;
1182 r_u->status = NT_STATUS_NOPROBLEMO;
1184 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1186 ZERO_ARRAY(rid);
1187 ZERO_ARRAY(type);
1189 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
1190 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1191 return r_u->status;
1194 if (num_rids > MAX_SAM_ENTRIES) {
1195 num_rids = MAX_SAM_ENTRIES;
1196 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1199 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
1201 for (i = 0; i < num_rids; i++) {
1202 fstring name;
1204 r_u->status = NT_STATUS_NONE_MAPPED;
1206 rid [i] = 0xffffffff;
1207 type[i] = SID_NAME_UNKNOWN;
1209 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer, q_u->uni_name[i].uni_str_len));
1211 if(sid_equal(&pol_sid, &global_sam_sid)) {
1212 DOM_SID sid;
1213 if(local_lookup_name(global_myname, name, &sid, &type[i])) {
1214 sid_split_rid( &sid, &rid[i]);
1215 r_u->status = NT_STATUS_NOPROBLEMO;
1220 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1222 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1224 return r_u->status;
1227 /*******************************************************************
1228 _samr_chgpasswd_user
1229 ********************************************************************/
1231 uint32 _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1233 fstring user_name;
1234 fstring wks;
1236 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1238 r_u->status = NT_STATUS_NOPROBLEMO;
1240 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
1241 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
1243 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1246 * Pass the user through the NT -> unix user mapping
1247 * function.
1250 (void)map_username(user_name);
1253 * Do any UNIX username case mangling.
1255 (void)Get_Pwnam( user_name, True);
1257 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1258 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1259 r_u->status = NT_STATUS_WRONG_PASSWORD;
1261 init_samr_r_chgpasswd_user(r_u, r_u->status);
1263 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1265 return r_u->status;
1268 /*******************************************************************
1269 makes a SAMR_R_LOOKUP_RIDS structure.
1270 ********************************************************************/
1272 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1273 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1275 uint32 i;
1276 UNIHDR *hdr_name=NULL;
1277 UNISTR2 *uni_name=NULL;
1279 *pp_uni_name = NULL;
1280 *pp_hdr_name = NULL;
1282 if (num_names != 0) {
1283 hdr_name = (UNIHDR *)talloc(ctx, sizeof(UNIHDR)*num_names);
1284 if (hdr_name == NULL)
1285 return False;
1287 uni_name = (UNISTR2 *)talloc(ctx,sizeof(UNISTR2)*num_names);
1288 if (uni_name == NULL)
1289 return False;
1292 for (i = 0; i < num_names; i++) {
1293 int len = names[i] != NULL ? strlen(names[i]) : 0;
1294 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1295 init_uni_hdr(&hdr_name[i], len);
1296 init_unistr2(&uni_name[i], names[i], len);
1299 *pp_uni_name = uni_name;
1300 *pp_hdr_name = hdr_name;
1302 return True;
1305 /*******************************************************************
1306 _samr_lookup_rids
1307 ********************************************************************/
1309 uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1311 fstring group_names[MAX_SAM_ENTRIES];
1312 uint32 group_attrs[MAX_SAM_ENTRIES];
1313 UNIHDR *hdr_name = NULL;
1314 UNISTR2 *uni_name = NULL;
1315 DOM_SID pol_sid;
1316 int num_rids = q_u->num_rids1;
1317 int i;
1319 r_u->status = NT_STATUS_NOPROBLEMO;
1321 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1323 /* find the policy handle. open a policy on it. */
1324 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
1325 return NT_STATUS_INVALID_HANDLE;
1327 if (num_rids > MAX_SAM_ENTRIES) {
1328 num_rids = MAX_SAM_ENTRIES;
1329 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1332 r_u->status = NT_STATUS_NONE_MAPPED;
1334 for (i = 0; i < num_rids; i++) {
1335 fstring tmpname;
1336 fstring domname;
1337 DOM_SID sid;
1338 enum SID_NAME_USE type;
1340 group_attrs[i] = SID_NAME_UNKNOWN;
1341 *group_names[i] = '\0';
1343 if (sid_equal(&pol_sid, &global_sam_sid)) {
1344 sid_copy(&sid, &pol_sid);
1345 sid_append_rid(&sid, q_u->rid[i]);
1347 if (lookup_sid(&sid, domname, tmpname, &type)) {
1348 r_u->status = NT_STATUS_NOPROBLEMO;
1349 group_attrs[i] = (uint32)type;
1350 fstrcpy(group_names[i],tmpname);
1355 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1356 return NT_STATUS_NO_MEMORY;
1358 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1360 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1362 return r_u->status;
1365 /*******************************************************************
1366 _api_samr_open_user. Safe - gives out no passwd info.
1367 ********************************************************************/
1369 uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1371 SAM_ACCOUNT *sampass;
1372 DOM_SID sid;
1373 POLICY_HND domain_pol = q_u->domain_pol;
1374 uint32 user_rid = q_u->user_rid;
1375 POLICY_HND *user_pol = &r_u->user_pol;
1376 struct samr_info *info = NULL;
1378 r_u->status = NT_STATUS_NO_PROBLEMO;
1380 /* find the domain policy handle. */
1381 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1382 return NT_STATUS_INVALID_HANDLE;
1384 become_root();
1385 sampass = pdb_getsampwrid(user_rid);
1386 unbecome_root();
1388 /* check that the RID exists in our domain. */
1389 if (sampass == NULL)
1390 return NT_STATUS_NO_SUCH_USER;
1392 samr_clear_sam_passwd(sampass);
1394 /* Get the domain SID stored in the domain policy */
1395 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1396 return NT_STATUS_INVALID_HANDLE;
1398 /* append the user's RID to it */
1399 if(!sid_append_rid(&sid, user_rid))
1400 return NT_STATUS_NO_SUCH_USER;
1402 /* associate the user's SID with the new handle. */
1403 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1404 return NT_STATUS_NO_MEMORY;
1406 ZERO_STRUCTP(info);
1407 info->sid = sid;
1409 /* get a (unique) handle. open a policy on it. */
1410 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1411 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1413 return r_u->status;
1416 /*************************************************************************
1417 get_user_info_10. Safe. Only gives out acb bits.
1418 *************************************************************************/
1420 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1422 SAM_ACCOUNT *smbpass;
1424 if (!pdb_rid_is_user(user_rid)) {
1425 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1426 return False;
1429 become_root();
1430 smbpass = pdb_getsampwrid(user_rid);
1431 unbecome_root();
1433 if (smbpass == NULL) {
1434 DEBUG(4,("User 0x%x not found\n", user_rid));
1435 return False;
1438 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1440 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1442 return True;
1445 /*************************************************************************
1446 get_user_info_12. OK - this is the killer as it gives out password info.
1447 Ensure that this is only allowed on an encrypted connection with a root
1448 user. JRA.
1449 *************************************************************************/
1451 static uint32 get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
1453 SAM_ACCOUNT *smbpass;
1455 if (!p->ntlmssp_auth_validated)
1456 return NT_STATUS_ACCESS_DENIED;
1458 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1459 return NT_STATUS_ACCESS_DENIED;
1462 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1465 smbpass = pdb_getsampwrid(user_rid);
1467 if (smbpass == NULL) {
1468 DEBUG(4, ("User 0x%x not found\n", user_rid));
1469 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1472 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1474 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED)
1475 return NT_STATUS_ACCOUNT_DISABLED;
1477 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1479 return NT_STATUS_NOPROBLEMO;
1482 /*************************************************************************
1483 get_user_info_21
1484 *************************************************************************/
1486 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1488 SAM_ACCOUNT *sampass;
1490 if (!pdb_rid_is_user(user_rid)) {
1491 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1492 return False;
1495 become_root();
1496 sampass = pdb_getsampwrid(user_rid);
1497 unbecome_root();
1499 if (sampass == NULL) {
1500 DEBUG(4,("User 0x%x not found\n", user_rid));
1501 return False;
1504 samr_clear_sam_passwd(sampass);
1506 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1508 init_sam_user_info21A(id21, sampass);
1510 return True;
1513 /*******************************************************************
1514 _samr_query_userinfo
1515 ********************************************************************/
1517 uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1519 SAM_USERINFO_CTR *ctr;
1520 uint32 rid = 0;
1521 struct samr_info *info = NULL;
1523 r_u->status=NT_STATUS_NO_PROBLEMO;
1525 /* search for the handle */
1526 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1527 return NT_STATUS_INVALID_HANDLE;
1529 /* find the user's rid */
1530 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1531 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1533 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
1535 ctr = (SAM_USERINFO_CTR *)talloc(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1536 if (!ctr)
1537 return NT_STATUS_NO_MEMORY;
1539 ZERO_STRUCTP(ctr);
1541 /* ok! user info levels (lots: see MSDEV help), off we go... */
1542 ctr->switch_value = q_u->switch_value;
1544 switch (q_u->switch_value) {
1545 case 0x10:
1546 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1547 if (ctr->info.id10 == NULL)
1548 return NT_STATUS_NO_MEMORY;
1550 if (!get_user_info_10(ctr->info.id10, rid))
1551 return NT_STATUS_NO_SUCH_USER;
1552 break;
1554 #if 0
1555 /* whoops - got this wrong. i think. or don't understand what's happening. */
1556 case 0x11:
1558 NTTIME expire;
1559 info = (void *)&id11;
1561 expire.low = 0xffffffff;
1562 expire.high = 0x7fffffff;
1564 ctr->info.id = (SAM_USER_INFO_11 *)talloc(p->mem_ctx,
1565 sizeof
1566 (*ctr->
1567 info.
1568 id11));
1569 init_sam_user_info11(ctr->info.id11, &expire,
1570 "BROOKFIELDS$", /* name */
1571 0x03ef, /* user rid */
1572 0x201, /* group rid */
1573 0x0080); /* acb info */
1575 break;
1577 #endif
1579 case 0x12:
1580 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1581 if (ctr->info.id12 == NULL)
1582 return NT_STATUS_NO_MEMORY;
1584 if ((r_u->status = get_user_info_12(p, ctr->info.id12, rid)) != NT_STATUS_NOPROBLEMO)
1585 return r_u->status;
1586 break;
1588 case 21:
1589 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1590 if (ctr->info.id21 == NULL)
1591 return NT_STATUS_NO_MEMORY;
1592 if (!get_user_info_21(ctr->info.id21, rid))
1593 return NT_STATUS_NO_SUCH_USER;
1594 break;
1596 default:
1597 return NT_STATUS_INVALID_INFO_CLASS;
1600 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1602 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1604 return r_u->status;
1607 /*******************************************************************
1608 samr_reply_query_usergroups
1609 ********************************************************************/
1611 uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1613 struct sam_passwd *sam_pass;
1614 DOM_GID *gids = NULL;
1615 int num_groups = 0;
1616 pstring groups;
1617 uint32 rid;
1618 struct samr_info *info = NULL;
1620 r_u->status = NT_STATUS_NO_PROBLEMO;
1622 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1624 /* find the policy handle. open a policy on it. */
1625 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1626 return NT_STATUS_INVALID_HANDLE;
1628 /* find the user's rid */
1629 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1630 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1632 become_root();
1633 sam_pass = pdb_getsampwrid(rid);
1634 unbecome_root();
1636 if (sam_pass == NULL)
1637 return NT_STATUS_NO_SUCH_USER;
1639 samr_clear_sam_passwd(sam_pass);
1641 get_domain_user_groups(groups, pdb_get_username(sam_pass));
1642 gids = NULL;
1643 num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
1645 /* construct the response. lkclXXXX: gids are not copied! */
1646 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1648 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1650 return r_u->status;
1653 /*******************************************************************
1654 _samr_query_dom_info
1655 ********************************************************************/
1657 uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1659 SAM_UNK_CTR *ctr;
1661 if ((ctr = (SAM_UNK_CTR *)talloc(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
1662 return NT_STATUS_NO_MEMORY;
1664 ZERO_STRUCTP(ctr);
1666 r_u->status = NT_STATUS_NO_PROBLEMO;
1668 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1670 /* find the policy handle. open a policy on it. */
1671 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
1672 return NT_STATUS_INVALID_HANDLE;
1674 switch (q_u->switch_value) {
1675 case 0x01:
1676 init_unk_info1(&ctr->info.inf1);
1677 break;
1678 case 0x02:
1679 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1680 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL));
1681 break;
1682 case 0x03:
1683 init_unk_info3(&ctr->info.inf3);
1684 break;
1685 case 0x06:
1686 init_unk_info6(&ctr->info.inf6);
1687 break;
1688 case 0x07:
1689 init_unk_info7(&ctr->info.inf7);
1690 break;
1691 case 0x0c:
1692 init_unk_info12(&ctr->info.inf12);
1693 break;
1694 default:
1695 return NT_STATUS_INVALID_INFO_CLASS;
1698 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_NOPROBLEMO);
1700 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1702 return r_u->status;
1705 /*******************************************************************
1706 _api_samr_create_user
1707 ********************************************************************/
1709 uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
1711 SAM_ACCOUNT *sam_pass;
1712 fstring mach_acct;
1713 pstring err_str;
1714 pstring msg_str;
1715 int local_flags=0;
1716 DOM_SID sid;
1717 pstring add_script;
1718 POLICY_HND dom_pol = q_u->domain_pol;
1719 UNISTR2 user_account = q_u->uni_name;
1720 uint16 acb_info = q_u->acb_info;
1721 POLICY_HND *user_pol = &r_u->user_pol;
1722 struct samr_info *info = NULL;
1724 /* find the policy handle. open a policy on it. */
1725 if (!find_policy_by_hnd(p, &dom_pol, NULL))
1726 return NT_STATUS_INVALID_HANDLE;
1728 /* find the machine account: tell the caller if it exists.
1729 lkclXXXX i have *no* idea if this is a problem or not
1730 or even if you are supposed to construct a different
1731 reply if the account already exists...
1734 fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
1735 strlower(mach_acct);
1737 become_root();
1738 sam_pass = pdb_getsampwnam(mach_acct);
1739 unbecome_root();
1740 if (sam_pass != NULL) {
1741 /* machine account exists: say so */
1742 return NT_STATUS_USER_EXISTS;
1745 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1746 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1749 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1750 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1751 * that only people with write access to the smbpasswd file will be able
1752 * to create a user. JRA.
1756 * add the user in the /etc/passwd file or the unix authority system.
1757 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1758 * a) local_password_change() checks for us if the /etc/passwd account really exists
1759 * b) smb_create_user() would return an error if the account already exists
1760 * and as it could return an error also if it can't create the account, it would be tricky.
1762 * So we go the easy way, only check after if the account exists.
1763 * JFM (2/3/2001), to clear any possible bad understanding (-:
1766 pstrcpy(add_script, lp_adduser_script());
1768 if(*add_script)
1769 smb_create_user(mach_acct, NULL);
1771 /* add the user in the smbpasswd file or the Samba authority database */
1772 if (!local_password_change(mach_acct, local_flags, NULL, err_str,
1773 sizeof(err_str), msg_str, sizeof(msg_str)))
1775 DEBUG(0, ("%s\n", err_str));
1776 close_policy_hnd(p, user_pol);
1777 return NT_STATUS_ACCESS_DENIED;
1780 become_root();
1781 sam_pass = pdb_getsampwnam(mach_acct);
1782 unbecome_root();
1783 if (sam_pass == NULL) {
1784 /* account doesn't exist: say so */
1785 close_policy_hnd(p, user_pol);
1786 return NT_STATUS_ACCESS_DENIED;
1789 /* Get the domain SID stored in the domain policy */
1790 if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
1791 close_policy_hnd(p, user_pol);
1792 return NT_STATUS_INVALID_HANDLE;
1795 /* append the user's RID to it */
1796 if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
1797 close_policy_hnd(p, user_pol);
1798 return NT_STATUS_NO_SUCH_USER;
1801 /* associate the user's SID with the new handle. */
1802 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1803 return NT_STATUS_NO_MEMORY;
1805 ZERO_STRUCTP(info);
1806 info->sid = sid;
1808 /* get a (unique) handle. open a policy on it. */
1809 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1810 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1812 r_u->user_rid=sam_pass->user_rid;
1813 r_u->unknown_0 = 0x000703ff;
1815 return NT_STATUS_NO_PROBLEMO;
1818 /*******************************************************************
1819 samr_reply_connect_anon
1820 ********************************************************************/
1822 uint32 _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
1824 struct samr_info *info = NULL;
1826 /* set up the SAMR connect_anon response */
1828 r_u->status = NT_STATUS_NO_PROBLEMO;
1830 /* associate the user's SID with the new handle. */
1831 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1832 return NT_STATUS_NO_MEMORY;
1834 ZERO_STRUCTP(info);
1835 info->status = q_u->unknown_0;
1837 /* get a (unique) handle. open a policy on it. */
1838 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
1839 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1841 return r_u->status;
1844 /*******************************************************************
1845 samr_reply_connect
1846 ********************************************************************/
1848 uint32 _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
1850 struct samr_info *info = NULL;
1852 DEBUG(5,("_samr_connect: %d\n", __LINE__));
1854 r_u->status = NT_STATUS_NO_PROBLEMO;
1856 /* associate the user's SID with the new handle. */
1857 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1858 return NT_STATUS_NO_MEMORY;
1860 ZERO_STRUCTP(info);
1861 info->status = q_u->access_mask;
1863 /* get a (unique) handle. open a policy on it. */
1864 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
1865 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1867 DEBUG(5,("_samr_connect: %d\n", __LINE__));
1869 return r_u->status;
1872 /**********************************************************************
1873 api_samr_lookup_domain
1874 **********************************************************************/
1876 uint32 _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
1878 r_u->status = NT_STATUS_NO_PROBLEMO;
1880 if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
1881 return NT_STATUS_INVALID_HANDLE;
1883 /* assume the domain name sent is our global_myname and
1884 send global_sam_sid */
1885 init_samr_r_lookup_domain(r_u, &global_sam_sid, r_u->status);
1887 return r_u->status;
1890 /******************************************************************
1891 makes a SAMR_R_ENUM_DOMAINS structure.
1892 ********************************************************************/
1894 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
1895 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
1897 uint32 i;
1898 SAM_ENTRY *sam;
1899 UNISTR2 *uni_name;
1901 DEBUG(5, ("make_enum_domains\n"));
1903 *pp_sam = NULL;
1904 *pp_uni_name = NULL;
1906 if (num_sam_entries == 0)
1907 return True;
1909 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
1910 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
1912 if (sam == NULL || uni_name == NULL)
1913 return False;
1915 for (i = 0; i < num_sam_entries; i++) {
1916 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
1918 init_sam_entry(&sam[i], len, 0);
1919 init_unistr2(&uni_name[i], doms[i], len);
1922 *pp_sam = sam;
1923 *pp_uni_name = uni_name;
1925 return True;
1928 /**********************************************************************
1929 api_samr_enum_domains
1930 **********************************************************************/
1932 uint32 _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
1934 uint32 num_entries = 2;
1935 fstring dom[2];
1937 r_u->status = NT_STATUS_NO_PROBLEMO;
1939 fstrcpy(dom[0],global_myworkgroup);
1940 fstrcpy(dom[1],"Builtin");
1942 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
1943 return NT_STATUS_NO_MEMORY;
1945 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
1947 return r_u->status;
1950 /*******************************************************************
1951 api_samr_open_alias
1952 ********************************************************************/
1954 uint32 _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
1956 DOM_SID sid;
1957 POLICY_HND domain_pol = q_u->dom_pol;
1958 uint32 alias_rid = q_u->rid_alias;
1959 POLICY_HND *alias_pol = &r_u->pol;
1960 struct samr_info *info = NULL;
1962 r_u->status = NT_STATUS_NO_PROBLEMO;
1964 /* get the domain policy. */
1965 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1966 return NT_STATUS_INVALID_HANDLE;
1968 /* Get the domain SID stored in the domain policy */
1969 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1970 return NT_STATUS_INVALID_HANDLE;
1972 /* append the alias' RID to it */
1973 if(!sid_append_rid(&sid, alias_rid))
1974 return NT_STATUS_NO_SUCH_USER;
1977 * we should check if the rid really exist !!!
1978 * JFM.
1981 /* associate the user's SID with the new handle. */
1982 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1983 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, alias_pol, free_samr_info, (void *)info))
1990 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1992 return r_u->status;
1995 /*******************************************************************
1996 set_user_info_10
1997 ********************************************************************/
1999 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
2001 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2003 if (id10 == NULL) {
2004 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2005 return False;
2008 pwd = pdb_getsampwrid(rid);
2009 if (!pwd)
2010 return False;
2012 pdb_set_acct_ctrl(pwd, id10->acb_info);
2014 if(!pdb_update_sam_account(pwd, True))
2015 return False;
2017 return True;
2020 /*******************************************************************
2021 set_user_info_12
2022 ********************************************************************/
2024 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2026 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2028 if (pwd == NULL)
2029 return False;
2031 if (id12 == NULL) {
2032 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2033 return False;
2036 pdb_set_lanman_passwd (pwd, id12->lm_pwd);
2037 pdb_set_nt_passwd (pwd, id12->nt_pwd);
2039 if(!pdb_update_sam_account(pwd, True))
2040 return False;
2042 return True;
2045 /*******************************************************************
2046 set_user_info_21
2047 ********************************************************************/
2049 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
2051 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2052 SAM_ACCOUNT new_pwd;
2054 if (id21 == NULL) {
2055 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2056 return False;
2059 if (pwd == NULL)
2060 return False;
2062 /* we make a copy so that we can modify stuff */
2063 ZERO_STRUCT(new_pwd);
2064 copy_sam_passwd(&new_pwd, pwd);
2065 copy_id21_to_sam_passwd(&new_pwd, id21);
2068 * The funny part about the previous two calls is
2069 * that pwd still has the password hashes from the
2070 * passdb entry. These have not been updated from
2071 * id21. I don't know if they need to be set. --jerry
2074 /* write the change out */
2075 if(!pdb_update_sam_account(&new_pwd, True))
2076 return False;
2078 return True;
2081 /*******************************************************************
2082 set_user_info_23
2083 ********************************************************************/
2085 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2087 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2088 SAM_ACCOUNT new_pwd;
2089 uint8 nt_hash[16];
2090 uint8 lm_hash[16];
2091 pstring buf;
2092 uint32 len;
2093 uint16 acct_ctrl;
2095 if (id23 == NULL) {
2096 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2097 return False;
2100 if (pwd == NULL)
2101 return False;
2103 acct_ctrl = pdb_get_acct_ctrl(pwd);
2105 ZERO_STRUCT (new_pwd);
2106 copy_sam_passwd(&new_pwd, pwd);
2107 copy_id23_to_sam_passwd(&new_pwd, id23);
2109 if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len, nt_hash, lm_hash))
2110 return False;
2112 pdb_set_lanman_passwd (&new_pwd, lm_hash);
2113 pdb_set_nt_passwd (&new_pwd, nt_hash);
2115 /* if it's a trust account, don't update /etc/passwd */
2116 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2117 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2118 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2119 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2120 } else {
2121 /* update the UNIX password */
2122 /* update the UNIX password */
2123 if (lp_unix_password_sync() )
2124 if(!chgpasswd(pdb_get_username(&new_pwd), "", buf, True))
2125 return False;
2128 memset(buf, 0, sizeof(buf));
2130 if(!pdb_update_sam_account(&new_pwd, True))
2131 return False;
2133 return True;
2136 /*******************************************************************
2137 set_user_info_24
2138 ********************************************************************/
2140 static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid)
2142 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2143 uchar nt_hash[16];
2144 uchar lm_hash[16];
2145 uint32 len;
2146 pstring buf;
2147 uint16 acct_ctrl;
2149 if (pwd == NULL)
2150 return False;
2152 acct_ctrl = pdb_get_acct_ctrl(pwd);
2154 memset(buf, 0, sizeof(buf));
2156 if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len, nt_hash, lm_hash))
2157 return False;
2159 pdb_set_lanman_passwd (pwd, lm_hash);
2160 pdb_set_nt_passwd (pwd, nt_hash);
2162 /* if it's a trust account, don't update /etc/passwd */
2163 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2164 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2165 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2166 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2167 } else {
2168 /* update the UNIX password */
2169 if (lp_unix_password_sync())
2170 if(!chgpasswd(pdb_get_username(pwd), "", buf, True))
2171 return False;
2174 memset(buf, 0, sizeof(buf));
2176 DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
2178 /* update the SAMBA password */
2179 if(!pdb_update_sam_account(pwd, True))
2180 return False;
2182 return True;
2185 /*******************************************************************
2186 samr_reply_set_userinfo
2187 ********************************************************************/
2189 uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2191 uint32 rid = 0x0;
2192 DOM_SID sid;
2193 struct current_user user;
2194 SAM_ACCOUNT *sam_pass;
2195 unsigned char sess_key[16];
2196 POLICY_HND *pol = &q_u->pol;
2197 uint16 switch_value = q_u->switch_value;
2198 SAM_USERINFO_CTR *ctr = q_u->ctr;
2200 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2202 r_u->status = NT_STATUS_NOPROBLEMO;
2204 if (p->ntlmssp_auth_validated) {
2205 memcpy(&user, &p->pipe_user, sizeof(user));
2206 } else {
2207 extern struct current_user current_user;
2208 memcpy(&user, &current_user, sizeof(user));
2211 /* find the policy handle. open a policy on it. */
2212 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2213 return NT_STATUS_INVALID_HANDLE;
2215 sid_split_rid(&sid, &rid);
2217 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2219 if (ctr == NULL) {
2220 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2221 return NT_STATUS_INVALID_INFO_CLASS;
2226 * We need the NT hash of the user who is changing the user's password.
2227 * This NT hash is used to generate a "user session key"
2228 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2231 become_root();
2232 sam_pass = pdb_getsampwuid(user.uid);
2233 unbecome_root();
2234 if(sam_pass == NULL) {
2235 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
2236 return NT_STATUS_ACCESS_DENIED;
2239 memset(sess_key, '\0', 16);
2240 mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2242 /* ok! user info levels (lots: see MSDEV help), off we go... */
2243 switch (switch_value) {
2244 case 0x12:
2245 if (!set_user_info_12(ctr->info.id12, rid))
2246 return NT_STATUS_ACCESS_DENIED;
2247 break;
2249 case 24:
2250 SamOEMhash(ctr->info.id24->pass, sess_key, 1);
2251 if (!set_user_info_24(ctr->info.id24, rid))
2252 return NT_STATUS_ACCESS_DENIED;
2253 break;
2255 case 23:
2256 SamOEMhash(ctr->info.id23->pass, sess_key, 1);
2257 if (!set_user_info_23(ctr->info.id23, rid))
2258 return NT_STATUS_ACCESS_DENIED;
2259 break;
2261 default:
2262 return NT_STATUS_INVALID_INFO_CLASS;
2265 return r_u->status;
2268 /*******************************************************************
2269 samr_reply_set_userinfo2
2270 ********************************************************************/
2272 uint32 _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2274 DOM_SID sid;
2275 uint32 rid = 0x0;
2276 SAM_USERINFO_CTR *ctr = q_u->ctr;
2277 POLICY_HND *pol = &q_u->pol;
2278 uint16 switch_value = q_u->switch_value;
2280 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2282 r_u->status = NT_STATUS_NOPROBLEMO;
2284 /* find the policy handle. open a policy on it. */
2285 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2286 return NT_STATUS_INVALID_HANDLE;
2288 sid_split_rid(&sid, &rid);
2290 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2292 if (ctr == NULL) {
2293 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2294 return NT_STATUS_INVALID_INFO_CLASS;
2297 switch_value=ctr->switch_value;
2299 /* ok! user info levels (lots: see MSDEV help), off we go... */
2300 switch (switch_value) {
2301 case 21:
2302 if (!set_user_info_21(ctr->info.id21, rid))
2303 return NT_STATUS_ACCESS_DENIED;
2304 break;
2305 case 16:
2306 if (!set_user_info_10(ctr->info.id10, rid))
2307 return NT_STATUS_ACCESS_DENIED;
2308 break;
2309 case 18:
2310 /* Used by AS/U JRA. */
2311 if (!set_user_info_12(ctr->info.id12, rid))
2312 return NT_STATUS_ACCESS_DENIED;
2313 break;
2314 default:
2315 return NT_STATUS_INVALID_INFO_CLASS;
2318 return r_u->status;
2321 /*********************************************************************
2322 _samr_query_aliasmem
2323 *********************************************************************/
2325 uint32 _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
2327 uint32 *rid=NULL;
2328 int num_rids;
2330 num_rids = 1;
2331 rid=(uint32 *)talloc(p->mem_ctx, num_rids*sizeof(uint32));
2332 if (rid==NULL)
2333 return NT_STATUS_NO_MEMORY;
2335 /* until i see a real useraliases query, we fack one up */
2337 rid[0] = BUILTIN_ALIAS_RID_USERS;
2339 init_samr_r_query_useraliases(r_u, num_rids, rid, NT_STATUS_NO_PROBLEMO);
2341 return NT_STATUS_NO_PROBLEMO;
2345 /*********************************************************************
2346 _samr_query_aliasmem
2347 *********************************************************************/
2349 uint32 _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
2351 int i;
2353 GROUP_MAP map;
2354 int num_uids = 0;
2355 DOM_SID2 *sid;
2356 uid_t *uid=NULL;
2358 DOM_SID alias_sid;
2359 DOM_SID als_sid;
2360 uint32 alias_rid;
2361 fstring alias_sid_str;
2362 DOM_SID temp_sid;
2365 /* find the policy handle. open a policy on it. */
2366 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2367 return NT_STATUS_INVALID_HANDLE;
2369 sid_copy(&als_sid, &alias_sid);
2370 sid_to_string(alias_sid_str, &alias_sid);
2371 sid_split_rid(&alias_sid, &alias_rid);
2373 DEBUG(10, ("sid is %s\n", alias_sid_str));
2375 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
2376 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
2377 if(!get_builtin_group_from_sid(als_sid, &map))
2378 return NT_STATUS_NO_SUCH_ALIAS;
2379 } else {
2380 if (sid_equal(&alias_sid, &global_sam_sid)) {
2381 DEBUG(10, ("lookup on Server SID\n"));
2382 if(!get_local_group_from_sid(als_sid, &map))
2383 return NT_STATUS_NO_SUCH_ALIAS;
2387 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2388 return NT_STATUS_NO_SUCH_ALIAS;
2390 DEBUG(10, ("sid is %s\n", alias_sid_str));
2391 sid = (DOM_SID2 *)talloc(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
2392 if (sid == NULL)
2393 return NT_STATUS_NO_SUCH_ALIAS;
2395 for (i = 0; i < num_uids; i++) {
2396 sid_copy(&temp_sid, &global_sam_sid);
2397 sid_append_rid(&temp_sid, pdb_uid_to_user_rid(uid[i]));
2399 init_dom_sid2(&sid[i], &temp_sid);
2402 DEBUG(10, ("sid is %s\n", alias_sid_str));
2403 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_NO_PROBLEMO);
2405 return NT_STATUS_NOPROBLEMO;
2408 /*********************************************************************
2409 _samr_query_groupmem
2410 *********************************************************************/
2412 uint32 _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
2414 int num_uids = 0;
2415 int i;
2416 DOM_SID group_sid;
2417 uint32 group_rid;
2418 fstring group_sid_str;
2419 uid_t *uid=NULL;
2421 GROUP_MAP map;
2423 uint32 *rid=NULL;
2424 uint32 *attr=NULL;
2427 /* find the policy handle. open a policy on it. */
2428 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid))
2429 return NT_STATUS_INVALID_HANDLE;
2431 /* todo: change to use sid_compare_front */
2433 sid_split_rid(&group_sid, &group_rid);
2434 sid_to_string(group_sid_str, &group_sid);
2435 DEBUG(10, ("sid is %s\n", group_sid_str));
2437 /* can we get a query for an SID outside our domain ? */
2438 if (!sid_equal(&group_sid, &global_sam_sid))
2439 return NT_STATUS_NO_SUCH_GROUP;
2441 sid_append_rid(&group_sid, group_rid);
2442 DEBUG(10, ("lookup on Domain SID\n"));
2444 if(!get_domain_group_from_sid(group_sid, &map))
2445 return NT_STATUS_NO_SUCH_GROUP;
2447 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2448 return NT_STATUS_NO_SUCH_GROUP;
2450 rid=talloc(p->mem_ctx, sizeof(uint32)*num_uids);
2451 attr=talloc(p->mem_ctx, sizeof(uint32)*num_uids);
2453 if (rid==NULL || attr==NULL)
2454 return NT_STATUS_NO_MEMORY;
2456 for (i=0; i<num_uids; i++) {
2457 rid[i]=pdb_uid_to_user_rid(uid[i]);
2458 attr[i] = SID_NAME_USER;
2461 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_NOPROBLEMO);
2463 return NT_STATUS_NOPROBLEMO;
2466 /*********************************************************************
2467 _samr_add_aliasmem
2468 *********************************************************************/
2470 uint32 _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
2472 DOM_SID alias_sid;
2473 fstring alias_sid_str;
2474 uid_t uid;
2475 struct passwd *pwd;
2476 struct group *grp;
2477 fstring grp_name;
2478 uint32 rid;
2479 GROUP_MAP map;
2481 /* Find the policy handle. Open a policy on it. */
2482 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2483 return NT_STATUS_INVALID_HANDLE;
2485 sid_to_string(alias_sid_str, &alias_sid);
2486 DEBUG(10, ("sid is %s\n", alias_sid_str));
2488 if (sid_compare(&alias_sid, &global_sam_sid)>0) {
2489 DEBUG(10, ("adding member on Server SID\n"));
2490 if(!get_local_group_from_sid(alias_sid, &map))
2491 return NT_STATUS_NO_SUCH_ALIAS;
2493 } else {
2494 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
2495 DEBUG(10, ("adding member on BUILTIN SID\n"));
2496 if( !get_builtin_group_from_sid(alias_sid, &map))
2497 return NT_STATUS_NO_SUCH_ALIAS;
2499 } else
2500 return NT_STATUS_NO_SUCH_ALIAS;
2503 sid_split_rid(&q_u->sid.sid, &rid);
2504 uid=pdb_user_rid_to_uid(rid);
2506 if ((pwd=getpwuid(uid)) == NULL)
2507 return NT_STATUS_NO_SUCH_USER;
2509 if ((grp=getgrgid(map.gid)) == NULL)
2510 return NT_STATUS_NO_SUCH_ALIAS;
2512 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2513 fstrcpy(grp_name, grp->gr_name);
2515 /* if the user is already in the group */
2516 if(user_in_group_list(pwd->pw_name, grp_name))
2517 return NT_STATUS_MEMBER_IN_ALIAS;
2520 * ok, the group exist, the user exist, the user is not in the group,
2521 * we can (finally) add it to the group !
2523 smb_add_user_group(grp_name, pwd->pw_name);
2525 /* check if the user has been added then ... */
2526 if(!user_in_group_list(pwd->pw_name, grp_name))
2527 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
2529 return NT_STATUS_NOPROBLEMO;
2532 /*********************************************************************
2533 _samr_del_aliasmem
2534 *********************************************************************/
2536 uint32 _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
2538 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2539 return False;
2542 /*********************************************************************
2543 _samr_add_groupmem
2544 *********************************************************************/
2546 uint32 _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
2548 DOM_SID group_sid;
2549 fstring group_sid_str;
2550 struct passwd *pwd;
2551 struct group *grp;
2552 fstring grp_name;
2553 GROUP_MAP map;
2555 /* Find the policy handle. Open a policy on it. */
2556 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2557 return NT_STATUS_INVALID_HANDLE;
2559 sid_to_string(group_sid_str, &group_sid);
2560 DEBUG(10, ("sid is %s\n", group_sid_str));
2562 if (sid_compare(&group_sid, &global_sam_sid)<=0)
2563 return NT_STATUS_NO_SUCH_GROUP;
2565 DEBUG(10, ("lookup on Domain SID\n"));
2567 if(!get_domain_group_from_sid(group_sid, &map))
2568 return NT_STATUS_NO_SUCH_GROUP;
2570 if ((pwd=getpwuid(pdb_user_rid_to_uid(q_u->rid))) ==NULL)
2571 return NT_STATUS_NO_SUCH_USER;
2573 if ((grp=getgrgid(map.gid)) == NULL)
2574 return NT_STATUS_NO_SUCH_GROUP;
2576 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2577 fstrcpy(grp_name, grp->gr_name);
2579 /* if the user is already in the group */
2580 if(user_in_group_list(pwd->pw_name, grp_name))
2581 return NT_STATUS_MEMBER_IN_GROUP;
2584 * ok, the group exist, the user exist, the user is not in the group,
2586 * we can (finally) add it to the group !
2589 smb_add_user_group(grp_name, pwd->pw_name);
2591 /* check if the user has been added then ... */
2592 if(!user_in_group_list(pwd->pw_name, grp_name))
2593 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
2595 return NT_STATUS_NOPROBLEMO;
2598 /*********************************************************************
2599 _samr_del_groupmem
2600 *********************************************************************/
2602 uint32 _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
2604 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2605 return False;
2608 /*********************************************************************
2609 _samr_delete_dom_user
2610 *********************************************************************/
2612 uint32 _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
2614 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2615 return False;
2618 /*********************************************************************
2619 _samr_delete_dom_group
2620 *********************************************************************/
2622 uint32 _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
2624 DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
2625 return False;
2628 /*********************************************************************
2629 _samr_delete_dom_alias
2630 *********************************************************************/
2632 uint32 _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
2634 DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
2635 return False;
2638 /*********************************************************************
2639 _samr_create_dom_group
2640 *********************************************************************/
2642 uint32 _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
2644 DOM_SID dom_sid;
2645 DOM_SID info_sid;
2646 fstring name;
2647 fstring sid_string;
2648 struct group *grp;
2649 struct samr_info *info;
2651 /* Find the policy handle. Open a policy on it. */
2652 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid))
2653 return NT_STATUS_INVALID_HANDLE;
2655 if (!sid_equal(&dom_sid, &global_sam_sid))
2656 return NT_STATUS_ACCESS_DENIED;
2658 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2660 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
2662 /* check if group already exist */
2663 if ((grp=getgrnam(name)) != NULL)
2664 return NT_STATUS_GROUP_EXISTS;
2666 /* we can create the UNIX group */
2667 smb_create_group(name);
2669 /* check if the group has been successfully created */
2670 if ((grp=getgrnam(name)) == NULL)
2671 return NT_STATUS_ACCESS_DENIED;
2673 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
2675 /* add the group to the mapping table */
2676 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, SE_PRIV_NONE))
2677 return NT_STATUS_ACCESS_DENIED;
2679 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2680 return NT_STATUS_NO_MEMORY;
2682 ZERO_STRUCTP(info);
2684 sid_copy(&info_sid, &global_sam_sid);
2685 sid_append_rid(&info->sid, r_u->rid);
2686 sid_to_string(sid_string, &info->sid);
2688 /* get a (unique) handle. open a policy on it. */
2689 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
2690 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2692 return NT_STATUS_NOPROBLEMO;
2695 /*********************************************************************
2696 _samr_create_dom_alias
2697 *********************************************************************/
2699 uint32 _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
2701 DOM_SID dom_sid;
2702 fstring name;
2703 fstring sid_string;
2704 struct group *grp;
2705 struct samr_info *info;
2707 /* Find the policy handle. Open a policy on it. */
2708 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid))
2709 return NT_STATUS_INVALID_HANDLE;
2711 if (!sid_equal(&dom_sid, &global_sam_sid))
2712 return NT_STATUS_ACCESS_DENIED;
2714 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2716 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
2718 /* check if group already exists */
2719 if ( (grp=getgrnam(name)) != NULL)
2720 return NT_STATUS_GROUP_EXISTS;
2722 /* we can create the UNIX group */
2723 smb_create_group(name);
2725 /* check if the group has been successfully created */
2726 if ((grp=getgrnam(name)) == NULL)
2727 return NT_STATUS_ACCESS_DENIED;
2729 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
2731 /* add the group to the mapping table */
2732 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, NULL, NULL, SE_PRIV_NONE))
2733 return NT_STATUS_ACCESS_DENIED;
2735 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2736 return NT_STATUS_NO_MEMORY;
2738 ZERO_STRUCTP(info);
2740 sid_copy(&info->sid, &global_sam_sid);
2741 sid_append_rid(&info->sid, r_u->rid);
2742 sid_to_string(sid_string, &info->sid);
2744 /* get a (unique) handle. open a policy on it. */
2745 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
2746 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2748 return NT_STATUS_NOPROBLEMO;
2751 /*********************************************************************
2752 _samr_query_groupinfo
2754 sends the name/comment pair of a domain group
2755 level 1 send also the number of users of that group
2756 *********************************************************************/
2758 uint32 _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
2760 DOM_SID group_sid;
2761 GROUP_MAP map;
2762 uid_t *uid;
2763 int num_uids=0;
2764 GROUP_INFO_CTR *ctr;
2766 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2767 return NT_STATUS_INVALID_HANDLE;
2769 if (!get_domain_group_from_sid(group_sid, &map))
2770 return NT_STATUS_INVALID_HANDLE;
2772 ctr=(GROUP_INFO_CTR *)talloc(p->mem_ctx, sizeof(GROUP_INFO_CTR));
2773 if (ctr==NULL)
2774 return NT_STATUS_NO_MEMORY;
2776 switch (q_u->switch_level) {
2777 case 1:
2778 ctr->switch_value1 = 1;
2779 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2780 return NT_STATUS_NO_SUCH_GROUP;
2781 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
2782 safe_free(uid);
2783 break;
2784 case 4:
2785 ctr->switch_value1 = 4;
2786 init_samr_group_info4(&ctr->group.info4, map.comment);
2787 break;
2788 default:
2789 return NT_STATUS_INVALID_INFO_CLASS;
2792 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_NO_PROBLEMO);
2794 return NT_STATUS_NO_PROBLEMO;
2797 /*********************************************************************
2798 _samr_set_groupinfo
2800 update a domain group's comment.
2801 *********************************************************************/
2803 uint32 _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
2805 DOM_SID group_sid;
2806 GROUP_MAP map;
2807 GROUP_INFO_CTR *ctr;
2809 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2810 return NT_STATUS_INVALID_HANDLE;
2812 if (!get_domain_group_from_sid(group_sid, &map))
2813 return NT_STATUS_NO_SUCH_GROUP;
2815 ctr=q_u->ctr;
2817 switch (ctr->switch_value1) {
2818 case 1:
2819 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
2820 break;
2821 case 4:
2822 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
2823 break;
2824 default:
2825 return NT_STATUS_INVALID_INFO_CLASS;
2828 if(!add_mapping_entry(&map, TDB_REPLACE))
2829 return NT_STATUS_NO_SUCH_GROUP;
2831 return NT_STATUS_NO_PROBLEMO;
2834 /*********************************************************************
2835 _samr_get_dom_pwinfo
2836 *********************************************************************/
2838 uint32 _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
2840 /* Actually, returning zeros here works quite well :-). */
2841 return NT_STATUS_NOPROBLEMO;
2844 /*********************************************************************
2845 _samr_open_group
2846 *********************************************************************/
2848 uint32 _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
2850 DOM_SID sid;
2851 GROUP_MAP map;
2852 struct samr_info *info;
2853 fstring sid_string;
2855 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
2856 return NT_STATUS_INVALID_HANDLE;
2858 /* this should not be hard-coded like this */
2859 if (!sid_equal(&sid, &global_sam_sid))
2860 return NT_STATUS_ACCESS_DENIED;
2862 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2863 return NT_STATUS_NO_MEMORY;
2865 ZERO_STRUCTP(info);
2867 sid_copy(&info->sid, &global_sam_sid);
2868 sid_append_rid(&info->sid, q_u->rid_group);
2869 sid_to_string(sid_string, &info->sid);
2871 DEBUG(10, ("Opening SID: %s\n", sid_string));
2873 /* check if that group really exists */
2874 if (!get_domain_group_from_sid(info->sid, &map))
2875 return NT_STATUS_NO_SUCH_USER;
2877 /* get a (unique) handle. open a policy on it. */
2878 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
2879 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2881 return NT_STATUS_NO_PROBLEMO;
2884 /*********************************************************************
2885 _samr_unknown_2d
2886 *********************************************************************/
2888 uint32 _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
2890 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
2891 return False;