make proto
[Samba/gbeck.git] / source / rpc_server / srv_samr_nt.c
blob2434fad74addaa9172120d2ba943ad67f3769b92
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));
1245 if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1246 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
1247 r_u->status = NT_STATUS_WRONG_PASSWORD;
1249 init_samr_r_chgpasswd_user(r_u, r_u->status);
1251 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1253 return r_u->status;
1256 /*******************************************************************
1257 makes a SAMR_R_LOOKUP_RIDS structure.
1258 ********************************************************************/
1260 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1261 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1263 uint32 i;
1264 UNIHDR *hdr_name=NULL;
1265 UNISTR2 *uni_name=NULL;
1267 *pp_uni_name = NULL;
1268 *pp_hdr_name = NULL;
1270 if (num_names != 0) {
1271 hdr_name = (UNIHDR *)talloc(ctx, sizeof(UNIHDR)*num_names);
1272 if (hdr_name == NULL)
1273 return False;
1275 uni_name = (UNISTR2 *)talloc(ctx,sizeof(UNISTR2)*num_names);
1276 if (uni_name == NULL)
1277 return False;
1280 for (i = 0; i < num_names; i++) {
1281 int len = names[i] != NULL ? strlen(names[i]) : 0;
1282 DEBUG(10, ("names[%d]:%s\n", i, names[i]));
1283 init_uni_hdr(&hdr_name[i], len);
1284 init_unistr2(&uni_name[i], names[i], len);
1287 *pp_uni_name = uni_name;
1288 *pp_hdr_name = hdr_name;
1290 return True;
1293 /*******************************************************************
1294 _samr_lookup_rids
1295 ********************************************************************/
1297 uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1299 fstring group_names[MAX_SAM_ENTRIES];
1300 uint32 group_attrs[MAX_SAM_ENTRIES];
1301 UNIHDR *hdr_name = NULL;
1302 UNISTR2 *uni_name = NULL;
1303 DOM_SID pol_sid;
1304 int num_rids = q_u->num_rids1;
1305 int i;
1307 r_u->status = NT_STATUS_NOPROBLEMO;
1309 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1311 /* find the policy handle. open a policy on it. */
1312 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid))
1313 return NT_STATUS_INVALID_HANDLE;
1315 if (num_rids > MAX_SAM_ENTRIES) {
1316 num_rids = MAX_SAM_ENTRIES;
1317 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1320 r_u->status = NT_STATUS_NONE_MAPPED;
1322 for (i = 0; i < num_rids; i++) {
1323 fstring tmpname;
1324 fstring domname;
1325 DOM_SID sid;
1326 enum SID_NAME_USE type;
1328 group_attrs[i] = SID_NAME_UNKNOWN;
1329 *group_names[i] = '\0';
1331 if (sid_equal(&pol_sid, &global_sam_sid)) {
1332 sid_copy(&sid, &pol_sid);
1333 sid_append_rid(&sid, q_u->rid[i]);
1335 if (lookup_sid(&sid, domname, tmpname, &type)) {
1336 r_u->status = NT_STATUS_NOPROBLEMO;
1337 group_attrs[i] = (uint32)type;
1338 fstrcpy(group_names[i],tmpname);
1343 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1344 return NT_STATUS_NO_MEMORY;
1346 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1348 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1350 return r_u->status;
1353 /*******************************************************************
1354 _api_samr_open_user. Safe - gives out no passwd info.
1355 ********************************************************************/
1357 uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1359 SAM_ACCOUNT *sampass;
1360 DOM_SID sid;
1361 POLICY_HND domain_pol = q_u->domain_pol;
1362 uint32 user_rid = q_u->user_rid;
1363 POLICY_HND *user_pol = &r_u->user_pol;
1364 struct samr_info *info = NULL;
1366 r_u->status = NT_STATUS_NO_PROBLEMO;
1368 /* find the domain policy handle. */
1369 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1370 return NT_STATUS_INVALID_HANDLE;
1372 become_root();
1373 sampass = pdb_getsampwrid(user_rid);
1374 unbecome_root();
1376 /* check that the RID exists in our domain. */
1377 if (sampass == NULL)
1378 return NT_STATUS_NO_SUCH_USER;
1380 samr_clear_sam_passwd(sampass);
1382 /* Get the domain SID stored in the domain policy */
1383 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1384 return NT_STATUS_INVALID_HANDLE;
1386 /* append the user's RID to it */
1387 if(!sid_append_rid(&sid, user_rid))
1388 return NT_STATUS_NO_SUCH_USER;
1390 /* associate the user's SID with the new handle. */
1391 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1392 return NT_STATUS_NO_MEMORY;
1394 ZERO_STRUCTP(info);
1395 info->sid = sid;
1397 /* get a (unique) handle. open a policy on it. */
1398 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1399 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1401 return r_u->status;
1404 /*************************************************************************
1405 get_user_info_10. Safe. Only gives out acb bits.
1406 *************************************************************************/
1408 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1410 SAM_ACCOUNT *smbpass;
1412 if (!pdb_rid_is_user(user_rid)) {
1413 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1414 return False;
1417 become_root();
1418 smbpass = pdb_getsampwrid(user_rid);
1419 unbecome_root();
1421 if (smbpass == NULL) {
1422 DEBUG(4,("User 0x%x not found\n", user_rid));
1423 return False;
1426 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1428 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1430 return True;
1433 /*************************************************************************
1434 get_user_info_12. OK - this is the killer as it gives out password info.
1435 Ensure that this is only allowed on an encrypted connection with a root
1436 user. JRA.
1437 *************************************************************************/
1439 static uint32 get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
1441 SAM_ACCOUNT *smbpass;
1443 if (!p->ntlmssp_auth_validated)
1444 return NT_STATUS_ACCESS_DENIED;
1446 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1447 return NT_STATUS_ACCESS_DENIED;
1450 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1453 smbpass = pdb_getsampwrid(user_rid);
1455 if (smbpass == NULL) {
1456 DEBUG(4, ("User 0x%x not found\n", user_rid));
1457 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1460 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1462 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED)
1463 return NT_STATUS_ACCOUNT_DISABLED;
1465 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1467 return NT_STATUS_NOPROBLEMO;
1470 /*************************************************************************
1471 get_user_info_21
1472 *************************************************************************/
1474 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1476 SAM_ACCOUNT *sampass;
1478 if (!pdb_rid_is_user(user_rid)) {
1479 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1480 return False;
1483 become_root();
1484 sampass = pdb_getsampwrid(user_rid);
1485 unbecome_root();
1487 if (sampass == NULL) {
1488 DEBUG(4,("User 0x%x not found\n", user_rid));
1489 return False;
1492 samr_clear_sam_passwd(sampass);
1494 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1496 init_sam_user_info21A(id21, sampass);
1498 return True;
1501 /*******************************************************************
1502 _samr_query_userinfo
1503 ********************************************************************/
1505 uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1507 SAM_USERINFO_CTR *ctr;
1508 uint32 rid = 0;
1509 struct samr_info *info = NULL;
1511 r_u->status=NT_STATUS_NO_PROBLEMO;
1513 /* search for the handle */
1514 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1515 return NT_STATUS_INVALID_HANDLE;
1517 /* find the user's rid */
1518 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1519 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1521 DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
1523 ctr = (SAM_USERINFO_CTR *)talloc(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1524 if (!ctr)
1525 return NT_STATUS_NO_MEMORY;
1527 ZERO_STRUCTP(ctr);
1529 /* ok! user info levels (lots: see MSDEV help), off we go... */
1530 ctr->switch_value = q_u->switch_value;
1532 switch (q_u->switch_value) {
1533 case 0x10:
1534 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1535 if (ctr->info.id10 == NULL)
1536 return NT_STATUS_NO_MEMORY;
1538 if (!get_user_info_10(ctr->info.id10, rid))
1539 return NT_STATUS_NO_SUCH_USER;
1540 break;
1542 #if 0
1543 /* whoops - got this wrong. i think. or don't understand what's happening. */
1544 case 0x11:
1546 NTTIME expire;
1547 info = (void *)&id11;
1549 expire.low = 0xffffffff;
1550 expire.high = 0x7fffffff;
1552 ctr->info.id = (SAM_USER_INFO_11 *)talloc(p->mem_ctx,
1553 sizeof
1554 (*ctr->
1555 info.
1556 id11));
1557 init_sam_user_info11(ctr->info.id11, &expire,
1558 "BROOKFIELDS$", /* name */
1559 0x03ef, /* user rid */
1560 0x201, /* group rid */
1561 0x0080); /* acb info */
1563 break;
1565 #endif
1567 case 0x12:
1568 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1569 if (ctr->info.id12 == NULL)
1570 return NT_STATUS_NO_MEMORY;
1572 if ((r_u->status = get_user_info_12(p, ctr->info.id12, rid)) != NT_STATUS_NOPROBLEMO)
1573 return r_u->status;
1574 break;
1576 case 21:
1577 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1578 if (ctr->info.id21 == NULL)
1579 return NT_STATUS_NO_MEMORY;
1580 if (!get_user_info_21(ctr->info.id21, rid))
1581 return NT_STATUS_NO_SUCH_USER;
1582 break;
1584 default:
1585 return NT_STATUS_INVALID_INFO_CLASS;
1588 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1590 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1592 return r_u->status;
1595 /*******************************************************************
1596 samr_reply_query_usergroups
1597 ********************************************************************/
1599 uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1601 struct sam_passwd *sam_pass;
1602 DOM_GID *gids = NULL;
1603 int num_groups = 0;
1604 pstring groups;
1605 uint32 rid;
1606 struct samr_info *info = NULL;
1608 r_u->status = NT_STATUS_NO_PROBLEMO;
1610 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1612 /* find the policy handle. open a policy on it. */
1613 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1614 return NT_STATUS_INVALID_HANDLE;
1616 /* find the user's rid */
1617 if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
1618 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1620 become_root();
1621 sam_pass = pdb_getsampwrid(rid);
1622 unbecome_root();
1624 if (sam_pass == NULL)
1625 return NT_STATUS_NO_SUCH_USER;
1627 samr_clear_sam_passwd(sam_pass);
1629 get_domain_user_groups(groups, pdb_get_username(sam_pass));
1630 gids = NULL;
1631 num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
1633 /* construct the response. lkclXXXX: gids are not copied! */
1634 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1636 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1638 return r_u->status;
1641 /*******************************************************************
1642 _samr_query_dom_info
1643 ********************************************************************/
1645 uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1647 SAM_UNK_CTR *ctr;
1649 if ((ctr = (SAM_UNK_CTR *)talloc(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
1650 return NT_STATUS_NO_MEMORY;
1652 ZERO_STRUCTP(ctr);
1654 r_u->status = NT_STATUS_NO_PROBLEMO;
1656 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1658 /* find the policy handle. open a policy on it. */
1659 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
1660 return NT_STATUS_INVALID_HANDLE;
1662 switch (q_u->switch_value) {
1663 case 0x01:
1664 init_unk_info1(&ctr->info.inf1);
1665 break;
1666 case 0x02:
1667 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
1668 init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL));
1669 break;
1670 case 0x03:
1671 init_unk_info3(&ctr->info.inf3);
1672 break;
1673 case 0x06:
1674 init_unk_info6(&ctr->info.inf6);
1675 break;
1676 case 0x07:
1677 init_unk_info7(&ctr->info.inf7);
1678 break;
1679 case 0x0c:
1680 init_unk_info12(&ctr->info.inf12);
1681 break;
1682 default:
1683 return NT_STATUS_INVALID_INFO_CLASS;
1686 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_NOPROBLEMO);
1688 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
1690 return r_u->status;
1693 /*******************************************************************
1694 _api_samr_create_user
1695 ********************************************************************/
1697 uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
1699 SAM_ACCOUNT *sam_pass;
1700 fstring mach_acct;
1701 pstring err_str;
1702 pstring msg_str;
1703 int local_flags=0;
1704 DOM_SID sid;
1705 pstring add_script;
1706 POLICY_HND dom_pol = q_u->domain_pol;
1707 UNISTR2 user_account = q_u->uni_name;
1708 uint16 acb_info = q_u->acb_info;
1709 POLICY_HND *user_pol = &r_u->user_pol;
1710 struct samr_info *info = NULL;
1712 /* find the policy handle. open a policy on it. */
1713 if (!find_policy_by_hnd(p, &dom_pol, NULL))
1714 return NT_STATUS_INVALID_HANDLE;
1716 /* find the machine account: tell the caller if it exists.
1717 lkclXXXX i have *no* idea if this is a problem or not
1718 or even if you are supposed to construct a different
1719 reply if the account already exists...
1722 fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
1723 strlower(mach_acct);
1725 become_root();
1726 sam_pass = pdb_getsampwnam(mach_acct);
1727 unbecome_root();
1728 if (sam_pass != NULL) {
1729 /* machine account exists: say so */
1730 return NT_STATUS_USER_EXISTS;
1733 local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
1734 local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
1737 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
1738 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
1739 * that only people with write access to the smbpasswd file will be able
1740 * to create a user. JRA.
1744 * add the user in the /etc/passwd file or the unix authority system.
1745 * We don't check if the smb_create_user() function succed or not for 2 reasons:
1746 * a) local_password_change() checks for us if the /etc/passwd account really exists
1747 * b) smb_create_user() would return an error if the account already exists
1748 * and as it could return an error also if it can't create the account, it would be tricky.
1750 * So we go the easy way, only check after if the account exists.
1751 * JFM (2/3/2001), to clear any possible bad understanding (-:
1754 pstrcpy(add_script, lp_adduser_script());
1756 if(*add_script)
1757 smb_create_user(mach_acct, NULL);
1759 /* add the user in the smbpasswd file or the Samba authority database */
1760 if (!local_password_change(mach_acct, local_flags, NULL, err_str,
1761 sizeof(err_str), msg_str, sizeof(msg_str)))
1763 DEBUG(0, ("%s\n", err_str));
1764 close_policy_hnd(p, user_pol);
1765 return NT_STATUS_ACCESS_DENIED;
1768 become_root();
1769 sam_pass = pdb_getsampwnam(mach_acct);
1770 unbecome_root();
1771 if (sam_pass == NULL) {
1772 /* account doesn't exist: say so */
1773 close_policy_hnd(p, user_pol);
1774 return NT_STATUS_ACCESS_DENIED;
1777 /* Get the domain SID stored in the domain policy */
1778 if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
1779 close_policy_hnd(p, user_pol);
1780 return NT_STATUS_INVALID_HANDLE;
1783 /* append the user's RID to it */
1784 if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
1785 close_policy_hnd(p, user_pol);
1786 return NT_STATUS_NO_SUCH_USER;
1789 /* associate the user's SID with the new handle. */
1790 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1791 return NT_STATUS_NO_MEMORY;
1793 ZERO_STRUCTP(info);
1794 info->sid = sid;
1796 /* get a (unique) handle. open a policy on it. */
1797 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1798 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1800 r_u->user_rid=sam_pass->user_rid;
1801 r_u->unknown_0 = 0x000703ff;
1803 return NT_STATUS_NO_PROBLEMO;
1806 /*******************************************************************
1807 samr_reply_connect_anon
1808 ********************************************************************/
1810 uint32 _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
1812 struct samr_info *info = NULL;
1814 /* set up the SAMR connect_anon response */
1816 r_u->status = NT_STATUS_NO_PROBLEMO;
1818 /* associate the user's SID with the new handle. */
1819 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1820 return NT_STATUS_NO_MEMORY;
1822 ZERO_STRUCTP(info);
1823 info->status = q_u->unknown_0;
1825 /* get a (unique) handle. open a policy on it. */
1826 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
1827 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1829 return r_u->status;
1832 /*******************************************************************
1833 samr_reply_connect
1834 ********************************************************************/
1836 uint32 _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
1838 struct samr_info *info = NULL;
1840 DEBUG(5,("_samr_connect: %d\n", __LINE__));
1842 r_u->status = NT_STATUS_NO_PROBLEMO;
1844 /* associate the user's SID with the new handle. */
1845 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1846 return NT_STATUS_NO_MEMORY;
1848 ZERO_STRUCTP(info);
1849 info->status = q_u->access_mask;
1851 /* get a (unique) handle. open a policy on it. */
1852 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
1853 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1855 DEBUG(5,("_samr_connect: %d\n", __LINE__));
1857 return r_u->status;
1860 /**********************************************************************
1861 api_samr_lookup_domain
1862 **********************************************************************/
1864 uint32 _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
1866 r_u->status = NT_STATUS_NO_PROBLEMO;
1868 if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
1869 return NT_STATUS_INVALID_HANDLE;
1871 /* assume the domain name sent is our global_myname and
1872 send global_sam_sid */
1873 init_samr_r_lookup_domain(r_u, &global_sam_sid, r_u->status);
1875 return r_u->status;
1878 /******************************************************************
1879 makes a SAMR_R_ENUM_DOMAINS structure.
1880 ********************************************************************/
1882 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
1883 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
1885 uint32 i;
1886 SAM_ENTRY *sam;
1887 UNISTR2 *uni_name;
1889 DEBUG(5, ("make_enum_domains\n"));
1891 *pp_sam = NULL;
1892 *pp_uni_name = NULL;
1894 if (num_sam_entries == 0)
1895 return True;
1897 sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
1898 uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
1900 if (sam == NULL || uni_name == NULL)
1901 return False;
1903 for (i = 0; i < num_sam_entries; i++) {
1904 int len = doms[i] != NULL ? strlen(doms[i]) : 0;
1906 init_sam_entry(&sam[i], len, 0);
1907 init_unistr2(&uni_name[i], doms[i], len);
1910 *pp_sam = sam;
1911 *pp_uni_name = uni_name;
1913 return True;
1916 /**********************************************************************
1917 api_samr_enum_domains
1918 **********************************************************************/
1920 uint32 _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
1922 uint32 num_entries = 2;
1923 fstring dom[2];
1925 r_u->status = NT_STATUS_NO_PROBLEMO;
1927 fstrcpy(dom[0],global_myworkgroup);
1928 fstrcpy(dom[1],"Builtin");
1930 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
1931 return NT_STATUS_NO_MEMORY;
1933 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
1935 return r_u->status;
1938 /*******************************************************************
1939 api_samr_open_alias
1940 ********************************************************************/
1942 uint32 _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
1944 DOM_SID sid;
1945 POLICY_HND domain_pol = q_u->dom_pol;
1946 uint32 alias_rid = q_u->rid_alias;
1947 POLICY_HND *alias_pol = &r_u->pol;
1948 struct samr_info *info = NULL;
1950 r_u->status = NT_STATUS_NO_PROBLEMO;
1952 /* get the domain policy. */
1953 if (!find_policy_by_hnd(p, &domain_pol, NULL))
1954 return NT_STATUS_INVALID_HANDLE;
1956 /* Get the domain SID stored in the domain policy */
1957 if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
1958 return NT_STATUS_INVALID_HANDLE;
1960 /* append the alias' RID to it */
1961 if(!sid_append_rid(&sid, alias_rid))
1962 return NT_STATUS_NO_SUCH_USER;
1965 * we should check if the rid really exist !!!
1966 * JFM.
1969 /* associate the user's SID with the new handle. */
1970 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
1971 return NT_STATUS_NO_MEMORY;
1973 ZERO_STRUCTP(info);
1974 info->sid = sid;
1976 /* get a (unique) handle. open a policy on it. */
1977 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
1978 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1980 return r_u->status;
1983 /*******************************************************************
1984 set_user_info_10
1985 ********************************************************************/
1987 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
1989 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
1991 if (id10 == NULL) {
1992 DEBUG(5, ("set_user_info_10: NULL id10\n"));
1993 return False;
1996 pwd = pdb_getsampwrid(rid);
1997 if (!pwd)
1998 return False;
2000 pdb_set_acct_ctrl(pwd, id10->acb_info);
2002 if(!pdb_update_sam_account(pwd, True))
2003 return False;
2005 return True;
2008 /*******************************************************************
2009 set_user_info_12
2010 ********************************************************************/
2012 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
2014 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2016 if (pwd == NULL)
2017 return False;
2019 if (id12 == NULL) {
2020 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2021 return False;
2024 pdb_set_lanman_passwd (pwd, id12->lm_pwd);
2025 pdb_set_nt_passwd (pwd, id12->nt_pwd);
2027 if(!pdb_update_sam_account(pwd, True))
2028 return False;
2030 return True;
2033 /*******************************************************************
2034 set_user_info_21
2035 ********************************************************************/
2037 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
2039 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2040 SAM_ACCOUNT new_pwd;
2042 if (id21 == NULL) {
2043 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2044 return False;
2047 if (pwd == NULL)
2048 return False;
2050 /* we make a copy so that we can modify stuff */
2051 copy_sam_passwd(&new_pwd, pwd);
2052 copy_id21_to_sam_passwd(&new_pwd, id21);
2055 * The funny part about the previous two calls is
2056 * that pwd still has the password hashes from the
2057 * passdb entry. These have not been updated from
2058 * id21. I don't know if they need to be set. --jerry
2061 /* write the change out */
2062 if(!pdb_update_sam_account(&new_pwd, True))
2063 return False;
2065 return True;
2068 /*******************************************************************
2069 set_user_info_23
2070 ********************************************************************/
2072 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
2074 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2075 SAM_ACCOUNT new_pwd;
2076 uint8 nt_hash[16];
2077 uint8 lm_hash[16];
2078 pstring buf;
2079 uint32 len;
2080 uint16 acct_ctrl;
2082 if (id23 == NULL) {
2083 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2084 return False;
2087 if (pwd == NULL)
2088 return False;
2090 acct_ctrl = pdb_get_acct_ctrl(pwd);
2092 copy_sam_passwd(&new_pwd, pwd);
2093 copy_id23_to_sam_passwd(&new_pwd, id23);
2095 if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len))
2096 return False;
2098 nt_lm_owf_gen(buf, nt_hash, lm_hash);
2100 pdb_set_lanman_passwd (&new_pwd, lm_hash);
2101 pdb_set_nt_passwd (&new_pwd, nt_hash);
2103 /* if it's a trust account, don't update /etc/passwd */
2104 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2105 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2106 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2107 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2108 } else {
2109 /* update the UNIX password */
2110 /* update the UNIX password */
2111 if (lp_unix_password_sync() )
2112 if(!chgpasswd(pdb_get_username(&new_pwd), "", buf, True))
2113 return False;
2116 memset(buf, 0, sizeof(buf));
2118 if(!pdb_update_sam_account(&new_pwd, True))
2119 return False;
2121 return True;
2124 /*******************************************************************
2125 set_user_info_24
2126 ********************************************************************/
2128 static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid)
2130 SAM_ACCOUNT *pwd = pdb_getsampwrid(rid);
2131 uchar nt_hash[16];
2132 uchar lm_hash[16];
2133 uint32 len;
2134 pstring buf;
2135 uint16 acct_ctrl;
2137 if (pwd == NULL)
2138 return False;
2140 acct_ctrl = pdb_get_acct_ctrl(pwd);
2142 memset(buf, 0, sizeof(buf));
2144 if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len))
2145 return False;
2147 DEBUG(5,("set_user_info_24:nt_lm_owf_gen\n"));
2149 nt_lm_owf_gen(buf, nt_hash, lm_hash);
2151 pdb_set_lanman_passwd (pwd, lm_hash);
2152 pdb_set_nt_passwd (pwd, nt_hash);
2154 /* if it's a trust account, don't update /etc/passwd */
2155 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2156 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2157 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2158 DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
2159 } else {
2160 /* update the UNIX password */
2161 if (lp_unix_password_sync())
2162 if(!chgpasswd(pdb_get_username(pwd), "", buf, True))
2163 return False;
2166 memset(buf, 0, sizeof(buf));
2168 DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
2170 /* update the SAMBA password */
2171 if(!pdb_update_sam_account(pwd, True))
2172 return False;
2174 return True;
2177 /*******************************************************************
2178 samr_reply_set_userinfo
2179 ********************************************************************/
2181 uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2183 uint32 rid = 0x0;
2184 DOM_SID sid;
2185 struct current_user user;
2186 SAM_ACCOUNT *sam_pass;
2187 unsigned char sess_key[16];
2188 POLICY_HND *pol = &q_u->pol;
2189 uint16 switch_value = q_u->switch_value;
2190 SAM_USERINFO_CTR *ctr = q_u->ctr;
2192 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2194 r_u->status = NT_STATUS_NOPROBLEMO;
2196 if (p->ntlmssp_auth_validated) {
2197 memcpy(&user, &p->pipe_user, sizeof(user));
2198 } else {
2199 extern struct current_user current_user;
2200 memcpy(&user, &current_user, sizeof(user));
2203 /* find the policy handle. open a policy on it. */
2204 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2205 return NT_STATUS_INVALID_HANDLE;
2207 sid_split_rid(&sid, &rid);
2209 DEBUG(5, ("_samr_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
2211 if (ctr == NULL) {
2212 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2213 return NT_STATUS_INVALID_INFO_CLASS;
2218 * We need the NT hash of the user who is changing the user's password.
2219 * This NT hash is used to generate a "user session key"
2220 * This "user session key" is in turn used to encrypt/decrypt the user's password.
2223 become_root();
2224 sam_pass = pdb_getsampwuid(user.uid);
2225 unbecome_root();
2226 if(sam_pass == NULL) {
2227 DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
2228 return NT_STATUS_ACCESS_DENIED;
2231 memset(sess_key, '\0', 16);
2232 mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
2234 /* ok! user info levels (lots: see MSDEV help), off we go... */
2235 switch (switch_value) {
2236 case 0x12:
2237 if (!set_user_info_12(ctr->info.id12, rid))
2238 return NT_STATUS_ACCESS_DENIED;
2239 break;
2241 case 24:
2242 SamOEMhash(ctr->info.id24->pass, sess_key, 1);
2243 if (!set_user_info_24(ctr->info.id24, rid))
2244 return NT_STATUS_ACCESS_DENIED;
2245 break;
2247 case 23:
2248 SamOEMhash(ctr->info.id23->pass, sess_key, 1);
2249 if (!set_user_info_23(ctr->info.id23, rid))
2250 return NT_STATUS_ACCESS_DENIED;
2251 break;
2253 default:
2254 return NT_STATUS_INVALID_INFO_CLASS;
2257 return r_u->status;
2260 /*******************************************************************
2261 samr_reply_set_userinfo2
2262 ********************************************************************/
2264 uint32 _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
2266 DOM_SID sid;
2267 uint32 rid = 0x0;
2268 SAM_USERINFO_CTR *ctr = q_u->ctr;
2269 POLICY_HND *pol = &q_u->pol;
2270 uint16 switch_value = q_u->switch_value;
2272 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
2274 r_u->status = NT_STATUS_NOPROBLEMO;
2276 /* find the policy handle. open a policy on it. */
2277 if (!get_lsa_policy_samr_sid(p, pol, &sid))
2278 return NT_STATUS_INVALID_HANDLE;
2280 sid_split_rid(&sid, &rid);
2282 DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
2284 if (ctr == NULL) {
2285 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
2286 return NT_STATUS_INVALID_INFO_CLASS;
2289 switch_value=ctr->switch_value;
2291 /* ok! user info levels (lots: see MSDEV help), off we go... */
2292 switch (switch_value) {
2293 case 21:
2294 if (!set_user_info_21(ctr->info.id21, rid))
2295 return NT_STATUS_ACCESS_DENIED;
2296 break;
2297 case 16:
2298 if (!set_user_info_10(ctr->info.id10, rid))
2299 return NT_STATUS_ACCESS_DENIED;
2300 break;
2301 case 18:
2302 /* Used by AS/U JRA. */
2303 if (!set_user_info_12(ctr->info.id12, rid))
2304 return NT_STATUS_ACCESS_DENIED;
2305 break;
2306 default:
2307 return NT_STATUS_INVALID_INFO_CLASS;
2310 return r_u->status;
2313 /*********************************************************************
2314 _samr_query_aliasmem
2315 *********************************************************************/
2317 uint32 _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
2319 uint32 *rid=NULL;
2320 int num_rids;
2322 num_rids = 1;
2323 rid=(uint32 *)talloc(p->mem_ctx, num_rids*sizeof(uint32));
2324 if (rid==NULL)
2325 return NT_STATUS_NO_MEMORY;
2327 /* until i see a real useraliases query, we fack one up */
2329 rid[0] = BUILTIN_ALIAS_RID_USERS;
2331 init_samr_r_query_useraliases(r_u, num_rids, rid, NT_STATUS_NO_PROBLEMO);
2333 return NT_STATUS_NO_PROBLEMO;
2337 /*********************************************************************
2338 _samr_query_aliasmem
2339 *********************************************************************/
2341 uint32 _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
2343 int i;
2345 GROUP_MAP map;
2346 int num_uids = 0;
2347 DOM_SID2 *sid;
2348 uid_t *uid=NULL;
2350 DOM_SID alias_sid;
2351 DOM_SID als_sid;
2352 uint32 alias_rid;
2353 fstring alias_sid_str;
2354 DOM_SID temp_sid;
2357 /* find the policy handle. open a policy on it. */
2358 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2359 return NT_STATUS_INVALID_HANDLE;
2361 sid_copy(&als_sid, &alias_sid);
2362 sid_to_string(alias_sid_str, &alias_sid);
2363 sid_split_rid(&alias_sid, &alias_rid);
2365 DEBUG(10, ("sid is %s\n", alias_sid_str));
2367 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
2368 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
2369 if(!get_builtin_group_from_sid(als_sid, &map))
2370 return NT_STATUS_NO_SUCH_ALIAS;
2371 } else {
2372 if (sid_equal(&alias_sid, &global_sam_sid)) {
2373 DEBUG(10, ("lookup on Server SID\n"));
2374 if(!get_local_group_from_sid(als_sid, &map))
2375 return NT_STATUS_NO_SUCH_ALIAS;
2379 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2380 return NT_STATUS_NO_SUCH_ALIAS;
2382 DEBUG(10, ("sid is %s\n", alias_sid_str));
2383 sid = (DOM_SID2 *)talloc(p->mem_ctx, sizeof(DOM_SID2) * num_uids);
2384 if (sid == NULL)
2385 return NT_STATUS_NO_SUCH_ALIAS;
2387 for (i = 0; i < num_uids; i++) {
2388 sid_copy(&temp_sid, &global_sam_sid);
2389 sid_append_rid(&temp_sid, pdb_uid_to_user_rid(uid[i]));
2391 init_dom_sid2(&sid[i], &temp_sid);
2394 DEBUG(10, ("sid is %s\n", alias_sid_str));
2395 init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_NO_PROBLEMO);
2397 return NT_STATUS_NOPROBLEMO;
2400 /*********************************************************************
2401 _samr_query_groupmem
2402 *********************************************************************/
2404 uint32 _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
2406 int num_uids = 0;
2407 int i;
2408 DOM_SID group_sid;
2409 uint32 group_rid;
2410 fstring group_sid_str;
2411 uid_t *uid=NULL;
2413 GROUP_MAP map;
2415 uint32 *rid=NULL;
2416 uint32 *attr=NULL;
2419 /* find the policy handle. open a policy on it. */
2420 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid))
2421 return NT_STATUS_INVALID_HANDLE;
2423 /* todo: change to use sid_compare_front */
2425 sid_split_rid(&group_sid, &group_rid);
2426 sid_to_string(group_sid_str, &group_sid);
2427 DEBUG(10, ("sid is %s\n", group_sid_str));
2429 /* can we get a query for an SID outside our domain ? */
2430 if (!sid_equal(&group_sid, &global_sam_sid))
2431 return NT_STATUS_NO_SUCH_GROUP;
2433 sid_append_rid(&group_sid, group_rid);
2434 DEBUG(10, ("lookup on Domain SID\n"));
2436 if(!get_domain_group_from_sid(group_sid, &map))
2437 return NT_STATUS_NO_SUCH_GROUP;
2439 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2440 return NT_STATUS_NO_SUCH_GROUP;
2442 rid=talloc(p->mem_ctx, sizeof(uint32)*num_uids);
2443 attr=talloc(p->mem_ctx, sizeof(uint32)*num_uids);
2445 if (rid==NULL || attr==NULL)
2446 return NT_STATUS_NO_MEMORY;
2448 for (i=0; i<num_uids; i++) {
2449 rid[i]=pdb_uid_to_user_rid(uid[i]);
2450 attr[i] = SID_NAME_USER;
2453 init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_NOPROBLEMO);
2455 return NT_STATUS_NOPROBLEMO;
2458 /*********************************************************************
2459 _samr_add_aliasmem
2460 *********************************************************************/
2462 uint32 _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
2464 DOM_SID alias_sid;
2465 fstring alias_sid_str;
2466 uid_t uid;
2467 struct passwd *pwd;
2468 struct group *grp;
2469 fstring grp_name;
2470 uint32 rid;
2471 GROUP_MAP map;
2473 /* Find the policy handle. Open a policy on it. */
2474 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid))
2475 return NT_STATUS_INVALID_HANDLE;
2477 sid_to_string(alias_sid_str, &alias_sid);
2478 DEBUG(10, ("sid is %s\n", alias_sid_str));
2480 if (sid_compare(&alias_sid, &global_sam_sid)>0) {
2481 DEBUG(10, ("adding member on Server SID\n"));
2482 if(!get_local_group_from_sid(alias_sid, &map))
2483 return NT_STATUS_NO_SUCH_ALIAS;
2485 } else {
2486 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
2487 DEBUG(10, ("adding member on BUILTIN SID\n"));
2488 if( !get_builtin_group_from_sid(alias_sid, &map))
2489 return NT_STATUS_NO_SUCH_ALIAS;
2491 } else
2492 return NT_STATUS_NO_SUCH_ALIAS;
2495 sid_split_rid(&q_u->sid.sid, &rid);
2496 uid=pdb_user_rid_to_uid(rid);
2498 if ((pwd=getpwuid(uid)) == NULL)
2499 return NT_STATUS_NO_SUCH_USER;
2501 if ((grp=getgrgid(map.gid)) == NULL)
2502 return NT_STATUS_NO_SUCH_ALIAS;
2504 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2505 fstrcpy(grp_name, grp->gr_name);
2507 /* if the user is already in the group */
2508 if(user_in_group_list(pwd->pw_name, grp_name))
2509 return NT_STATUS_MEMBER_IN_ALIAS;
2512 * ok, the group exist, the user exist, the user is not in the group,
2513 * we can (finally) add it to the group !
2515 smb_add_user_group(grp_name, pwd->pw_name);
2517 /* check if the user has been added then ... */
2518 if(!user_in_group_list(pwd->pw_name, grp_name))
2519 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
2521 return NT_STATUS_NOPROBLEMO;
2524 /*********************************************************************
2525 _samr_del_aliasmem
2526 *********************************************************************/
2528 uint32 _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
2530 DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
2531 return False;
2534 /*********************************************************************
2535 _samr_add_groupmem
2536 *********************************************************************/
2538 uint32 _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
2540 DOM_SID group_sid;
2541 fstring group_sid_str;
2542 struct passwd *pwd;
2543 struct group *grp;
2544 fstring grp_name;
2545 GROUP_MAP map;
2547 /* Find the policy handle. Open a policy on it. */
2548 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2549 return NT_STATUS_INVALID_HANDLE;
2551 sid_to_string(group_sid_str, &group_sid);
2552 DEBUG(10, ("sid is %s\n", group_sid_str));
2554 if (sid_compare(&group_sid, &global_sam_sid)<=0)
2555 return NT_STATUS_NO_SUCH_GROUP;
2557 DEBUG(10, ("lookup on Domain SID\n"));
2559 if(!get_domain_group_from_sid(group_sid, &map))
2560 return NT_STATUS_NO_SUCH_GROUP;
2562 if ((pwd=getpwuid(pdb_user_rid_to_uid(q_u->rid))) ==NULL)
2563 return NT_STATUS_NO_SUCH_USER;
2565 if ((grp=getgrgid(map.gid)) == NULL)
2566 return NT_STATUS_NO_SUCH_GROUP;
2568 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
2569 fstrcpy(grp_name, grp->gr_name);
2571 /* if the user is already in the group */
2572 if(user_in_group_list(pwd->pw_name, grp_name))
2573 return NT_STATUS_MEMBER_IN_GROUP;
2576 * ok, the group exist, the user exist, the user is not in the group,
2578 * we can (finally) add it to the group !
2581 smb_add_user_group(grp_name, pwd->pw_name);
2583 /* check if the user has been added then ... */
2584 if(!user_in_group_list(pwd->pw_name, grp_name))
2585 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
2587 return NT_STATUS_NOPROBLEMO;
2590 /*********************************************************************
2591 _samr_del_groupmem
2592 *********************************************************************/
2594 uint32 _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
2596 DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
2597 return False;
2600 /*********************************************************************
2601 _samr_delete_dom_user
2602 *********************************************************************/
2604 uint32 _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
2606 DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
2607 return False;
2610 /*********************************************************************
2611 _samr_delete_dom_group
2612 *********************************************************************/
2614 uint32 _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
2616 DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
2617 return False;
2620 /*********************************************************************
2621 _samr_delete_dom_alias
2622 *********************************************************************/
2624 uint32 _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
2626 DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
2627 return False;
2630 /*********************************************************************
2631 _samr_create_dom_group
2632 *********************************************************************/
2634 uint32 _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
2636 DOM_SID dom_sid;
2637 DOM_SID info_sid;
2638 fstring name;
2639 fstring sid_string;
2640 struct group *grp;
2641 struct samr_info *info;
2643 /* Find the policy handle. Open a policy on it. */
2644 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid))
2645 return NT_STATUS_INVALID_HANDLE;
2647 if (!sid_equal(&dom_sid, &global_sam_sid))
2648 return NT_STATUS_ACCESS_DENIED;
2650 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2652 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
2654 /* check if group already exist */
2655 if ((grp=getgrnam(name)) != NULL)
2656 return NT_STATUS_GROUP_EXISTS;
2658 /* we can create the UNIX group */
2659 smb_create_group(name);
2661 /* check if the group has been successfully created */
2662 if ((grp=getgrnam(name)) == NULL)
2663 return NT_STATUS_ACCESS_DENIED;
2665 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
2667 /* add the group to the mapping table */
2668 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, SE_PRIV_NONE))
2669 return NT_STATUS_ACCESS_DENIED;
2671 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2672 return NT_STATUS_NO_MEMORY;
2674 ZERO_STRUCTP(info);
2676 sid_copy(&info_sid, &global_sam_sid);
2677 sid_append_rid(&info->sid, r_u->rid);
2678 sid_to_string(sid_string, &info->sid);
2680 /* get a (unique) handle. open a policy on it. */
2681 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
2682 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2684 return NT_STATUS_NOPROBLEMO;
2687 /*********************************************************************
2688 _samr_create_dom_alias
2689 *********************************************************************/
2691 uint32 _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
2693 DOM_SID dom_sid;
2694 fstring name;
2695 fstring sid_string;
2696 struct group *grp;
2697 struct samr_info *info;
2699 /* Find the policy handle. Open a policy on it. */
2700 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid))
2701 return NT_STATUS_INVALID_HANDLE;
2703 if (!sid_equal(&dom_sid, &global_sam_sid))
2704 return NT_STATUS_ACCESS_DENIED;
2706 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
2708 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
2710 /* check if group already exists */
2711 if ( (grp=getgrnam(name)) != NULL)
2712 return NT_STATUS_GROUP_EXISTS;
2714 /* we can create the UNIX group */
2715 smb_create_group(name);
2717 /* check if the group has been successfully created */
2718 if ((grp=getgrnam(name)) == NULL)
2719 return NT_STATUS_ACCESS_DENIED;
2721 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
2723 /* add the group to the mapping table */
2724 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, NULL, NULL, SE_PRIV_NONE))
2725 return NT_STATUS_ACCESS_DENIED;
2727 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2728 return NT_STATUS_NO_MEMORY;
2730 ZERO_STRUCTP(info);
2732 sid_copy(&info->sid, &global_sam_sid);
2733 sid_append_rid(&info->sid, r_u->rid);
2734 sid_to_string(sid_string, &info->sid);
2736 /* get a (unique) handle. open a policy on it. */
2737 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
2738 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2740 return NT_STATUS_NOPROBLEMO;
2743 /*********************************************************************
2744 _samr_query_groupinfo
2746 sends the name/comment pair of a domain group
2747 level 1 send also the number of users of that group
2748 *********************************************************************/
2750 uint32 _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
2752 DOM_SID group_sid;
2753 GROUP_MAP map;
2754 uid_t *uid;
2755 int num_uids=0;
2756 GROUP_INFO_CTR *ctr;
2758 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2759 return NT_STATUS_INVALID_HANDLE;
2761 if (!get_domain_group_from_sid(group_sid, &map))
2762 return NT_STATUS_INVALID_HANDLE;
2764 ctr=(GROUP_INFO_CTR *)talloc(p->mem_ctx, sizeof(GROUP_INFO_CTR));
2765 if (ctr==NULL)
2766 return NT_STATUS_NO_MEMORY;
2768 switch (q_u->switch_level) {
2769 case 1:
2770 ctr->switch_value1 = 1;
2771 if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
2772 return NT_STATUS_NO_SUCH_GROUP;
2773 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
2774 safe_free(uid);
2775 break;
2776 case 4:
2777 ctr->switch_value1 = 4;
2778 init_samr_group_info4(&ctr->group.info4, map.comment);
2779 break;
2780 default:
2781 return NT_STATUS_INVALID_INFO_CLASS;
2784 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_NO_PROBLEMO);
2786 return NT_STATUS_NO_PROBLEMO;
2789 /*********************************************************************
2790 _samr_set_groupinfo
2792 update a domain group's comment.
2793 *********************************************************************/
2795 uint32 _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
2797 DOM_SID group_sid;
2798 GROUP_MAP map;
2799 GROUP_INFO_CTR *ctr;
2801 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid))
2802 return NT_STATUS_INVALID_HANDLE;
2804 if (!get_domain_group_from_sid(group_sid, &map))
2805 return NT_STATUS_NO_SUCH_GROUP;
2807 ctr=q_u->ctr;
2809 switch (ctr->switch_value1) {
2810 case 1:
2811 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
2812 break;
2813 case 4:
2814 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
2815 break;
2816 default:
2817 return NT_STATUS_INVALID_INFO_CLASS;
2820 if(!add_mapping_entry(&map, TDB_REPLACE))
2821 return NT_STATUS_NO_SUCH_GROUP;
2823 return NT_STATUS_NO_PROBLEMO;
2826 /*********************************************************************
2827 _samr_get_dom_pwinfo
2828 *********************************************************************/
2830 uint32 _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
2832 /* Actually, returning zeros here works quite well :-). */
2833 return NT_STATUS_NOPROBLEMO;
2836 /*********************************************************************
2837 _samr_open_group
2838 *********************************************************************/
2840 uint32 _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
2842 DOM_SID sid;
2843 GROUP_MAP map;
2844 struct samr_info *info;
2845 fstring sid_string;
2847 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
2848 return NT_STATUS_INVALID_HANDLE;
2850 /* this should not be hard-coded like this */
2851 if (!sid_equal(&sid, &global_sam_sid))
2852 return NT_STATUS_ACCESS_DENIED;
2854 if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
2855 return NT_STATUS_NO_MEMORY;
2857 ZERO_STRUCTP(info);
2859 sid_copy(&info->sid, &global_sam_sid);
2860 sid_append_rid(&info->sid, q_u->rid_group);
2861 sid_to_string(sid_string, &info->sid);
2863 DEBUG(10, ("Opening SID: %s\n", sid_string));
2865 /* check if that group really exists */
2866 if (!get_domain_group_from_sid(info->sid, &map))
2867 return NT_STATUS_NO_SUCH_USER;
2869 /* get a (unique) handle. open a policy on it. */
2870 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
2871 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2873 return NT_STATUS_NO_PROBLEMO;
2876 /*********************************************************************
2877 _samr_unknown_2d
2878 *********************************************************************/
2880 uint32 _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
2882 DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
2883 return False;