Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / samba / source / rpc_server / srv_samr.c
blob169dc2169edc4cd5b50c1433653059894fcf9b2d
2 /*
3 * Unix SMB/Netbios implementation.
4 * Version 1.9.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1997,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8 * Copyright (C) Paul Ashton 1997.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "includes.h"
27 #include "nterr.h"
29 extern int DEBUGLEVEL;
31 extern fstring global_myworkgroup;
32 extern pstring global_myname;
33 extern DOM_SID global_sam_sid;
35 extern rid_name domain_group_rids[];
36 extern rid_name domain_alias_rids[];
37 extern rid_name builtin_alias_rids[];
39 /*******************************************************************
40 This next function should be replaced with something that
41 dynamically returns the correct user info..... JRA.
42 ********************************************************************/
44 static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
45 int start_idx,
46 int *total_entries, int *num_entries,
47 int max_num_entries,
48 uint16 acb_mask)
50 void *vp = NULL;
51 struct sam_passwd *pwd = NULL;
53 (*num_entries) = 0;
54 (*total_entries) = 0;
56 if (pw_buf == NULL) return False;
58 vp = startsmbpwent(False);
59 if (!vp)
61 DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
62 return False;
65 while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries)
67 int user_name_len;
69 if (start_idx > 0)
71 /* skip the requested number of entries.
72 not very efficient, but hey...
74 start_idx--;
75 continue;
78 user_name_len = strlen(pwd->smb_name);
79 init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len);
80 init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
81 pw_buf[(*num_entries)].user_rid = pwd->user_rid;
82 memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
84 /* Now check if the NT compatible password is available. */
85 if (pwd->smb_nt_passwd != NULL)
87 memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
90 pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
92 DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
93 (*num_entries), pwd->smb_name,
94 pwd->user_rid, pwd->acct_ctrl));
96 if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
98 DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
99 (*num_entries)++;
101 else
103 DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
106 (*total_entries)++;
109 endsmbpwent(vp);
111 return (*num_entries) > 0;
114 /*******************************************************************
115 samr_reply_unknown_1
116 ********************************************************************/
117 static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
118 prs_struct *rdata)
120 SAMR_R_CLOSE_HND r_u;
122 /* set up the SAMR unknown_1 response */
123 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
125 /* close the policy handle */
126 if (close_lsa_policy_hnd(&(q_u->pol)))
128 r_u.status = 0;
130 else
132 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
135 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
137 /* store the response in the SMB stream */
138 samr_io_r_close_hnd("", &r_u, rdata, 0);
140 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
144 /*******************************************************************
145 api_samr_close_hnd
146 ********************************************************************/
147 static BOOL api_samr_close_hnd( uint16 vuid, prs_struct *data, prs_struct *rdata)
149 SAMR_Q_CLOSE_HND q_u;
151 /* grab the samr unknown 1 */
152 samr_io_q_close_hnd("", &q_u, data, 0);
154 /* construct reply. always indicate success */
155 samr_reply_close_hnd(&q_u, rdata);
157 return True;
161 /*******************************************************************
162 samr_reply_open_domain
163 ********************************************************************/
164 static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
165 prs_struct *rdata)
167 SAMR_R_OPEN_DOMAIN r_u;
168 BOOL pol_open = False;
170 r_u.status = 0x0;
172 /* find the connection policy handle. */
173 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
175 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
178 /* get a (unique) handle. open a policy on it. */
179 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
181 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
184 /* associate the domain SID with the (unique) handle. */
185 if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
187 /* oh, whoops. don't know what error message to return, here */
188 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
191 if (r_u.status != 0 && pol_open)
193 close_lsa_policy_hnd(&(r_u.domain_pol));
196 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
198 /* store the response in the SMB stream */
199 samr_io_r_open_domain("", &r_u, rdata, 0);
201 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
205 /*******************************************************************
206 api_samr_open_domain
207 ********************************************************************/
208 static BOOL api_samr_open_domain( uint16 vuid, prs_struct *data, prs_struct *rdata)
210 SAMR_Q_OPEN_DOMAIN q_u;
212 /* grab the samr open */
213 samr_io_q_open_domain("", &q_u, data, 0);
215 /* construct reply. always indicate success */
216 samr_reply_open_domain(&q_u, rdata);
218 return True;
222 /*******************************************************************
223 samr_reply_unknown_2c
224 ********************************************************************/
225 static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
226 prs_struct *rdata)
228 SAMR_R_UNKNOWN_2C r_u;
229 uint32 status = 0x0;
231 /* find the policy handle. open a policy on it. */
232 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
234 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
237 /* find the user's rid */
238 if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
240 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
243 init_samr_r_unknown_2c(&r_u, status);
245 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
247 /* store the response in the SMB stream */
248 samr_io_r_unknown_2c("", &r_u, rdata, 0);
250 DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
254 /*******************************************************************
255 api_samr_unknown_2c
256 ********************************************************************/
257 static BOOL api_samr_unknown_2c( uint16 vuid, prs_struct *data, prs_struct *rdata)
259 SAMR_Q_UNKNOWN_2C q_u;
261 /* grab the samr open */
262 samr_io_q_unknown_2c("", &q_u, data, 0);
264 /* construct reply. always indicate success */
265 samr_reply_unknown_2c(&q_u, rdata);
267 return True;
271 /*******************************************************************
272 samr_reply_unknown_3
273 ********************************************************************/
274 static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
275 prs_struct *rdata)
277 SAMR_R_UNKNOWN_3 r_u;
278 DOM_SID3 sid[MAX_SAM_SIDS];
279 uint32 rid;
280 uint32 status;
282 status = 0x0;
284 /* find the policy handle. open a policy on it. */
285 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
287 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
290 /* find the user's rid */
291 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
293 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
296 if (status == 0x0)
298 DOM_SID user_sid;
299 DOM_SID everyone_sid;
301 user_sid = global_sam_sid;
303 SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
306 * Add the user RID.
308 user_sid.sub_auths[user_sid.num_auths++] = rid;
310 string_to_sid(&everyone_sid, "S-1-1");
312 /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
313 /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
314 init_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
315 init_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
318 init_samr_r_unknown_3(&r_u,
319 0x0001, 0x8004,
320 0x00000014, 0x0002, 0x0070,
321 2, sid, status);
323 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
325 /* store the response in the SMB stream */
326 samr_io_r_unknown_3("", &r_u, rdata, 0);
328 DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
332 /*******************************************************************
333 api_samr_unknown_3
334 ********************************************************************/
335 static BOOL api_samr_unknown_3( uint16 vuid, prs_struct *data, prs_struct *rdata)
337 SAMR_Q_UNKNOWN_3 q_u;
339 /* grab the samr open */
340 samr_io_q_unknown_3("", &q_u, data, 0);
342 /* construct reply. always indicate success */
343 samr_reply_unknown_3(&q_u, rdata);
345 return True;
349 /*******************************************************************
350 samr_reply_enum_dom_users
351 ********************************************************************/
352 static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
353 prs_struct *rdata)
355 SAMR_R_ENUM_DOM_USERS r_e;
356 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
357 int num_entries;
358 int total_entries;
360 r_e.status = 0x0;
361 r_e.total_num_entries = 0;
363 /* find the policy handle. open a policy on it. */
364 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
366 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
369 DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
371 become_root(True);
372 get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
373 unbecome_root(True);
375 init_samr_r_enum_dom_users(&r_e, total_entries,
376 q_u->unknown_0, num_entries,
377 pass, r_e.status);
379 /* store the response in the SMB stream */
380 samr_io_r_enum_dom_users("", &r_e, rdata, 0);
382 DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
386 /*******************************************************************
387 api_samr_enum_dom_users
388 ********************************************************************/
389 static BOOL api_samr_enum_dom_users( uint16 vuid, prs_struct *data, prs_struct *rdata)
391 SAMR_Q_ENUM_DOM_USERS q_e;
393 /* grab the samr open */
394 samr_io_q_enum_dom_users("", &q_e, data, 0);
396 /* construct reply. */
397 samr_reply_enum_dom_users(&q_e, rdata);
399 return True;
403 /*******************************************************************
404 samr_reply_enum_dom_groups
405 ********************************************************************/
406 static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
407 prs_struct *rdata)
409 SAMR_R_ENUM_DOM_GROUPS r_e;
410 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
411 int num_entries;
412 BOOL got_grps;
413 char *dummy_group = "Domain Admins";
415 r_e.status = 0x0;
416 r_e.num_entries = 0;
418 /* find the policy handle. open a policy on it. */
419 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
421 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
424 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
426 got_grps = True;
427 num_entries = 1;
428 init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
429 pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
431 if (r_e.status == 0 && got_grps)
433 init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
436 /* store the response in the SMB stream */
437 samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
439 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
443 /*******************************************************************
444 api_samr_enum_dom_groups
445 ********************************************************************/
446 static BOOL api_samr_enum_dom_groups( uint16 vuid, prs_struct *data, prs_struct *rdata)
448 SAMR_Q_ENUM_DOM_GROUPS q_e;
450 /* grab the samr open */
451 samr_io_q_enum_dom_groups("", &q_e, data, 0);
453 /* construct reply. */
454 samr_reply_enum_dom_groups(&q_e, rdata);
456 return True;
460 /*******************************************************************
461 samr_reply_enum_dom_aliases
462 ********************************************************************/
463 static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
464 prs_struct *rdata)
466 SAMR_R_ENUM_DOM_ALIASES r_e;
467 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
468 int num_entries = 0;
469 DOM_SID sid;
470 fstring sid_str;
471 fstring sam_sid_str;
473 r_e.status = 0x0;
474 r_e.num_entries = 0;
476 /* find the policy handle. open a policy on it. */
477 if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
479 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
482 sid_to_string(sid_str, &sid);
483 sid_to_string(sam_sid_str, &global_sam_sid);
485 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
487 /* well-known aliases */
488 if (strequal(sid_str, "S-1-5-32"))
490 char *name;
491 while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
493 init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
494 pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
495 num_entries++;
498 else if (strequal(sid_str, sam_sid_str))
500 /* local aliases */
501 /* oops! there's no code to deal with this */
502 DEBUG(3,("samr_reply_enum_dom_aliases: enum of aliases in our domain not supported yet\n"));
503 num_entries = 0;
506 init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
508 /* store the response in the SMB stream */
509 samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
511 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
515 /*******************************************************************
516 api_samr_enum_dom_aliases
517 ********************************************************************/
518 static BOOL api_samr_enum_dom_aliases( uint16 vuid, prs_struct *data, prs_struct *rdata)
520 SAMR_Q_ENUM_DOM_ALIASES q_e;
522 /* grab the samr open */
523 samr_io_q_enum_dom_aliases("", &q_e, data, 0);
525 /* construct reply. */
526 samr_reply_enum_dom_aliases(&q_e, rdata);
528 return True;
532 /*******************************************************************
533 samr_reply_query_dispinfo
534 ********************************************************************/
535 static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
536 prs_struct *rdata)
538 SAMR_R_QUERY_DISPINFO r_e;
539 SAM_INFO_CTR ctr;
540 SAM_INFO_1 info1;
541 SAM_INFO_2 info2;
542 SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
543 int num_entries = 0;
544 int total_entries = 0;
545 BOOL got_pwds;
546 uint16 switch_level = 0x0;
548 ZERO_STRUCT(r_e);
550 r_e.status = 0x0;
552 DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
554 /* find the policy handle. open a policy on it. */
555 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
557 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
558 DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
561 if (r_e.status == 0x0)
563 become_root(True);
564 got_pwds = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
565 unbecome_root(True);
567 switch (q_u->switch_level)
569 case 0x1:
572 /* query disp info is for users */
573 switch_level = 0x1;
574 init_sam_info_1(&info1, ACB_NORMAL,
575 q_u->start_idx, num_entries, pass);
577 ctr.sam.info1 = &info1;
579 break;
581 case 0x2:
583 /* query disp info is for servers */
584 switch_level = 0x2;
585 init_sam_info_2(&info2, ACB_WSTRUST,
586 q_u->start_idx, num_entries, pass);
588 ctr.sam.info2 = &info2;
590 break;
595 if (r_e.status == 0 && got_pwds)
597 init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
600 /* store the response in the SMB stream */
601 samr_io_r_query_dispinfo("", &r_e, rdata, 0);
603 DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
607 /*******************************************************************
608 api_samr_query_dispinfo
609 ********************************************************************/
610 static BOOL api_samr_query_dispinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
612 SAMR_Q_QUERY_DISPINFO q_e;
614 /* grab the samr open */
615 samr_io_q_query_dispinfo("", &q_e, data, 0);
617 /* construct reply. */
618 samr_reply_query_dispinfo(&q_e, rdata);
620 return True;
624 /*******************************************************************
625 samr_reply_query_aliasinfo
626 ********************************************************************/
627 static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
628 prs_struct *rdata)
630 SAMR_R_QUERY_ALIASINFO r_e;
632 r_e.status = 0x0;
633 r_e.ptr = 0;
635 /* find the policy handle. open a policy on it. */
636 if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
638 r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
641 DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
643 if (r_e.status == 0x0)
645 if (q_u->switch_level != 3)
647 r_e.status = NT_STATUS_INVALID_INFO_CLASS;
651 init_samr_r_query_aliasinfo(&r_e, q_u->switch_level,
652 "<account description>",
653 r_e.status);
655 /* store the response in the SMB stream */
656 samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
658 DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
662 /*******************************************************************
663 api_samr_query_aliasinfo
664 ********************************************************************/
665 static BOOL api_samr_query_aliasinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
667 SAMR_Q_QUERY_ALIASINFO q_e;
669 /* grab the samr open */
670 samr_io_q_query_aliasinfo("", &q_e, data, 0);
672 /* construct reply. */
673 samr_reply_query_aliasinfo(&q_e, rdata);
675 return True;
679 /*******************************************************************
680 samr_reply_lookup_ids
681 ********************************************************************/
682 static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
683 prs_struct *rdata)
685 uint32 rid[MAX_SAM_ENTRIES];
686 uint32 status = 0;
687 int num_rids = q_u->num_sids1;
689 SAMR_R_LOOKUP_IDS r_u;
691 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
693 if (num_rids > MAX_SAM_ENTRIES)
695 num_rids = MAX_SAM_ENTRIES;
696 DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
699 #if 0
700 int i;
701 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
703 for (i = 0; i < num_rids && status == 0; i++)
705 struct sam_passwd *sam_pass;
706 fstring user_name;
709 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
710 q_u->uni_user_name[i].uni_str_len));
712 /* find the user account */
713 become_root(True);
714 sam_pass = get_smb21pwd_entry(user_name, 0);
715 unbecome_root(True);
717 if (sam_pass == NULL)
719 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
720 rid[i] = 0;
722 else
724 rid[i] = sam_pass->user_rid;
727 #endif
729 num_rids = 1;
730 rid[0] = BUILTIN_ALIAS_RID_USERS;
732 init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
734 /* store the response in the SMB stream */
735 samr_io_r_lookup_ids("", &r_u, rdata, 0);
737 DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
741 /*******************************************************************
742 api_samr_lookup_ids
743 ********************************************************************/
744 static BOOL api_samr_lookup_ids( uint16 vuid, prs_struct *data, prs_struct *rdata)
746 SAMR_Q_LOOKUP_IDS q_u;
748 /* grab the samr 0x10 */
749 samr_io_q_lookup_ids("", &q_u, data, 0);
751 /* construct reply. always indicate success */
752 samr_reply_lookup_ids(&q_u, rdata);
754 return True;
757 /*******************************************************************
758 samr_reply_lookup_names
759 ********************************************************************/
761 static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
762 prs_struct *rdata)
764 uint32 rid[MAX_SAM_ENTRIES];
765 uint8 type[MAX_SAM_ENTRIES];
766 uint32 status = 0;
767 int i;
768 int num_rids = q_u->num_names1;
769 DOM_SID pol_sid;
771 SAMR_R_LOOKUP_NAMES r_u;
773 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
775 ZERO_ARRAY(rid);
776 ZERO_ARRAY(type);
778 if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
779 status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
780 init_samr_r_lookup_names(&r_u, 0, rid, type, status);
781 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
782 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
783 return False;
785 return True;
788 if (num_rids > MAX_SAM_ENTRIES) {
789 num_rids = MAX_SAM_ENTRIES;
790 DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
793 SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
795 for (i = 0; i < num_rids; i++) {
796 fstring name;
798 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
800 rid [i] = 0xffffffff;
801 type[i] = SID_NAME_UNKNOWN;
803 fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
804 q_u->uni_name[i].uni_str_len));
806 if(sid_equal(&pol_sid, &global_sam_sid)) {
807 DOM_SID sid;
809 if(lookup_local_name(global_myname, name, &sid, &type[i])) {
810 sid_split_rid( &sid, &rid[i]);
811 status = 0;
816 init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
818 /* store the response in the SMB stream */
819 if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
820 DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
821 return False;
824 DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
826 return True;
829 /*******************************************************************
830 api_samr_lookup_names
831 ********************************************************************/
833 static BOOL api_samr_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata)
835 SAMR_Q_LOOKUP_NAMES q_u;
837 memset(&q_u, '\0', sizeof(q_u));
839 /* grab the samr lookup names */
840 if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
841 DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
842 return False;
845 /* construct reply. always indicate success */
846 if(!samr_reply_lookup_names(&q_u, rdata))
847 return False;
849 return True;
852 /*******************************************************************
853 samr_reply_chgpasswd_user
854 ********************************************************************/
856 static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
857 prs_struct *rdata)
859 SAMR_R_CHGPASSWD_USER r_u;
860 uint32 status = 0x0;
861 fstring user_name;
862 fstring wks;
864 fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
865 fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
867 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
869 if (!pass_oem_change(user_name,
870 q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
871 q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
873 status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
876 init_samr_r_chgpasswd_user(&r_u, status);
878 /* store the response in the SMB stream */
879 if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
880 DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
881 return False;
884 DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
885 return True;
888 /*******************************************************************
889 api_samr_chgpasswd_user
890 ********************************************************************/
892 static BOOL api_samr_chgpasswd_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
894 SAMR_Q_CHGPASSWD_USER q_u;
896 /* unknown 38 command */
897 if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
898 DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
899 return False;
902 /* construct reply. */
903 if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
904 DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
905 return False;
908 return True;
912 /*******************************************************************
913 samr_reply_unknown_38
914 ********************************************************************/
915 static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
916 prs_struct *rdata)
918 SAMR_R_UNKNOWN_38 r_u;
920 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
922 init_samr_r_unknown_38(&r_u);
924 /* store the response in the SMB stream */
925 samr_io_r_unknown_38("", &r_u, rdata, 0);
927 DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
930 /*******************************************************************
931 api_samr_unknown_38
932 ********************************************************************/
933 static BOOL api_samr_unknown_38( uint16 vuid, prs_struct *data, prs_struct *rdata)
935 SAMR_Q_UNKNOWN_38 q_u;
937 /* unknown 38 command */
938 samr_io_q_unknown_38("", &q_u, data, 0);
940 /* construct reply. always indicate success */
941 samr_reply_unknown_38(&q_u, rdata);
943 return True;
947 /*******************************************************************
948 samr_reply_unknown_12
949 ********************************************************************/
950 static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
951 prs_struct *rdata)
953 fstring group_names[MAX_SAM_ENTRIES];
954 uint32 group_attrs[MAX_SAM_ENTRIES];
955 uint32 status = 0;
956 int num_gids = q_u->num_gids1;
958 SAMR_R_UNKNOWN_12 r_u;
960 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
962 /* find the policy handle. open a policy on it. */
963 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
965 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
968 if (status == 0x0)
970 int i;
971 if (num_gids > MAX_SAM_ENTRIES)
973 num_gids = MAX_SAM_ENTRIES;
974 DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
977 for (i = 0; i < num_gids && status == 0; i++)
979 fstrcpy(group_names[i], "dummy group");
980 group_attrs[i] = 0x2;
984 init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
986 /* store the response in the SMB stream */
987 samr_io_r_unknown_12("", &r_u, rdata, 0);
989 DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
993 /*******************************************************************
994 api_samr_unknown_12
995 ********************************************************************/
996 static BOOL api_samr_unknown_12( uint16 vuid, prs_struct *data, prs_struct *rdata)
998 SAMR_Q_UNKNOWN_12 q_u;
1000 /* grab the samr lookup names */
1001 samr_io_q_unknown_12("", &q_u, data, 0);
1003 /* construct reply. always indicate success */
1004 samr_reply_unknown_12(&q_u, rdata);
1006 return True;
1010 /*******************************************************************
1011 samr_reply_open_user
1012 ********************************************************************/
1013 static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
1014 prs_struct *rdata,
1015 int status)
1017 SAMR_R_OPEN_USER r_u;
1018 struct sam_passwd *sam_pass;
1019 BOOL pol_open = False;
1021 /* set up the SAMR open_user response */
1022 memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
1024 r_u.status = 0x0;
1026 /* find the policy handle. open a policy on it. */
1027 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1029 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1032 /* get a (unique) handle. open a policy on it. */
1033 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
1035 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1038 become_root(True);
1039 sam_pass = getsam21pwrid(q_u->user_rid);
1040 unbecome_root(True);
1042 /* check that the RID exists in our domain. */
1043 if (r_u.status == 0x0 && sam_pass == NULL)
1045 r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1048 /* associate the RID with the (unique) handle. */
1049 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
1051 /* oh, whoops. don't know what error message to return, here */
1052 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1055 if (r_u.status != 0 && pol_open)
1057 close_lsa_policy_hnd(&(r_u.user_pol));
1060 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1062 /* store the response in the SMB stream */
1063 samr_io_r_open_user("", &r_u, rdata, 0);
1065 DEBUG(5,("samr_open_user: %d\n", __LINE__));
1069 /*******************************************************************
1070 api_samr_open_user
1071 ********************************************************************/
1072 static BOOL api_samr_open_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
1074 SAMR_Q_OPEN_USER q_u;
1076 /* grab the samr unknown 22 */
1077 samr_io_q_open_user("", &q_u, data, 0);
1079 /* construct reply. always indicate success */
1080 samr_reply_open_user(&q_u, rdata, 0x0);
1082 return True;
1086 /*************************************************************************
1087 get_user_info_10
1088 *************************************************************************/
1089 static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
1091 struct smb_passwd *smb_pass;
1093 if (!pdb_rid_is_user(user_rid))
1095 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1096 return False;
1099 become_root(True);
1100 smb_pass = getsmbpwrid(user_rid);
1101 unbecome_root(True);
1103 if (smb_pass == NULL)
1105 DEBUG(4,("User 0x%x not found\n", user_rid));
1106 return False;
1109 DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
1111 init_sam_user_info10(id10, smb_pass->acct_ctrl);
1113 return True;
1116 /*************************************************************************
1117 get_user_info_21
1118 *************************************************************************/
1119 static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
1121 NTTIME dummy_time;
1122 struct sam_passwd *sam_pass;
1123 LOGON_HRS hrs;
1124 int i;
1126 if (!pdb_rid_is_user(user_rid))
1128 DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
1129 return False;
1132 become_root(True);
1133 sam_pass = getsam21pwrid(user_rid);
1134 unbecome_root(True);
1136 if (sam_pass == NULL)
1138 DEBUG(4,("User 0x%x not found\n", user_rid));
1139 return False;
1142 DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
1144 dummy_time.low = 0xffffffff;
1145 dummy_time.high = 0x7fffffff;
1147 DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
1149 /* create a LOGON_HRS structure */
1150 hrs.len = sam_pass->hours_len;
1151 SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
1152 for (i = 0; i < hrs.len; i++)
1154 hrs.hours[i] = sam_pass->hours[i];
1157 init_sam_user_info21(id21,
1159 &dummy_time, /* logon_time */
1160 &dummy_time, /* logoff_time */
1161 &dummy_time, /* kickoff_time */
1162 &dummy_time, /* pass_last_set_time */
1163 &dummy_time, /* pass_can_change_time */
1164 &dummy_time, /* pass_must_change_time */
1166 sam_pass->smb_name, /* user_name */
1167 sam_pass->full_name, /* full_name */
1168 sam_pass->home_dir, /* home_dir */
1169 sam_pass->dir_drive, /* dir_drive */
1170 sam_pass->logon_script, /* logon_script */
1171 sam_pass->profile_path, /* profile_path */
1172 sam_pass->acct_desc, /* description */
1173 sam_pass->workstations, /* workstations user can log in from */
1174 sam_pass->unknown_str, /* don't know, yet */
1175 sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
1177 sam_pass->user_rid, /* RID user_id */
1178 sam_pass->group_rid, /* RID group_id */
1179 sam_pass->acct_ctrl,
1181 sam_pass->unknown_3, /* unknown_3 */
1182 sam_pass->logon_divs, /* divisions per week */
1183 &hrs, /* logon hours */
1184 sam_pass->unknown_5,
1185 sam_pass->unknown_6);
1187 return True;
1190 /*******************************************************************
1191 samr_reply_query_userinfo
1192 ********************************************************************/
1193 static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
1194 prs_struct *rdata)
1196 SAMR_R_QUERY_USERINFO r_u;
1197 #if 0
1198 SAM_USER_INFO_11 id11;
1199 #endif
1200 SAM_USER_INFO_10 id10;
1201 SAM_USER_INFO_21 id21;
1202 void *info = NULL;
1204 uint32 status = 0x0;
1205 uint32 rid = 0x0;
1207 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1209 /* search for the handle */
1210 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1212 status = NT_STATUS_INVALID_HANDLE;
1215 /* find the user's rid */
1216 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1218 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1221 DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
1223 /* ok! user info levels (there are lots: see MSDEV help), off we go... */
1224 if (status == 0x0)
1226 switch (q_u->switch_value)
1228 case 0x10:
1230 info = (void*)&id10;
1231 status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1232 break;
1234 #if 0
1235 /* whoops - got this wrong. i think. or don't understand what's happening. */
1236 case 0x11:
1238 NTTIME expire;
1239 info = (void*)&id11;
1241 expire.low = 0xffffffff;
1242 expire.high = 0x7fffffff;
1244 make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
1246 break;
1248 #endif
1249 case 21:
1251 info = (void*)&id21;
1252 status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
1253 break;
1256 default:
1258 status = NT_STATUS_INVALID_INFO_CLASS;
1260 break;
1265 init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
1267 /* store the response in the SMB stream */
1268 samr_io_r_query_userinfo("", &r_u, rdata, 0);
1270 DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
1274 /*******************************************************************
1275 api_samr_query_userinfo
1276 ********************************************************************/
1277 static BOOL api_samr_query_userinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
1279 SAMR_Q_QUERY_USERINFO q_u;
1281 /* grab the samr unknown 24 */
1282 samr_io_q_query_userinfo("", &q_u, data, 0);
1284 /* construct reply. always indicate success */
1285 samr_reply_query_userinfo(&q_u, rdata);
1287 return True;
1291 /*******************************************************************
1292 samr_reply_query_usergroups
1293 ********************************************************************/
1294 static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
1295 prs_struct *rdata)
1297 SAMR_R_QUERY_USERGROUPS r_u;
1298 uint32 status = 0x0;
1300 struct sam_passwd *sam_pass;
1301 DOM_GID *gids = NULL;
1302 int num_groups = 0;
1303 uint32 rid;
1305 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1307 /* find the policy handle. open a policy on it. */
1308 if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
1310 status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1313 /* find the user's rid */
1314 if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
1316 status = NT_STATUS_OBJECT_TYPE_MISMATCH;
1319 if (status == 0x0)
1321 become_root(True);
1322 sam_pass = getsam21pwrid(rid);
1323 unbecome_root(True);
1325 if (sam_pass == NULL)
1327 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1331 if (status == 0x0)
1333 pstring groups;
1334 get_domain_user_groups(groups, sam_pass->smb_name);
1335 gids = NULL;
1336 num_groups = make_dom_gids(groups, &gids);
1339 /* construct the response. lkclXXXX: gids are not copied! */
1340 init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
1342 /* store the response in the SMB stream */
1343 samr_io_r_query_usergroups("", &r_u, rdata, 0);
1345 if (gids)
1347 free((char *)gids);
1350 DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
1354 /*******************************************************************
1355 api_samr_query_usergroups
1356 ********************************************************************/
1357 static BOOL api_samr_query_usergroups( uint16 vuid, prs_struct *data, prs_struct *rdata)
1359 SAMR_Q_QUERY_USERGROUPS q_u;
1360 /* grab the samr unknown 32 */
1361 samr_io_q_query_usergroups("", &q_u, data, 0);
1363 /* construct reply. */
1364 samr_reply_query_usergroups(&q_u, rdata);
1366 return True;
1370 /*******************************************************************
1371 samr_reply_query_dom_info
1372 ********************************************************************/
1373 static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
1374 prs_struct *rdata)
1376 SAMR_R_QUERY_DOMAIN_INFO r_u;
1377 SAM_UNK_CTR ctr;
1378 uint16 switch_value = 0x0;
1379 uint32 status = 0x0;
1381 ZERO_STRUCT(r_u);
1382 ZERO_STRUCT(ctr);
1384 r_u.ctr = &ctr;
1386 DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
1388 /* find the policy handle. open a policy on it. */
1389 if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
1391 r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
1392 DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
1395 if (status == 0x0)
1397 switch (q_u->switch_value)
1399 case 0x02:
1401 switch_value = 0x2;
1402 init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
1404 break;
1406 default:
1408 status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
1409 break;
1414 init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
1416 /* store the response in the SMB stream */
1417 samr_io_r_query_dom_info("", &r_u, rdata, 0);
1419 DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
1423 /*******************************************************************
1424 api_samr_query_dom_info
1425 ********************************************************************/
1426 static BOOL api_samr_query_dom_info( uint16 vuid, prs_struct *data, prs_struct *rdata)
1428 SAMR_Q_QUERY_DOMAIN_INFO q_e;
1430 /* grab the samr unknown 8 command */
1431 samr_io_q_query_dom_info("", &q_e, data, 0);
1433 /* construct reply. */
1434 samr_reply_query_dom_info(&q_e, rdata);
1436 return True;
1441 /*******************************************************************
1442 samr_reply_unknown_32
1443 ********************************************************************/
1444 static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
1445 prs_struct *rdata,
1446 int status)
1448 int i;
1449 SAMR_R_UNKNOWN_32 r_u;
1451 /* set up the SAMR unknown_32 response */
1452 memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
1453 if (status == 0)
1455 for (i = 4; i < POL_HND_SIZE; i++)
1457 r_u.pol.data[i] = i+1;
1461 init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
1462 r_u.status = status;
1464 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1466 /* store the response in the SMB stream */
1467 samr_io_r_unknown_32("", &r_u, rdata, 0);
1469 DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
1473 /*******************************************************************
1474 api_samr_unknown_32
1475 ********************************************************************/
1476 static BOOL api_samr_unknown_32( uint16 vuid, prs_struct *data, prs_struct *rdata)
1478 uint32 status = 0;
1479 struct sam_passwd *sam_pass;
1480 fstring mach_acct;
1482 SAMR_Q_UNKNOWN_32 q_u;
1484 /* grab the samr unknown 32 */
1485 samr_io_q_unknown_32("", &q_u, data, 0);
1487 /* find the machine account: tell the caller if it exists.
1488 lkclXXXX i have *no* idea if this is a problem or not
1489 or even if you are supposed to construct a different
1490 reply if the account already exists...
1493 fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
1494 q_u.uni_mach_acct.uni_str_len));
1496 become_root(True);
1497 sam_pass = getsam21pwnam(mach_acct);
1498 unbecome_root(True);
1500 if (sam_pass != NULL)
1502 /* machine account exists: say so */
1503 status = 0xC0000000 | NT_STATUS_USER_EXISTS;
1505 else
1507 /* this could cause trouble... */
1508 DEBUG(0,("trouble!\n"));
1509 status = 0;
1512 /* construct reply. */
1513 samr_reply_unknown_32(&q_u, rdata, status);
1515 return True;
1519 /*******************************************************************
1520 samr_reply_connect_anon
1521 ********************************************************************/
1522 static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
1523 prs_struct *rdata)
1525 SAMR_R_CONNECT_ANON r_u;
1526 BOOL pol_open = False;
1528 /* set up the SAMR connect_anon response */
1530 r_u.status = 0x0;
1531 /* get a (unique) handle. open a policy on it. */
1532 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1534 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1537 /* associate the domain SID with the (unique) handle. */
1538 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1540 /* oh, whoops. don't know what error message to return, here */
1541 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1544 if (r_u.status != 0 && pol_open)
1546 close_lsa_policy_hnd(&(r_u.connect_pol));
1549 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1551 /* store the response in the SMB stream */
1552 samr_io_r_connect_anon("", &r_u, rdata, 0);
1554 DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
1558 /*******************************************************************
1559 api_samr_connect_anon
1560 ********************************************************************/
1561 static BOOL api_samr_connect_anon( uint16 vuid, prs_struct *data, prs_struct *rdata)
1563 SAMR_Q_CONNECT_ANON q_u;
1565 /* grab the samr open policy */
1566 samr_io_q_connect_anon("", &q_u, data, 0);
1568 /* construct reply. always indicate success */
1569 samr_reply_connect_anon(&q_u, rdata);
1571 return True;
1574 /*******************************************************************
1575 samr_reply_connect
1576 ********************************************************************/
1577 static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
1578 prs_struct *rdata)
1580 SAMR_R_CONNECT r_u;
1581 BOOL pol_open = False;
1583 /* set up the SAMR connect response */
1585 r_u.status = 0x0;
1586 /* get a (unique) handle. open a policy on it. */
1587 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
1589 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1592 /* associate the domain SID with the (unique) handle. */
1593 if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
1595 /* oh, whoops. don't know what error message to return, here */
1596 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1599 if (r_u.status != 0 && pol_open)
1601 close_lsa_policy_hnd(&(r_u.connect_pol));
1604 DEBUG(5,("samr_connect: %d\n", __LINE__));
1606 /* store the response in the SMB stream */
1607 samr_io_r_connect("", &r_u, rdata, 0);
1609 DEBUG(5,("samr_connect: %d\n", __LINE__));
1613 /*******************************************************************
1614 api_samr_connect
1615 ********************************************************************/
1616 static BOOL api_samr_connect( uint16 vuid, prs_struct *data, prs_struct *rdata)
1618 SAMR_Q_CONNECT q_u;
1620 /* grab the samr open policy */
1621 samr_io_q_connect("", &q_u, data, 0);
1623 /* construct reply. always indicate success */
1624 samr_reply_connect(&q_u, rdata);
1626 return True;
1629 /*******************************************************************
1630 samr_reply_open_alias
1631 ********************************************************************/
1632 static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
1633 prs_struct *rdata)
1635 SAMR_R_OPEN_ALIAS r_u;
1636 BOOL pol_open = False;
1638 /* set up the SAMR open_alias response */
1640 r_u.status = 0x0;
1641 /* get a (unique) handle. open a policy on it. */
1642 if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
1644 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1647 /* associate a RID with the (unique) handle. */
1648 if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
1650 /* oh, whoops. don't know what error message to return, here */
1651 r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
1654 if (r_u.status != 0 && pol_open)
1656 close_lsa_policy_hnd(&(r_u.pol));
1659 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1661 /* store the response in the SMB stream */
1662 samr_io_r_open_alias("", &r_u, rdata, 0);
1664 DEBUG(5,("samr_open_alias: %d\n", __LINE__));
1668 /*******************************************************************
1669 api_samr_open_alias
1670 ********************************************************************/
1671 static BOOL api_samr_open_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
1674 SAMR_Q_OPEN_ALIAS q_u;
1676 /* grab the samr open policy */
1677 samr_io_q_open_alias("", &q_u, data, 0);
1679 /* construct reply. always indicate success */
1680 samr_reply_open_alias(&q_u, rdata);
1682 return True;
1685 /*******************************************************************
1686 array of \PIPE\samr operations
1687 ********************************************************************/
1688 static struct api_struct api_samr_cmds [] =
1690 { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
1691 { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
1692 { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
1693 { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
1694 { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
1695 { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
1696 { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
1697 { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
1698 { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
1699 { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
1700 { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
1701 { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
1702 { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
1703 { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
1704 { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
1705 { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
1706 { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
1707 { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
1708 { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
1709 { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
1710 { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
1711 { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
1712 { NULL , 0 , NULL }
1715 /*******************************************************************
1716 receives a samr pipe and responds.
1717 ********************************************************************/
1718 BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
1720 return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);